OSDN Git Service

gcc/
[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_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
106
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
126
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
131
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
143
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
151
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
163
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
166
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
172
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
177
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
183
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
193
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
198
199    ;; For SSE5
200    (UNSPEC_SSE5_INTRINSIC       150)
201    (UNSPEC_SSE5_UNSIGNED_CMP    151)
202    (UNSPEC_SSE5_TRUEFALSE       152)
203    (UNSPEC_SSE5_PERMUTE         153)
204    (UNSPEC_FRCZ                 154)
205    (UNSPEC_CVTPH2PS             155)
206    (UNSPEC_CVTPS2PH             156)
207
208    ; For AES support
209    (UNSPEC_AESENC               159)
210    (UNSPEC_AESENCLAST           160)
211    (UNSPEC_AESDEC               161)
212    (UNSPEC_AESDECLAST           162)
213    (UNSPEC_AESIMC               163)
214    (UNSPEC_AESKEYGENASSIST      164)
215
216    ; For PCLMUL support
217    (UNSPEC_PCLMUL               165)
218
219    ; For AVX support
220    (UNSPEC_PCMP                 166)
221    (UNSPEC_VPERMIL              167)
222    (UNSPEC_VPERMIL2F128         168)
223    (UNSPEC_MASKLOAD             169)
224    (UNSPEC_MASKSTORE            170)
225    (UNSPEC_CAST                 171)
226    (UNSPEC_VTESTP               172)
227   ])
228
229 (define_constants
230   [(UNSPECV_BLOCKAGE            0)
231    (UNSPECV_STACK_PROBE         1)
232    (UNSPECV_EMMS                2)
233    (UNSPECV_LDMXCSR             3)
234    (UNSPECV_STMXCSR             4)
235    (UNSPECV_FEMMS               5)
236    (UNSPECV_CLFLUSH             6)
237    (UNSPECV_ALIGN               7)
238    (UNSPECV_MONITOR             8)
239    (UNSPECV_MWAIT               9)
240    (UNSPECV_CMPXCHG             10)
241    (UNSPECV_XCHG                12)
242    (UNSPECV_LOCK                13)
243    (UNSPECV_PROLOGUE_USE        14)
244    (UNSPECV_CLD                 15)
245    (UNSPECV_VZEROALL            16)
246    (UNSPECV_VZEROUPPER          17)
247   ])
248
249 ;; Constants to represent pcomtrue/pcomfalse variants
250 (define_constants
251   [(PCOM_FALSE                  0)
252    (PCOM_TRUE                   1)
253    (COM_FALSE_S                 2)
254    (COM_FALSE_P                 3)
255    (COM_TRUE_S                  4)
256    (COM_TRUE_P                  5)
257   ])
258
259 ;; Constants used in the SSE5 pperm instruction
260 (define_constants
261   [(PPERM_SRC                   0x00)   /* copy source */
262    (PPERM_INVERT                0x20)   /* invert source */
263    (PPERM_REVERSE               0x40)   /* bit reverse source */
264    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
265    (PPERM_ZERO                  0x80)   /* all 0's */
266    (PPERM_ONES                  0xa0)   /* all 1's */
267    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
268    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
269    (PPERM_SRC1                  0x00)   /* use first source byte */
270    (PPERM_SRC2                  0x10)   /* use second source byte */
271    ])
272
273 ;; Registers by name.
274 (define_constants
275   [(AX_REG                       0)
276    (DX_REG                       1)
277    (CX_REG                       2)
278    (BX_REG                       3)
279    (SI_REG                       4)
280    (DI_REG                       5)
281    (BP_REG                       6)
282    (SP_REG                       7)
283    (ST0_REG                      8)
284    (ST1_REG                      9)
285    (ST2_REG                     10)
286    (ST3_REG                     11)
287    (ST4_REG                     12)
288    (ST5_REG                     13)
289    (ST6_REG                     14)
290    (ST7_REG                     15)
291    (FLAGS_REG                   17)
292    (FPSR_REG                    18)
293    (FPCR_REG                    19)
294    (XMM0_REG                    21)
295    (XMM1_REG                    22)
296    (XMM2_REG                    23)
297    (XMM3_REG                    24)
298    (XMM4_REG                    25)
299    (XMM5_REG                    26)
300    (XMM6_REG                    27)
301    (XMM7_REG                    28)
302    (MM0_REG                     29)
303    (MM1_REG                     30)
304    (MM2_REG                     31)
305    (MM3_REG                     32)
306    (MM4_REG                     33)
307    (MM5_REG                     34)
308    (MM6_REG                     35)
309    (MM7_REG                     36)
310    (R8_REG                      37)
311    (R9_REG                      38)
312    (R10_REG                     39)
313    (R11_REG                     40)
314    (R12_REG                     41)
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   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
419            (const_int 0)
420          (eq_attr "mode" "HI")
421            (const_int 1)
422          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
423            (const_int 1)
424         ]
425         (const_int 0)))
426
427 ;; Set when string REP prefix is used.
428 (define_attr "prefix_rep" ""
429   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
430            (const_int 0)
431          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
432            (const_int 1)
433         ]
434         (const_int 0)))
435
436 ;; Set when 0f opcode prefix is used.
437 (define_attr "prefix_0f" ""
438   (if_then_else
439     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
440          (eq_attr "unit" "sse,mmx"))
441     (const_int 1)
442     (const_int 0)))
443
444 ;; Set when REX opcode prefix is used.
445 (define_attr "prefix_rex" ""
446   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
447            (const_int 0)
448          (and (eq_attr "mode" "DI")
449               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
450                    (eq_attr "unit" "!mmx")))
451            (const_int 1)
452          (and (eq_attr "mode" "QI")
453               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
454                   (const_int 0)))
455            (const_int 1)
456          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
457              (const_int 0))
458            (const_int 1)
459          (and (eq_attr "type" "imovx")
460               (match_operand:QI 1 "ext_QIreg_operand" ""))
461            (const_int 1)
462         ]
463         (const_int 0)))
464
465 ;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
466 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
467 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
468 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
469 (define_attr "prefix_extra" ""
470   (cond [(eq_attr "type" "ssemuladd,sse4arg")
471            (const_int 2)
472          (eq_attr "type" "sseiadd1,ssecvt1")
473            (const_int 1)
474         ]
475         (const_int 0)))
476
477 ;; Prefix used: original, VEX or maybe VEX.
478 (define_attr "prefix" "orig,vex,maybe_vex"
479   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
480     (const_string "vex")
481     (const_string "orig")))
482
483 ;; VEX W bit is used.
484 (define_attr "prefix_vex_w" "" (const_int 0))
485
486 ;; The length of VEX prefix
487 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
488 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
489 ;; still prefix_0f 1, with prefix_extra 1.
490 (define_attr "length_vex" ""
491   (if_then_else (and (eq_attr "prefix_0f" "1")
492                      (eq_attr "prefix_extra" "0"))
493     (if_then_else (eq_attr "prefix_vex_w" "1")
494       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
495       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
496     (if_then_else (eq_attr "prefix_vex_w" "1")
497       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
498       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
499
500 ;; Set when modrm byte is used.
501 (define_attr "modrm" ""
502   (cond [(eq_attr "type" "str,leave")
503            (const_int 0)
504          (eq_attr "unit" "i387")
505            (const_int 0)
506          (and (eq_attr "type" "incdec")
507               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
508                    (ior (match_operand:SI 1 "register_operand" "")
509                         (match_operand:HI 1 "register_operand" ""))))
510            (const_int 0)
511          (and (eq_attr "type" "push")
512               (not (match_operand 1 "memory_operand" "")))
513            (const_int 0)
514          (and (eq_attr "type" "pop")
515               (not (match_operand 0 "memory_operand" "")))
516            (const_int 0)
517          (and (eq_attr "type" "imov")
518               (and (not (eq_attr "mode" "DI"))
519                    (ior (and (match_operand 0 "register_operand" "")
520                              (match_operand 1 "immediate_operand" ""))
521                         (ior (and (match_operand 0 "ax_reg_operand" "")
522                                   (match_operand 1 "memory_displacement_only_operand" ""))
523                              (and (match_operand 0 "memory_displacement_only_operand" "")
524                                   (match_operand 1 "ax_reg_operand" ""))))))
525            (const_int 0)
526          (and (eq_attr "type" "call")
527               (match_operand 0 "constant_call_address_operand" ""))
528              (const_int 0)
529          (and (eq_attr "type" "callv")
530               (match_operand 1 "constant_call_address_operand" ""))
531              (const_int 0)
532          (and (eq_attr "type" "alu,alu1,icmp,test")
533               (match_operand 0 "ax_reg_operand" ""))
534              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
535          ]
536          (const_int 1)))
537
538 ;; The (bounding maximum) length of an instruction in bytes.
539 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
540 ;; Later we may want to split them and compute proper length as for
541 ;; other insns.
542 (define_attr "length" ""
543   (cond [(eq_attr "type" "other,multi,fistp,frndint")
544            (const_int 16)
545          (eq_attr "type" "fcmp")
546            (const_int 4)
547          (eq_attr "unit" "i387")
548            (plus (const_int 2)
549                  (plus (attr "prefix_data16")
550                        (attr "length_address")))
551          (ior (eq_attr "prefix" "vex")
552               (and (eq_attr "prefix" "maybe_vex")
553                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
554            (plus (attr "length_vex")
555                  (plus (attr "length_immediate")
556                        (plus (attr "modrm")
557                              (attr "length_address"))))]
558          (plus (plus (attr "modrm")
559                      (plus (attr "prefix_0f")
560                            (plus (attr "prefix_rex")
561                                  (plus (attr "prefix_extra")
562                                        (const_int 1)))))
563                (plus (attr "prefix_rep")
564                      (plus (attr "prefix_data16")
565                            (plus (attr "length_immediate")
566                                  (attr "length_address")))))))
567
568 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
569 ;; `store' if there is a simple memory reference therein, or `unknown'
570 ;; if the instruction is complex.
571
572 (define_attr "memory" "none,load,store,both,unknown"
573   (cond [(eq_attr "type" "other,multi,str")
574            (const_string "unknown")
575          (eq_attr "type" "lea,fcmov,fpspc")
576            (const_string "none")
577          (eq_attr "type" "fistp,leave")
578            (const_string "both")
579          (eq_attr "type" "frndint")
580            (const_string "load")
581          (eq_attr "type" "push")
582            (if_then_else (match_operand 1 "memory_operand" "")
583              (const_string "both")
584              (const_string "store"))
585          (eq_attr "type" "pop")
586            (if_then_else (match_operand 0 "memory_operand" "")
587              (const_string "both")
588              (const_string "load"))
589          (eq_attr "type" "setcc")
590            (if_then_else (match_operand 0 "memory_operand" "")
591              (const_string "store")
592              (const_string "none"))
593          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
594            (if_then_else (ior (match_operand 0 "memory_operand" "")
595                               (match_operand 1 "memory_operand" ""))
596              (const_string "load")
597              (const_string "none"))
598          (eq_attr "type" "ibr")
599            (if_then_else (match_operand 0 "memory_operand" "")
600              (const_string "load")
601              (const_string "none"))
602          (eq_attr "type" "call")
603            (if_then_else (match_operand 0 "constant_call_address_operand" "")
604              (const_string "none")
605              (const_string "load"))
606          (eq_attr "type" "callv")
607            (if_then_else (match_operand 1 "constant_call_address_operand" "")
608              (const_string "none")
609              (const_string "load"))
610          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
611               (match_operand 1 "memory_operand" ""))
612            (const_string "both")
613          (and (match_operand 0 "memory_operand" "")
614               (match_operand 1 "memory_operand" ""))
615            (const_string "both")
616          (match_operand 0 "memory_operand" "")
617            (const_string "store")
618          (match_operand 1 "memory_operand" "")
619            (const_string "load")
620          (and (eq_attr "type"
621                  "!alu1,negnot,ishift1,
622                    imov,imovx,icmp,test,bitmanip,
623                    fmov,fcmp,fsgn,
624                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
625                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
626               (match_operand 2 "memory_operand" ""))
627            (const_string "load")
628          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
629               (match_operand 3 "memory_operand" ""))
630            (const_string "load")
631         ]
632         (const_string "none")))
633
634 ;; Indicates if an instruction has both an immediate and a displacement.
635
636 (define_attr "imm_disp" "false,true,unknown"
637   (cond [(eq_attr "type" "other,multi")
638            (const_string "unknown")
639          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
640               (and (match_operand 0 "memory_displacement_operand" "")
641                    (match_operand 1 "immediate_operand" "")))
642            (const_string "true")
643          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
644               (and (match_operand 0 "memory_displacement_operand" "")
645                    (match_operand 2 "immediate_operand" "")))
646            (const_string "true")
647         ]
648         (const_string "false")))
649
650 ;; Indicates if an FP operation has an integer source.
651
652 (define_attr "fp_int_src" "false,true"
653   (const_string "false"))
654
655 ;; Defines rounding mode of an FP operation.
656
657 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
658   (const_string "any"))
659
660 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
661 (define_attr "use_carry" "0,1" (const_string "0"))
662
663 ;; Define attribute to indicate unaligned ssemov insns
664 (define_attr "movu" "0,1" (const_string "0"))
665
666 ;; Describe a user's asm statement.
667 (define_asm_attributes
668   [(set_attr "length" "128")
669    (set_attr "type" "multi")])
670
671 ;; All integer comparison codes.
672 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
673
674 ;; All floating-point comparison codes.
675 (define_code_iterator fp_cond [unordered ordered
676                                uneq unge ungt unle unlt ltgt ])
677
678 (define_code_iterator plusminus [plus minus])
679
680 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
681
682 ;; Base name for define_insn
683 (define_code_attr plusminus_insn
684   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
685    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
686
687 ;; Base name for insn mnemonic.
688 (define_code_attr plusminus_mnemonic
689   [(plus "add") (ss_plus "adds") (us_plus "addus")
690    (minus "sub") (ss_minus "subs") (us_minus "subus")])
691
692 ;; Mark commutative operators as such in constraints.
693 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
694                         (minus "") (ss_minus "") (us_minus "")])
695
696 ;; Mapping of signed max and min
697 (define_code_iterator smaxmin [smax smin])
698
699 ;; Mapping of unsigned max and min
700 (define_code_iterator umaxmin [umax umin])
701
702 ;; Mapping of signed/unsigned max and min
703 (define_code_iterator maxmin [smax smin umax umin])
704
705 ;; Base name for integer and FP insn mnemonic
706 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
707                                  (umax "maxu") (umin "minu")])
708 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
709
710 ;; Mapping of parallel logic operators
711 (define_code_iterator plogic [and ior xor])
712
713 ;; Base name for insn mnemonic.
714 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
715
716 ;; Mapping of abs neg operators
717 (define_code_iterator absneg [abs neg])
718
719 ;; Base name for x87 insn mnemonic.
720 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
721
722 ;; All single word integer modes.
723 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
724
725 ;; Single word integer modes without QImode.
726 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
727
728 ;; Instruction suffix for integer modes.
729 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
730
731 ;; Register class for integer modes.
732 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
733
734 ;; Immediate operand constraint for integer modes.
735 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
736
737 ;; General operand predicate for integer modes.
738 (define_mode_attr general_operand
739         [(QI "general_operand")
740          (HI "general_operand")
741          (SI "general_operand")
742          (DI "x86_64_general_operand")])
743
744 ;; SSE and x87 SFmode and DFmode floating point modes
745 (define_mode_iterator MODEF [SF DF])
746
747 ;; All x87 floating point modes
748 (define_mode_iterator X87MODEF [SF DF XF])
749
750 ;; All integer modes handled by x87 fisttp operator.
751 (define_mode_iterator X87MODEI [HI SI DI])
752
753 ;; All integer modes handled by integer x87 operators.
754 (define_mode_iterator X87MODEI12 [HI SI])
755
756 ;; All integer modes handled by SSE cvtts?2si* operators.
757 (define_mode_iterator SSEMODEI24 [SI DI])
758
759 ;; SSE asm suffix for floating point modes
760 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
761
762 ;; SSE vector mode corresponding to a scalar mode
763 (define_mode_attr ssevecmode
764   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
765
766 ;; Instruction suffix for REX 64bit operators.
767 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
768
769 ;; This mode iterator allows :P to be used for patterns that operate on
770 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
771 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
772
773 \f
774 ;; Scheduling descriptions
775
776 (include "pentium.md")
777 (include "ppro.md")
778 (include "k6.md")
779 (include "athlon.md")
780 (include "geode.md")
781 (include "atom.md")
782
783 \f
784 ;; Operand and operator predicates and constraints
785
786 (include "predicates.md")
787 (include "constraints.md")
788
789 \f
790 ;; Compare and branch/compare and store instructions.
791
792 (define_expand "cbranchti4"
793   [(set (reg:CC FLAGS_REG)
794         (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
795                     (match_operand:TI 2 "x86_64_general_operand" "")))
796    (set (pc) (if_then_else
797               (match_operator 0 "comparison_operator"
798                [(reg:CC FLAGS_REG)
799                 (const_int 0)])
800               (label_ref (match_operand 3 "" ""))
801               (pc)))]
802   "TARGET_64BIT"
803 {
804   if (MEM_P (operands[1]) && MEM_P (operands[2]))
805     operands[1] = force_reg (TImode, operands[1]);
806   ix86_compare_op0 = operands[1];
807   ix86_compare_op1 = operands[2];
808   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
809   DONE;
810 })
811
812 (define_expand "cbranchdi4"
813   [(set (reg:CC FLAGS_REG)
814         (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
815                     (match_operand:DI 2 "x86_64_general_operand" "")))
816    (set (pc) (if_then_else
817               (match_operator 0 "comparison_operator"
818                [(reg:CC FLAGS_REG)
819                 (const_int 0)])
820               (label_ref (match_operand 3 "" ""))
821               (pc)))]
822   ""
823 {
824   if (MEM_P (operands[1]) && MEM_P (operands[2]))
825     operands[1] = force_reg (DImode, operands[1]);
826   ix86_compare_op0 = operands[1];
827   ix86_compare_op1 = operands[2];
828   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
829   DONE;
830 })
831
832 (define_expand "cstoredi4"
833   [(set (reg:CC FLAGS_REG)
834         (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
835                     (match_operand:DI 3 "x86_64_general_operand" "")))
836    (set (match_operand:QI 0 "register_operand" "")
837               (match_operator 1 "comparison_operator"
838                [(reg:CC FLAGS_REG)
839                 (const_int 0)]))]
840   "TARGET_64BIT"
841 {
842   if (MEM_P (operands[2]) && MEM_P (operands[3]))
843     operands[2] = force_reg (DImode, operands[2]);
844   ix86_compare_op0 = operands[2];
845   ix86_compare_op1 = operands[3];
846   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
847   DONE;
848 })
849
850 (define_expand "cbranchsi4"
851   [(set (reg:CC FLAGS_REG)
852         (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
853                     (match_operand:SI 2 "general_operand" "")))
854    (set (pc) (if_then_else
855               (match_operator 0 "comparison_operator"
856                [(reg:CC FLAGS_REG)
857                 (const_int 0)])
858               (label_ref (match_operand 3 "" ""))
859               (pc)))]
860   ""
861 {
862   if (MEM_P (operands[1]) && MEM_P (operands[2]))
863     operands[1] = force_reg (SImode, operands[1]);
864   ix86_compare_op0 = operands[1];
865   ix86_compare_op1 = operands[2];
866   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
867   DONE;
868 })
869
870 (define_expand "cstoresi4"
871   [(set (reg:CC FLAGS_REG)
872         (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
873                     (match_operand:SI 3 "general_operand" "")))
874    (set (match_operand:QI 0 "register_operand" "")
875               (match_operator 1 "comparison_operator"
876                [(reg:CC FLAGS_REG)
877                 (const_int 0)]))]
878   ""
879 {
880   if (MEM_P (operands[2]) && MEM_P (operands[3]))
881     operands[2] = force_reg (SImode, operands[2]);
882   ix86_compare_op0 = operands[2];
883   ix86_compare_op1 = operands[3];
884   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
885   DONE;
886 })
887
888 (define_expand "cbranchhi4"
889   [(set (reg:CC FLAGS_REG)
890         (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
891                     (match_operand:HI 2 "general_operand" "")))
892    (set (pc) (if_then_else
893               (match_operator 0 "comparison_operator"
894                [(reg:CC FLAGS_REG)
895                 (const_int 0)])
896               (label_ref (match_operand 3 "" ""))
897               (pc)))]
898   ""
899 {
900   if (MEM_P (operands[1]) && MEM_P (operands[2]))
901     operands[1] = force_reg (HImode, operands[1]);
902   ix86_compare_op0 = operands[1];
903   ix86_compare_op1 = operands[2];
904   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
905   DONE;
906 })
907
908 (define_expand "cstorehi4"
909   [(set (reg:CC FLAGS_REG)
910         (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
911                     (match_operand:HI 3 "general_operand" "")))
912    (set (match_operand:QI 0 "register_operand" "")
913               (match_operator 1 "comparison_operator"
914                [(reg:CC FLAGS_REG)
915                 (const_int 0)]))]
916   ""
917 {
918   if (MEM_P (operands[2]) && MEM_P (operands[3]))
919     operands[2] = force_reg (HImode, operands[2]);
920   ix86_compare_op0 = operands[2];
921   ix86_compare_op1 = operands[3];
922   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
923   DONE;
924 })
925
926
927 (define_expand "cbranchqi4"
928   [(set (reg:CC FLAGS_REG)
929         (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
930                     (match_operand:QI 2 "general_operand" "")))
931    (set (pc) (if_then_else
932               (match_operator 0 "comparison_operator"
933                [(reg:CC FLAGS_REG)
934                 (const_int 0)])
935               (label_ref (match_operand 3 "" ""))
936               (pc)))]
937   ""
938 {
939   if (MEM_P (operands[1]) && MEM_P (operands[2]))
940     operands[1] = force_reg (QImode, operands[1]);
941   ix86_compare_op0 = operands[1];
942   ix86_compare_op1 = operands[2];
943   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
944   DONE;
945 })
946
947
948 (define_expand "cstoreqi4"
949   [(set (reg:CC FLAGS_REG)
950         (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
951                     (match_operand:QI 3 "general_operand" "")))
952    (set (match_operand:QI 0 "register_operand" "")
953               (match_operator 1 "comparison_operator"
954                [(reg:CC FLAGS_REG)
955                 (const_int 0)]))]
956   ""
957 {
958   if (MEM_P (operands[2]) && MEM_P (operands[3]))
959     operands[2] = force_reg (QImode, operands[2]);
960   ix86_compare_op0 = operands[2];
961   ix86_compare_op1 = operands[3];
962   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
963   DONE;
964 })
965
966
967 (define_insn "cmpdi_ccno_1_rex64"
968   [(set (reg FLAGS_REG)
969         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
970                  (match_operand:DI 1 "const0_operand" "")))]
971   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
972   "@
973    test{q}\t%0, %0
974    cmp{q}\t{%1, %0|%0, %1}"
975   [(set_attr "type" "test,icmp")
976    (set_attr "length_immediate" "0,1")
977    (set_attr "mode" "DI")])
978
979 (define_insn "*cmpdi_minus_1_rex64"
980   [(set (reg FLAGS_REG)
981         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
982                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
983                  (const_int 0)))]
984   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
985   "cmp{q}\t{%1, %0|%0, %1}"
986   [(set_attr "type" "icmp")
987    (set_attr "mode" "DI")])
988
989 (define_expand "cmpdi_1_rex64"
990   [(set (reg:CC FLAGS_REG)
991         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
992                     (match_operand:DI 1 "general_operand" "")))]
993   "TARGET_64BIT"
994   "")
995
996 (define_insn "cmpdi_1_insn_rex64"
997   [(set (reg FLAGS_REG)
998         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
999                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1000   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001   "cmp{q}\t{%1, %0|%0, %1}"
1002   [(set_attr "type" "icmp")
1003    (set_attr "mode" "DI")])
1004
1005
1006 (define_insn "*cmpsi_ccno_1"
1007   [(set (reg FLAGS_REG)
1008         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1009                  (match_operand:SI 1 "const0_operand" "")))]
1010   "ix86_match_ccmode (insn, CCNOmode)"
1011   "@
1012    test{l}\t%0, %0
1013    cmp{l}\t{%1, %0|%0, %1}"
1014   [(set_attr "type" "test,icmp")
1015    (set_attr "length_immediate" "0,1")
1016    (set_attr "mode" "SI")])
1017
1018 (define_insn "*cmpsi_minus_1"
1019   [(set (reg FLAGS_REG)
1020         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1021                            (match_operand:SI 1 "general_operand" "ri,mr"))
1022                  (const_int 0)))]
1023   "ix86_match_ccmode (insn, CCGOCmode)"
1024   "cmp{l}\t{%1, %0|%0, %1}"
1025   [(set_attr "type" "icmp")
1026    (set_attr "mode" "SI")])
1027
1028 (define_expand "cmpsi_1"
1029   [(set (reg:CC FLAGS_REG)
1030         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1031                     (match_operand:SI 1 "general_operand" "")))]
1032   ""
1033   "")
1034
1035 (define_insn "*cmpsi_1_insn"
1036   [(set (reg FLAGS_REG)
1037         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1038                  (match_operand:SI 1 "general_operand" "ri,mr")))]
1039   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1040     && ix86_match_ccmode (insn, CCmode)"
1041   "cmp{l}\t{%1, %0|%0, %1}"
1042   [(set_attr "type" "icmp")
1043    (set_attr "mode" "SI")])
1044
1045 (define_insn "*cmphi_ccno_1"
1046   [(set (reg FLAGS_REG)
1047         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1048                  (match_operand:HI 1 "const0_operand" "")))]
1049   "ix86_match_ccmode (insn, CCNOmode)"
1050   "@
1051    test{w}\t%0, %0
1052    cmp{w}\t{%1, %0|%0, %1}"
1053   [(set_attr "type" "test,icmp")
1054    (set_attr "length_immediate" "0,1")
1055    (set_attr "mode" "HI")])
1056
1057 (define_insn "*cmphi_minus_1"
1058   [(set (reg FLAGS_REG)
1059         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1060                            (match_operand:HI 1 "general_operand" "rn,mr"))
1061                  (const_int 0)))]
1062   "ix86_match_ccmode (insn, CCGOCmode)"
1063   "cmp{w}\t{%1, %0|%0, %1}"
1064   [(set_attr "type" "icmp")
1065    (set_attr "mode" "HI")])
1066
1067 (define_insn "*cmphi_1"
1068   [(set (reg FLAGS_REG)
1069         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1070                  (match_operand:HI 1 "general_operand" "rn,mr")))]
1071   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1072    && ix86_match_ccmode (insn, CCmode)"
1073   "cmp{w}\t{%1, %0|%0, %1}"
1074   [(set_attr "type" "icmp")
1075    (set_attr "mode" "HI")])
1076
1077 (define_insn "*cmpqi_ccno_1"
1078   [(set (reg FLAGS_REG)
1079         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1080                  (match_operand:QI 1 "const0_operand" "")))]
1081   "ix86_match_ccmode (insn, CCNOmode)"
1082   "@
1083    test{b}\t%0, %0
1084    cmp{b}\t{$0, %0|%0, 0}"
1085   [(set_attr "type" "test,icmp")
1086    (set_attr "length_immediate" "0,1")
1087    (set_attr "mode" "QI")])
1088
1089 (define_insn "*cmpqi_1"
1090   [(set (reg FLAGS_REG)
1091         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1092                  (match_operand:QI 1 "general_operand" "qn,mq")))]
1093   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1094     && ix86_match_ccmode (insn, CCmode)"
1095   "cmp{b}\t{%1, %0|%0, %1}"
1096   [(set_attr "type" "icmp")
1097    (set_attr "mode" "QI")])
1098
1099 (define_insn "*cmpqi_minus_1"
1100   [(set (reg FLAGS_REG)
1101         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1102                            (match_operand:QI 1 "general_operand" "qn,mq"))
1103                  (const_int 0)))]
1104   "ix86_match_ccmode (insn, CCGOCmode)"
1105   "cmp{b}\t{%1, %0|%0, %1}"
1106   [(set_attr "type" "icmp")
1107    (set_attr "mode" "QI")])
1108
1109 (define_insn "*cmpqi_ext_1"
1110   [(set (reg FLAGS_REG)
1111         (compare
1112           (match_operand:QI 0 "general_operand" "Qm")
1113           (subreg:QI
1114             (zero_extract:SI
1115               (match_operand 1 "ext_register_operand" "Q")
1116               (const_int 8)
1117               (const_int 8)) 0)))]
1118   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1119   "cmp{b}\t{%h1, %0|%0, %h1}"
1120   [(set_attr "type" "icmp")
1121    (set_attr "mode" "QI")])
1122
1123 (define_insn "*cmpqi_ext_1_rex64"
1124   [(set (reg FLAGS_REG)
1125         (compare
1126           (match_operand:QI 0 "register_operand" "Q")
1127           (subreg:QI
1128             (zero_extract:SI
1129               (match_operand 1 "ext_register_operand" "Q")
1130               (const_int 8)
1131               (const_int 8)) 0)))]
1132   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1133   "cmp{b}\t{%h1, %0|%0, %h1}"
1134   [(set_attr "type" "icmp")
1135    (set_attr "mode" "QI")])
1136
1137 (define_insn "*cmpqi_ext_2"
1138   [(set (reg FLAGS_REG)
1139         (compare
1140           (subreg:QI
1141             (zero_extract:SI
1142               (match_operand 0 "ext_register_operand" "Q")
1143               (const_int 8)
1144               (const_int 8)) 0)
1145           (match_operand:QI 1 "const0_operand" "")))]
1146   "ix86_match_ccmode (insn, CCNOmode)"
1147   "test{b}\t%h0, %h0"
1148   [(set_attr "type" "test")
1149    (set_attr "length_immediate" "0")
1150    (set_attr "mode" "QI")])
1151
1152 (define_expand "cmpqi_ext_3"
1153   [(set (reg:CC FLAGS_REG)
1154         (compare:CC
1155           (subreg:QI
1156             (zero_extract:SI
1157               (match_operand 0 "ext_register_operand" "")
1158               (const_int 8)
1159               (const_int 8)) 0)
1160           (match_operand:QI 1 "general_operand" "")))]
1161   ""
1162   "")
1163
1164 (define_insn "cmpqi_ext_3_insn"
1165   [(set (reg FLAGS_REG)
1166         (compare
1167           (subreg:QI
1168             (zero_extract:SI
1169               (match_operand 0 "ext_register_operand" "Q")
1170               (const_int 8)
1171               (const_int 8)) 0)
1172           (match_operand:QI 1 "general_operand" "Qmn")))]
1173   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1174   "cmp{b}\t{%1, %h0|%h0, %1}"
1175   [(set_attr "type" "icmp")
1176    (set_attr "modrm" "1")
1177    (set_attr "mode" "QI")])
1178
1179 (define_insn "cmpqi_ext_3_insn_rex64"
1180   [(set (reg FLAGS_REG)
1181         (compare
1182           (subreg:QI
1183             (zero_extract:SI
1184               (match_operand 0 "ext_register_operand" "Q")
1185               (const_int 8)
1186               (const_int 8)) 0)
1187           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1188   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1189   "cmp{b}\t{%1, %h0|%h0, %1}"
1190   [(set_attr "type" "icmp")
1191    (set_attr "modrm" "1")
1192    (set_attr "mode" "QI")])
1193
1194 (define_insn "*cmpqi_ext_4"
1195   [(set (reg FLAGS_REG)
1196         (compare
1197           (subreg:QI
1198             (zero_extract:SI
1199               (match_operand 0 "ext_register_operand" "Q")
1200               (const_int 8)
1201               (const_int 8)) 0)
1202           (subreg:QI
1203             (zero_extract:SI
1204               (match_operand 1 "ext_register_operand" "Q")
1205               (const_int 8)
1206               (const_int 8)) 0)))]
1207   "ix86_match_ccmode (insn, CCmode)"
1208   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1209   [(set_attr "type" "icmp")
1210    (set_attr "mode" "QI")])
1211
1212 ;; These implement float point compares.
1213 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1214 ;; which would allow mix and match FP modes on the compares.  Which is what
1215 ;; the old patterns did, but with many more of them.
1216
1217 (define_expand "cbranchxf4"
1218   [(set (reg:CC FLAGS_REG)
1219         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1220                     (match_operand:XF 2 "nonmemory_operand" "")))
1221    (set (pc) (if_then_else
1222               (match_operator 0 "comparison_operator"
1223                [(reg:CC FLAGS_REG)
1224                 (const_int 0)])
1225               (label_ref (match_operand 3 "" ""))
1226               (pc)))]
1227   "TARGET_80387"
1228 {
1229   ix86_compare_op0 = operands[1];
1230   ix86_compare_op1 = operands[2];
1231   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1232   DONE;
1233 })
1234
1235 (define_expand "cstorexf4"
1236   [(set (reg:CC FLAGS_REG)
1237         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1238                     (match_operand:XF 3 "nonmemory_operand" "")))
1239    (set (match_operand:QI 0 "register_operand" "")
1240               (match_operator 1 "comparison_operator"
1241                [(reg:CC FLAGS_REG)
1242                 (const_int 0)]))]
1243   "TARGET_80387"
1244 {
1245   ix86_compare_op0 = operands[2];
1246   ix86_compare_op1 = operands[3];
1247   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1248   DONE;
1249 })
1250
1251 (define_expand "cbranch<mode>4"
1252   [(set (reg:CC FLAGS_REG)
1253         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1254                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1255    (set (pc) (if_then_else
1256               (match_operator 0 "comparison_operator"
1257                [(reg:CC FLAGS_REG)
1258                 (const_int 0)])
1259               (label_ref (match_operand 3 "" ""))
1260               (pc)))]
1261   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1262 {
1263   ix86_compare_op0 = operands[1];
1264   ix86_compare_op1 = operands[2];
1265   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1266   DONE;
1267 })
1268
1269 (define_expand "cstore<mode>4"
1270   [(set (reg:CC FLAGS_REG)
1271         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1272                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1273    (set (match_operand:QI 0 "register_operand" "")
1274               (match_operator 1 "comparison_operator"
1275                [(reg:CC FLAGS_REG)
1276                 (const_int 0)]))]
1277   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1278 {
1279   ix86_compare_op0 = operands[2];
1280   ix86_compare_op1 = operands[3];
1281   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1282   DONE;
1283 })
1284
1285 (define_expand "cbranchcc4"
1286   [(set (pc) (if_then_else
1287               (match_operator 0 "comparison_operator"
1288                [(match_operand 1 "flags_reg_operand" "")
1289                 (match_operand 2 "const0_operand" "")])
1290               (label_ref (match_operand 3 "" ""))
1291               (pc)))]
1292   ""
1293 {
1294   ix86_compare_op0 = operands[1];
1295   ix86_compare_op1 = operands[2];
1296   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1297   DONE;
1298 })
1299
1300 (define_expand "cstorecc4"
1301   [(set (match_operand:QI 0 "register_operand" "")
1302               (match_operator 1 "comparison_operator"
1303                [(match_operand 2 "flags_reg_operand" "")
1304                 (match_operand 3 "const0_operand" "")]))]
1305   ""
1306 {
1307   ix86_compare_op0 = operands[2];
1308   ix86_compare_op1 = operands[3];
1309   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1310   DONE;
1311 })
1312
1313
1314 ;; FP compares, step 1:
1315 ;; Set the FP condition codes.
1316 ;;
1317 ;; CCFPmode     compare with exceptions
1318 ;; CCFPUmode    compare with no exceptions
1319
1320 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1321 ;; used to manage the reg stack popping would not be preserved.
1322
1323 (define_insn "*cmpfp_0"
1324   [(set (match_operand:HI 0 "register_operand" "=a")
1325         (unspec:HI
1326           [(compare:CCFP
1327              (match_operand 1 "register_operand" "f")
1328              (match_operand 2 "const0_operand" ""))]
1329         UNSPEC_FNSTSW))]
1330   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1331    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1332   "* return output_fp_compare (insn, operands, 0, 0);"
1333   [(set_attr "type" "multi")
1334    (set_attr "unit" "i387")
1335    (set (attr "mode")
1336      (cond [(match_operand:SF 1 "" "")
1337               (const_string "SF")
1338             (match_operand:DF 1 "" "")
1339               (const_string "DF")
1340            ]
1341            (const_string "XF")))])
1342
1343 (define_insn_and_split "*cmpfp_0_cc"
1344   [(set (reg:CCFP FLAGS_REG)
1345         (compare:CCFP
1346           (match_operand 1 "register_operand" "f")
1347           (match_operand 2 "const0_operand" "")))
1348    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1350    && TARGET_SAHF && !TARGET_CMOVE
1351    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1352   "#"
1353   "&& reload_completed"
1354   [(set (match_dup 0)
1355         (unspec:HI
1356           [(compare:CCFP (match_dup 1)(match_dup 2))]
1357         UNSPEC_FNSTSW))
1358    (set (reg:CC FLAGS_REG)
1359         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1360   ""
1361   [(set_attr "type" "multi")
1362    (set_attr "unit" "i387")
1363    (set (attr "mode")
1364      (cond [(match_operand:SF 1 "" "")
1365               (const_string "SF")
1366             (match_operand:DF 1 "" "")
1367               (const_string "DF")
1368            ]
1369            (const_string "XF")))])
1370
1371 (define_insn "*cmpfp_xf"
1372   [(set (match_operand:HI 0 "register_operand" "=a")
1373         (unspec:HI
1374           [(compare:CCFP
1375              (match_operand:XF 1 "register_operand" "f")
1376              (match_operand:XF 2 "register_operand" "f"))]
1377           UNSPEC_FNSTSW))]
1378   "TARGET_80387"
1379   "* return output_fp_compare (insn, operands, 0, 0);"
1380   [(set_attr "type" "multi")
1381    (set_attr "unit" "i387")
1382    (set_attr "mode" "XF")])
1383
1384 (define_insn_and_split "*cmpfp_xf_cc"
1385   [(set (reg:CCFP FLAGS_REG)
1386         (compare:CCFP
1387           (match_operand:XF 1 "register_operand" "f")
1388           (match_operand:XF 2 "register_operand" "f")))
1389    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1390   "TARGET_80387
1391    && TARGET_SAHF && !TARGET_CMOVE"
1392   "#"
1393   "&& reload_completed"
1394   [(set (match_dup 0)
1395         (unspec:HI
1396           [(compare:CCFP (match_dup 1)(match_dup 2))]
1397         UNSPEC_FNSTSW))
1398    (set (reg:CC FLAGS_REG)
1399         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1400   ""
1401   [(set_attr "type" "multi")
1402    (set_attr "unit" "i387")
1403    (set_attr "mode" "XF")])
1404
1405 (define_insn "*cmpfp_<mode>"
1406   [(set (match_operand:HI 0 "register_operand" "=a")
1407         (unspec:HI
1408           [(compare:CCFP
1409              (match_operand:MODEF 1 "register_operand" "f")
1410              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1411           UNSPEC_FNSTSW))]
1412   "TARGET_80387"
1413   "* return output_fp_compare (insn, operands, 0, 0);"
1414   [(set_attr "type" "multi")
1415    (set_attr "unit" "i387")
1416    (set_attr "mode" "<MODE>")])
1417
1418 (define_insn_and_split "*cmpfp_<mode>_cc"
1419   [(set (reg:CCFP FLAGS_REG)
1420         (compare:CCFP
1421           (match_operand:MODEF 1 "register_operand" "f")
1422           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1423    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1424   "TARGET_80387
1425    && TARGET_SAHF && !TARGET_CMOVE"
1426   "#"
1427   "&& reload_completed"
1428   [(set (match_dup 0)
1429         (unspec:HI
1430           [(compare:CCFP (match_dup 1)(match_dup 2))]
1431         UNSPEC_FNSTSW))
1432    (set (reg:CC FLAGS_REG)
1433         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1434   ""
1435   [(set_attr "type" "multi")
1436    (set_attr "unit" "i387")
1437    (set_attr "mode" "<MODE>")])
1438
1439 (define_insn "*cmpfp_u"
1440   [(set (match_operand:HI 0 "register_operand" "=a")
1441         (unspec:HI
1442           [(compare:CCFPU
1443              (match_operand 1 "register_operand" "f")
1444              (match_operand 2 "register_operand" "f"))]
1445           UNSPEC_FNSTSW))]
1446   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1447    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1448   "* return output_fp_compare (insn, operands, 0, 1);"
1449   [(set_attr "type" "multi")
1450    (set_attr "unit" "i387")
1451    (set (attr "mode")
1452      (cond [(match_operand:SF 1 "" "")
1453               (const_string "SF")
1454             (match_operand:DF 1 "" "")
1455               (const_string "DF")
1456            ]
1457            (const_string "XF")))])
1458
1459 (define_insn_and_split "*cmpfp_u_cc"
1460   [(set (reg:CCFPU FLAGS_REG)
1461         (compare:CCFPU
1462           (match_operand 1 "register_operand" "f")
1463           (match_operand 2 "register_operand" "f")))
1464    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1465   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1466    && TARGET_SAHF && !TARGET_CMOVE
1467    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1468   "#"
1469   "&& reload_completed"
1470   [(set (match_dup 0)
1471         (unspec:HI
1472           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1473         UNSPEC_FNSTSW))
1474    (set (reg:CC FLAGS_REG)
1475         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1476   ""
1477   [(set_attr "type" "multi")
1478    (set_attr "unit" "i387")
1479    (set (attr "mode")
1480      (cond [(match_operand:SF 1 "" "")
1481               (const_string "SF")
1482             (match_operand:DF 1 "" "")
1483               (const_string "DF")
1484            ]
1485            (const_string "XF")))])
1486
1487 (define_insn "*cmpfp_<mode>"
1488   [(set (match_operand:HI 0 "register_operand" "=a")
1489         (unspec:HI
1490           [(compare:CCFP
1491              (match_operand 1 "register_operand" "f")
1492              (match_operator 3 "float_operator"
1493                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1494           UNSPEC_FNSTSW))]
1495   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1496    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1497    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1498   "* return output_fp_compare (insn, operands, 0, 0);"
1499   [(set_attr "type" "multi")
1500    (set_attr "unit" "i387")
1501    (set_attr "fp_int_src" "true")
1502    (set_attr "mode" "<MODE>")])
1503
1504 (define_insn_and_split "*cmpfp_<mode>_cc"
1505   [(set (reg:CCFP FLAGS_REG)
1506         (compare:CCFP
1507           (match_operand 1 "register_operand" "f")
1508           (match_operator 3 "float_operator"
1509             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1510    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1511   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1512    && TARGET_SAHF && !TARGET_CMOVE
1513    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1514    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1515   "#"
1516   "&& reload_completed"
1517   [(set (match_dup 0)
1518         (unspec:HI
1519           [(compare:CCFP
1520              (match_dup 1)
1521              (match_op_dup 3 [(match_dup 2)]))]
1522         UNSPEC_FNSTSW))
1523    (set (reg:CC FLAGS_REG)
1524         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1525   ""
1526   [(set_attr "type" "multi")
1527    (set_attr "unit" "i387")
1528    (set_attr "fp_int_src" "true")
1529    (set_attr "mode" "<MODE>")])
1530
1531 ;; FP compares, step 2
1532 ;; Move the fpsw to ax.
1533
1534 (define_insn "x86_fnstsw_1"
1535   [(set (match_operand:HI 0 "register_operand" "=a")
1536         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1537   "TARGET_80387"
1538   "fnstsw\t%0"
1539   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1540    (set_attr "mode" "SI")
1541    (set_attr "unit" "i387")])
1542
1543 ;; FP compares, step 3
1544 ;; Get ax into flags, general case.
1545
1546 (define_insn "x86_sahf_1"
1547   [(set (reg:CC FLAGS_REG)
1548         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1549                    UNSPEC_SAHF))]
1550   "TARGET_SAHF"
1551 {
1552 #ifdef HAVE_AS_IX86_SAHF
1553   return "sahf";
1554 #else
1555   return ".byte\t0x9e";
1556 #endif
1557 }
1558   [(set_attr "length" "1")
1559    (set_attr "athlon_decode" "vector")
1560    (set_attr "amdfam10_decode" "direct")
1561    (set_attr "mode" "SI")])
1562
1563 ;; Pentium Pro can do steps 1 through 3 in one go.
1564 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1565 (define_insn "*cmpfp_i_mixed"
1566   [(set (reg:CCFP FLAGS_REG)
1567         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1568                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1569   "TARGET_MIX_SSE_I387
1570    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1571    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572   "* return output_fp_compare (insn, operands, 1, 0);"
1573   [(set_attr "type" "fcmp,ssecomi")
1574    (set_attr "prefix" "orig,maybe_vex")
1575    (set (attr "mode")
1576      (if_then_else (match_operand:SF 1 "" "")
1577         (const_string "SF")
1578         (const_string "DF")))
1579    (set (attr "prefix_rep")
1580         (if_then_else (eq_attr "type" "ssecomi")
1581                       (const_string "0")
1582                       (const_string "*")))
1583    (set (attr "prefix_data16")
1584         (cond [(eq_attr "type" "fcmp")
1585                  (const_string "*")
1586                (eq_attr "mode" "DF")
1587                  (const_string "1")
1588               ]
1589               (const_string "0")))
1590    (set_attr "athlon_decode" "vector")
1591    (set_attr "amdfam10_decode" "direct")])
1592
1593 (define_insn "*cmpfp_i_sse"
1594   [(set (reg:CCFP FLAGS_REG)
1595         (compare:CCFP (match_operand 0 "register_operand" "x")
1596                       (match_operand 1 "nonimmediate_operand" "xm")))]
1597   "TARGET_SSE_MATH
1598    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1599    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1600   "* return output_fp_compare (insn, operands, 1, 0);"
1601   [(set_attr "type" "ssecomi")
1602    (set_attr "prefix" "maybe_vex")
1603    (set (attr "mode")
1604      (if_then_else (match_operand:SF 1 "" "")
1605         (const_string "SF")
1606         (const_string "DF")))
1607    (set_attr "prefix_rep" "0")
1608    (set (attr "prefix_data16")
1609         (if_then_else (eq_attr "mode" "DF")
1610                       (const_string "1")
1611                       (const_string "0")))
1612    (set_attr "athlon_decode" "vector")
1613    (set_attr "amdfam10_decode" "direct")])
1614
1615 (define_insn "*cmpfp_i_i387"
1616   [(set (reg:CCFP FLAGS_REG)
1617         (compare:CCFP (match_operand 0 "register_operand" "f")
1618                       (match_operand 1 "register_operand" "f")))]
1619   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1620    && TARGET_CMOVE
1621    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1622    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1623   "* return output_fp_compare (insn, operands, 1, 0);"
1624   [(set_attr "type" "fcmp")
1625    (set (attr "mode")
1626      (cond [(match_operand:SF 1 "" "")
1627               (const_string "SF")
1628             (match_operand:DF 1 "" "")
1629               (const_string "DF")
1630            ]
1631            (const_string "XF")))
1632    (set_attr "athlon_decode" "vector")
1633    (set_attr "amdfam10_decode" "direct")])
1634
1635 (define_insn "*cmpfp_iu_mixed"
1636   [(set (reg:CCFPU FLAGS_REG)
1637         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1638                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1639   "TARGET_MIX_SSE_I387
1640    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1641    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1642   "* return output_fp_compare (insn, operands, 1, 1);"
1643   [(set_attr "type" "fcmp,ssecomi")
1644    (set_attr "prefix" "orig,maybe_vex")
1645    (set (attr "mode")
1646      (if_then_else (match_operand:SF 1 "" "")
1647         (const_string "SF")
1648         (const_string "DF")))
1649    (set (attr "prefix_rep")
1650         (if_then_else (eq_attr "type" "ssecomi")
1651                       (const_string "0")
1652                       (const_string "*")))
1653    (set (attr "prefix_data16")
1654         (cond [(eq_attr "type" "fcmp")
1655                  (const_string "*")
1656                (eq_attr "mode" "DF")
1657                  (const_string "1")
1658               ]
1659               (const_string "0")))
1660    (set_attr "athlon_decode" "vector")
1661    (set_attr "amdfam10_decode" "direct")])
1662
1663 (define_insn "*cmpfp_iu_sse"
1664   [(set (reg:CCFPU FLAGS_REG)
1665         (compare:CCFPU (match_operand 0 "register_operand" "x")
1666                        (match_operand 1 "nonimmediate_operand" "xm")))]
1667   "TARGET_SSE_MATH
1668    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1669    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1670   "* return output_fp_compare (insn, operands, 1, 1);"
1671   [(set_attr "type" "ssecomi")
1672    (set_attr "prefix" "maybe_vex")
1673    (set (attr "mode")
1674      (if_then_else (match_operand:SF 1 "" "")
1675         (const_string "SF")
1676         (const_string "DF")))
1677    (set_attr "prefix_rep" "0")
1678    (set (attr "prefix_data16")
1679         (if_then_else (eq_attr "mode" "DF")
1680                       (const_string "1")
1681                       (const_string "0")))
1682    (set_attr "athlon_decode" "vector")
1683    (set_attr "amdfam10_decode" "direct")])
1684
1685 (define_insn "*cmpfp_iu_387"
1686   [(set (reg:CCFPU FLAGS_REG)
1687         (compare:CCFPU (match_operand 0 "register_operand" "f")
1688                        (match_operand 1 "register_operand" "f")))]
1689   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1690    && TARGET_CMOVE
1691    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1692    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1693   "* return output_fp_compare (insn, operands, 1, 1);"
1694   [(set_attr "type" "fcmp")
1695    (set (attr "mode")
1696      (cond [(match_operand:SF 1 "" "")
1697               (const_string "SF")
1698             (match_operand:DF 1 "" "")
1699               (const_string "DF")
1700            ]
1701            (const_string "XF")))
1702    (set_attr "athlon_decode" "vector")
1703    (set_attr "amdfam10_decode" "direct")])
1704 \f
1705 ;; Move instructions.
1706
1707 ;; General case of fullword move.
1708
1709 (define_expand "movsi"
1710   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1711         (match_operand:SI 1 "general_operand" ""))]
1712   ""
1713   "ix86_expand_move (SImode, operands); DONE;")
1714
1715 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1716 ;; general_operand.
1717 ;;
1718 ;; %%% We don't use a post-inc memory reference because x86 is not a
1719 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1720 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1721 ;; targets without our curiosities, and it is just as easy to represent
1722 ;; this differently.
1723
1724 (define_insn "*pushsi2"
1725   [(set (match_operand:SI 0 "push_operand" "=<")
1726         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727   "!TARGET_64BIT"
1728   "push{l}\t%1"
1729   [(set_attr "type" "push")
1730    (set_attr "mode" "SI")])
1731
1732 ;; For 64BIT abi we always round up to 8 bytes.
1733 (define_insn "*pushsi2_rex64"
1734   [(set (match_operand:SI 0 "push_operand" "=X")
1735         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1736   "TARGET_64BIT"
1737   "push{q}\t%q1"
1738   [(set_attr "type" "push")
1739    (set_attr "mode" "SI")])
1740
1741 (define_insn "*pushsi2_prologue"
1742   [(set (match_operand:SI 0 "push_operand" "=<")
1743         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1744    (clobber (mem:BLK (scratch)))]
1745   "!TARGET_64BIT"
1746   "push{l}\t%1"
1747   [(set_attr "type" "push")
1748    (set_attr "mode" "SI")])
1749
1750 (define_insn "*popsi1_epilogue"
1751   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1752         (mem:SI (reg:SI SP_REG)))
1753    (set (reg:SI SP_REG)
1754         (plus:SI (reg:SI SP_REG) (const_int 4)))
1755    (clobber (mem:BLK (scratch)))]
1756   "!TARGET_64BIT"
1757   "pop{l}\t%0"
1758   [(set_attr "type" "pop")
1759    (set_attr "mode" "SI")])
1760
1761 (define_insn "popsi1"
1762   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1763         (mem:SI (reg:SI SP_REG)))
1764    (set (reg:SI SP_REG)
1765         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1766   "!TARGET_64BIT"
1767   "pop{l}\t%0"
1768   [(set_attr "type" "pop")
1769    (set_attr "mode" "SI")])
1770
1771 (define_insn "*movsi_xor"
1772   [(set (match_operand:SI 0 "register_operand" "=r")
1773         (match_operand:SI 1 "const0_operand" ""))
1774    (clobber (reg:CC FLAGS_REG))]
1775   "reload_completed"
1776   "xor{l}\t%0, %0"
1777   [(set_attr "type" "alu1")
1778    (set_attr "mode" "SI")
1779    (set_attr "length_immediate" "0")])
1780
1781 (define_insn "*movsi_or"
1782   [(set (match_operand:SI 0 "register_operand" "=r")
1783         (match_operand:SI 1 "immediate_operand" "i"))
1784    (clobber (reg:CC FLAGS_REG))]
1785   "reload_completed
1786    && operands[1] == constm1_rtx"
1787 {
1788   operands[1] = constm1_rtx;
1789   return "or{l}\t{%1, %0|%0, %1}";
1790 }
1791   [(set_attr "type" "alu1")
1792    (set_attr "mode" "SI")
1793    (set_attr "length_immediate" "1")])
1794
1795 (define_insn "*movsi_1"
1796   [(set (match_operand:SI 0 "nonimmediate_operand"
1797                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1798         (match_operand:SI 1 "general_operand"
1799                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1800   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 {
1802   switch (get_attr_type (insn))
1803     {
1804     case TYPE_SSELOG1:
1805       if (get_attr_mode (insn) == MODE_TI)
1806         return "%vpxor\t%0, %d0";
1807       return "%vxorps\t%0, %d0";
1808
1809     case TYPE_SSEMOV:
1810       switch (get_attr_mode (insn))
1811         {
1812         case MODE_TI:
1813           return "%vmovdqa\t{%1, %0|%0, %1}";
1814         case MODE_V4SF:
1815           return "%vmovaps\t{%1, %0|%0, %1}";
1816         case MODE_SI:
1817           return "%vmovd\t{%1, %0|%0, %1}";
1818         case MODE_SF:
1819           return "%vmovss\t{%1, %0|%0, %1}";
1820         default:
1821           gcc_unreachable ();
1822         }
1823
1824     case TYPE_MMX:
1825       return "pxor\t%0, %0";
1826
1827     case TYPE_MMXMOV:
1828       if (get_attr_mode (insn) == MODE_DI)
1829         return "movq\t{%1, %0|%0, %1}";
1830       return "movd\t{%1, %0|%0, %1}";
1831
1832     case TYPE_LEA:
1833       return "lea{l}\t{%1, %0|%0, %1}";
1834
1835     default:
1836       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1837       return "mov{l}\t{%1, %0|%0, %1}";
1838     }
1839 }
1840   [(set (attr "type")
1841      (cond [(eq_attr "alternative" "2")
1842               (const_string "mmx")
1843             (eq_attr "alternative" "3,4,5")
1844               (const_string "mmxmov")
1845             (eq_attr "alternative" "6")
1846               (const_string "sselog1")
1847             (eq_attr "alternative" "7,8,9,10,11")
1848               (const_string "ssemov")
1849             (match_operand:DI 1 "pic_32bit_operand" "")
1850               (const_string "lea")
1851            ]
1852            (const_string "imov")))
1853    (set (attr "prefix")
1854      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1855        (const_string "orig")
1856        (const_string "maybe_vex")))
1857    (set (attr "prefix_data16")
1858      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1859        (const_string "1")
1860        (const_string "*")))
1861    (set (attr "mode")
1862      (cond [(eq_attr "alternative" "2,3")
1863               (const_string "DI")
1864             (eq_attr "alternative" "6,7")
1865               (if_then_else
1866                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1867                 (const_string "V4SF")
1868                 (const_string "TI"))
1869             (and (eq_attr "alternative" "8,9,10,11")
1870                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1871               (const_string "SF")
1872            ]
1873            (const_string "SI")))])
1874
1875 ;; Stores and loads of ax to arbitrary constant address.
1876 ;; We fake an second form of instruction to force reload to load address
1877 ;; into register when rax is not available
1878 (define_insn "*movabssi_1_rex64"
1879   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1880         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1881   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1882   "@
1883    movabs{l}\t{%1, %P0|%P0, %1}
1884    mov{l}\t{%1, %a0|%a0, %1}"
1885   [(set_attr "type" "imov")
1886    (set_attr "modrm" "0,*")
1887    (set_attr "length_address" "8,0")
1888    (set_attr "length_immediate" "0,*")
1889    (set_attr "memory" "store")
1890    (set_attr "mode" "SI")])
1891
1892 (define_insn "*movabssi_2_rex64"
1893   [(set (match_operand:SI 0 "register_operand" "=a,r")
1894         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1895   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1896   "@
1897    movabs{l}\t{%P1, %0|%0, %P1}
1898    mov{l}\t{%a1, %0|%0, %a1}"
1899   [(set_attr "type" "imov")
1900    (set_attr "modrm" "0,*")
1901    (set_attr "length_address" "8,0")
1902    (set_attr "length_immediate" "0")
1903    (set_attr "memory" "load")
1904    (set_attr "mode" "SI")])
1905
1906 (define_insn "*swapsi"
1907   [(set (match_operand:SI 0 "register_operand" "+r")
1908         (match_operand:SI 1 "register_operand" "+r"))
1909    (set (match_dup 1)
1910         (match_dup 0))]
1911   ""
1912   "xchg{l}\t%1, %0"
1913   [(set_attr "type" "imov")
1914    (set_attr "mode" "SI")
1915    (set_attr "pent_pair" "np")
1916    (set_attr "athlon_decode" "vector")
1917    (set_attr "amdfam10_decode" "double")])
1918
1919 (define_expand "movhi"
1920   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1921         (match_operand:HI 1 "general_operand" ""))]
1922   ""
1923   "ix86_expand_move (HImode, operands); DONE;")
1924
1925 (define_insn "*pushhi2"
1926   [(set (match_operand:HI 0 "push_operand" "=X")
1927         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1928   "!TARGET_64BIT"
1929   "push{l}\t%k1"
1930   [(set_attr "type" "push")
1931    (set_attr "mode" "SI")])
1932
1933 ;; For 64BIT abi we always round up to 8 bytes.
1934 (define_insn "*pushhi2_rex64"
1935   [(set (match_operand:HI 0 "push_operand" "=X")
1936         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1937   "TARGET_64BIT"
1938   "push{q}\t%q1"
1939   [(set_attr "type" "push")
1940    (set_attr "mode" "DI")])
1941
1942 (define_insn "*movhi_1"
1943   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1944         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1945   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 {
1947   switch (get_attr_type (insn))
1948     {
1949     case TYPE_IMOVX:
1950       /* movzwl is faster than movw on p2 due to partial word stalls,
1951          though not as fast as an aligned movl.  */
1952       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1953     default:
1954       if (get_attr_mode (insn) == MODE_SI)
1955         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1956       else
1957         return "mov{w}\t{%1, %0|%0, %1}";
1958     }
1959 }
1960   [(set (attr "type")
1961      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1962               (const_string "imov")
1963             (and (eq_attr "alternative" "0")
1964                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1965                           (const_int 0))
1966                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1967                           (const_int 0))))
1968               (const_string "imov")
1969             (and (eq_attr "alternative" "1,2")
1970                  (match_operand:HI 1 "aligned_operand" ""))
1971               (const_string "imov")
1972             (and (ne (symbol_ref "TARGET_MOVX")
1973                      (const_int 0))
1974                  (eq_attr "alternative" "0,2"))
1975               (const_string "imovx")
1976            ]
1977            (const_string "imov")))
1978     (set (attr "mode")
1979       (cond [(eq_attr "type" "imovx")
1980                (const_string "SI")
1981              (and (eq_attr "alternative" "1,2")
1982                   (match_operand:HI 1 "aligned_operand" ""))
1983                (const_string "SI")
1984              (and (eq_attr "alternative" "0")
1985                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1986                            (const_int 0))
1987                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1988                            (const_int 0))))
1989                (const_string "SI")
1990             ]
1991             (const_string "HI")))])
1992
1993 ;; Stores and loads of ax to arbitrary constant address.
1994 ;; We fake an second form of instruction to force reload to load address
1995 ;; into register when rax is not available
1996 (define_insn "*movabshi_1_rex64"
1997   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1998         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1999   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2000   "@
2001    movabs{w}\t{%1, %P0|%P0, %1}
2002    mov{w}\t{%1, %a0|%a0, %1}"
2003   [(set_attr "type" "imov")
2004    (set_attr "modrm" "0,*")
2005    (set_attr "length_address" "8,0")
2006    (set_attr "length_immediate" "0,*")
2007    (set_attr "memory" "store")
2008    (set_attr "mode" "HI")])
2009
2010 (define_insn "*movabshi_2_rex64"
2011   [(set (match_operand:HI 0 "register_operand" "=a,r")
2012         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2013   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2014   "@
2015    movabs{w}\t{%P1, %0|%0, %P1}
2016    mov{w}\t{%a1, %0|%0, %a1}"
2017   [(set_attr "type" "imov")
2018    (set_attr "modrm" "0,*")
2019    (set_attr "length_address" "8,0")
2020    (set_attr "length_immediate" "0")
2021    (set_attr "memory" "load")
2022    (set_attr "mode" "HI")])
2023
2024 (define_insn "*swaphi_1"
2025   [(set (match_operand:HI 0 "register_operand" "+r")
2026         (match_operand:HI 1 "register_operand" "+r"))
2027    (set (match_dup 1)
2028         (match_dup 0))]
2029   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2030   "xchg{l}\t%k1, %k0"
2031   [(set_attr "type" "imov")
2032    (set_attr "mode" "SI")
2033    (set_attr "pent_pair" "np")
2034    (set_attr "athlon_decode" "vector")
2035    (set_attr "amdfam10_decode" "double")])
2036
2037 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2038 (define_insn "*swaphi_2"
2039   [(set (match_operand:HI 0 "register_operand" "+r")
2040         (match_operand:HI 1 "register_operand" "+r"))
2041    (set (match_dup 1)
2042         (match_dup 0))]
2043   "TARGET_PARTIAL_REG_STALL"
2044   "xchg{w}\t%1, %0"
2045   [(set_attr "type" "imov")
2046    (set_attr "mode" "HI")
2047    (set_attr "pent_pair" "np")
2048    (set_attr "athlon_decode" "vector")])
2049
2050 (define_expand "movstricthi"
2051   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2052         (match_operand:HI 1 "general_operand" ""))]
2053   ""
2054 {
2055   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2056     FAIL;
2057   /* Don't generate memory->memory moves, go through a register */
2058   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2059     operands[1] = force_reg (HImode, operands[1]);
2060 })
2061
2062 (define_insn "*movstricthi_1"
2063   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2064         (match_operand:HI 1 "general_operand" "rn,m"))]
2065   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2066    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2067   "mov{w}\t{%1, %0|%0, %1}"
2068   [(set_attr "type" "imov")
2069    (set_attr "mode" "HI")])
2070
2071 (define_insn "*movstricthi_xor"
2072   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2073         (match_operand:HI 1 "const0_operand" ""))
2074    (clobber (reg:CC FLAGS_REG))]
2075   "reload_completed"
2076   "xor{w}\t%0, %0"
2077   [(set_attr "type" "alu1")
2078    (set_attr "mode" "HI")
2079    (set_attr "length_immediate" "0")])
2080
2081 (define_expand "movqi"
2082   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2083         (match_operand:QI 1 "general_operand" ""))]
2084   ""
2085   "ix86_expand_move (QImode, operands); DONE;")
2086
2087 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2088 ;; "push a byte".  But actually we use pushl, which has the effect
2089 ;; of rounding the amount pushed up to a word.
2090
2091 (define_insn "*pushqi2"
2092   [(set (match_operand:QI 0 "push_operand" "=X")
2093         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2094   "!TARGET_64BIT"
2095   "push{l}\t%k1"
2096   [(set_attr "type" "push")
2097    (set_attr "mode" "SI")])
2098
2099 ;; For 64BIT abi we always round up to 8 bytes.
2100 (define_insn "*pushqi2_rex64"
2101   [(set (match_operand:QI 0 "push_operand" "=X")
2102         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2103   "TARGET_64BIT"
2104   "push{q}\t%q1"
2105   [(set_attr "type" "push")
2106    (set_attr "mode" "DI")])
2107
2108 ;; Situation is quite tricky about when to choose full sized (SImode) move
2109 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2110 ;; partial register dependency machines (such as AMD Athlon), where QImode
2111 ;; moves issue extra dependency and for partial register stalls machines
2112 ;; that don't use QImode patterns (and QImode move cause stall on the next
2113 ;; instruction).
2114 ;;
2115 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2116 ;; register stall machines with, where we use QImode instructions, since
2117 ;; partial register stall can be caused there.  Then we use movzx.
2118 (define_insn "*movqi_1"
2119   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2120         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2121   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2122 {
2123   switch (get_attr_type (insn))
2124     {
2125     case TYPE_IMOVX:
2126       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2127       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2128     default:
2129       if (get_attr_mode (insn) == MODE_SI)
2130         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2131       else
2132         return "mov{b}\t{%1, %0|%0, %1}";
2133     }
2134 }
2135   [(set (attr "type")
2136      (cond [(and (eq_attr "alternative" "5")
2137                  (not (match_operand:QI 1 "aligned_operand" "")))
2138               (const_string "imovx")
2139             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2140               (const_string "imov")
2141             (and (eq_attr "alternative" "3")
2142                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2143                           (const_int 0))
2144                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2145                           (const_int 0))))
2146               (const_string "imov")
2147             (eq_attr "alternative" "3,5")
2148               (const_string "imovx")
2149             (and (ne (symbol_ref "TARGET_MOVX")
2150                      (const_int 0))
2151                  (eq_attr "alternative" "2"))
2152               (const_string "imovx")
2153            ]
2154            (const_string "imov")))
2155    (set (attr "mode")
2156       (cond [(eq_attr "alternative" "3,4,5")
2157                (const_string "SI")
2158              (eq_attr "alternative" "6")
2159                (const_string "QI")
2160              (eq_attr "type" "imovx")
2161                (const_string "SI")
2162              (and (eq_attr "type" "imov")
2163                   (and (eq_attr "alternative" "0,1")
2164                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2165                                 (const_int 0))
2166                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2167                                      (const_int 0))
2168                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2169                                      (const_int 0))))))
2170                (const_string "SI")
2171              ;; Avoid partial register stalls when not using QImode arithmetic
2172              (and (eq_attr "type" "imov")
2173                   (and (eq_attr "alternative" "0,1")
2174                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2175                                 (const_int 0))
2176                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2177                                 (const_int 0)))))
2178                (const_string "SI")
2179            ]
2180            (const_string "QI")))])
2181
2182 (define_insn "*swapqi_1"
2183   [(set (match_operand:QI 0 "register_operand" "+r")
2184         (match_operand:QI 1 "register_operand" "+r"))
2185    (set (match_dup 1)
2186         (match_dup 0))]
2187   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2188   "xchg{l}\t%k1, %k0"
2189   [(set_attr "type" "imov")
2190    (set_attr "mode" "SI")
2191    (set_attr "pent_pair" "np")
2192    (set_attr "athlon_decode" "vector")
2193    (set_attr "amdfam10_decode" "vector")])
2194
2195 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2196 (define_insn "*swapqi_2"
2197   [(set (match_operand:QI 0 "register_operand" "+q")
2198         (match_operand:QI 1 "register_operand" "+q"))
2199    (set (match_dup 1)
2200         (match_dup 0))]
2201   "TARGET_PARTIAL_REG_STALL"
2202   "xchg{b}\t%1, %0"
2203   [(set_attr "type" "imov")
2204    (set_attr "mode" "QI")
2205    (set_attr "pent_pair" "np")
2206    (set_attr "athlon_decode" "vector")])
2207
2208 (define_expand "movstrictqi"
2209   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2210         (match_operand:QI 1 "general_operand" ""))]
2211   ""
2212 {
2213   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2214     FAIL;
2215   /* Don't generate memory->memory moves, go through a register.  */
2216   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2217     operands[1] = force_reg (QImode, operands[1]);
2218 })
2219
2220 (define_insn "*movstrictqi_1"
2221   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2222         (match_operand:QI 1 "general_operand" "*qn,m"))]
2223   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2224    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2225   "mov{b}\t{%1, %0|%0, %1}"
2226   [(set_attr "type" "imov")
2227    (set_attr "mode" "QI")])
2228
2229 (define_insn "*movstrictqi_xor"
2230   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2231         (match_operand:QI 1 "const0_operand" ""))
2232    (clobber (reg:CC FLAGS_REG))]
2233   "reload_completed"
2234   "xor{b}\t%0, %0"
2235   [(set_attr "type" "alu1")
2236    (set_attr "mode" "QI")
2237    (set_attr "length_immediate" "0")])
2238
2239 (define_insn "*movsi_extv_1"
2240   [(set (match_operand:SI 0 "register_operand" "=R")
2241         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2242                          (const_int 8)
2243                          (const_int 8)))]
2244   ""
2245   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2246   [(set_attr "type" "imovx")
2247    (set_attr "mode" "SI")])
2248
2249 (define_insn "*movhi_extv_1"
2250   [(set (match_operand:HI 0 "register_operand" "=R")
2251         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2252                          (const_int 8)
2253                          (const_int 8)))]
2254   ""
2255   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2256   [(set_attr "type" "imovx")
2257    (set_attr "mode" "SI")])
2258
2259 (define_insn "*movqi_extv_1"
2260   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2261         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2262                          (const_int 8)
2263                          (const_int 8)))]
2264   "!TARGET_64BIT"
2265 {
2266   switch (get_attr_type (insn))
2267     {
2268     case TYPE_IMOVX:
2269       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2270     default:
2271       return "mov{b}\t{%h1, %0|%0, %h1}";
2272     }
2273 }
2274   [(set (attr "type")
2275      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2276                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2277                              (ne (symbol_ref "TARGET_MOVX")
2278                                  (const_int 0))))
2279         (const_string "imovx")
2280         (const_string "imov")))
2281    (set (attr "mode")
2282      (if_then_else (eq_attr "type" "imovx")
2283         (const_string "SI")
2284         (const_string "QI")))])
2285
2286 (define_insn "*movqi_extv_1_rex64"
2287   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2288         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2289                          (const_int 8)
2290                          (const_int 8)))]
2291   "TARGET_64BIT"
2292 {
2293   switch (get_attr_type (insn))
2294     {
2295     case TYPE_IMOVX:
2296       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2297     default:
2298       return "mov{b}\t{%h1, %0|%0, %h1}";
2299     }
2300 }
2301   [(set (attr "type")
2302      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2303                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2304                              (ne (symbol_ref "TARGET_MOVX")
2305                                  (const_int 0))))
2306         (const_string "imovx")
2307         (const_string "imov")))
2308    (set (attr "mode")
2309      (if_then_else (eq_attr "type" "imovx")
2310         (const_string "SI")
2311         (const_string "QI")))])
2312
2313 ;; Stores and loads of ax to arbitrary constant address.
2314 ;; We fake an second form of instruction to force reload to load address
2315 ;; into register when rax is not available
2316 (define_insn "*movabsqi_1_rex64"
2317   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2318         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2319   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2320   "@
2321    movabs{b}\t{%1, %P0|%P0, %1}
2322    mov{b}\t{%1, %a0|%a0, %1}"
2323   [(set_attr "type" "imov")
2324    (set_attr "modrm" "0,*")
2325    (set_attr "length_address" "8,0")
2326    (set_attr "length_immediate" "0,*")
2327    (set_attr "memory" "store")
2328    (set_attr "mode" "QI")])
2329
2330 (define_insn "*movabsqi_2_rex64"
2331   [(set (match_operand:QI 0 "register_operand" "=a,r")
2332         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2333   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2334   "@
2335    movabs{b}\t{%P1, %0|%0, %P1}
2336    mov{b}\t{%a1, %0|%0, %a1}"
2337   [(set_attr "type" "imov")
2338    (set_attr "modrm" "0,*")
2339    (set_attr "length_address" "8,0")
2340    (set_attr "length_immediate" "0")
2341    (set_attr "memory" "load")
2342    (set_attr "mode" "QI")])
2343
2344 (define_insn "*movdi_extzv_1"
2345   [(set (match_operand:DI 0 "register_operand" "=R")
2346         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2347                          (const_int 8)
2348                          (const_int 8)))]
2349   "TARGET_64BIT"
2350   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2351   [(set_attr "type" "imovx")
2352    (set_attr "mode" "SI")])
2353
2354 (define_insn "*movsi_extzv_1"
2355   [(set (match_operand:SI 0 "register_operand" "=R")
2356         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2357                          (const_int 8)
2358                          (const_int 8)))]
2359   ""
2360   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2361   [(set_attr "type" "imovx")
2362    (set_attr "mode" "SI")])
2363
2364 (define_insn "*movqi_extzv_2"
2365   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2366         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2367                                     (const_int 8)
2368                                     (const_int 8)) 0))]
2369   "!TARGET_64BIT"
2370 {
2371   switch (get_attr_type (insn))
2372     {
2373     case TYPE_IMOVX:
2374       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2375     default:
2376       return "mov{b}\t{%h1, %0|%0, %h1}";
2377     }
2378 }
2379   [(set (attr "type")
2380      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2381                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2382                              (ne (symbol_ref "TARGET_MOVX")
2383                                  (const_int 0))))
2384         (const_string "imovx")
2385         (const_string "imov")))
2386    (set (attr "mode")
2387      (if_then_else (eq_attr "type" "imovx")
2388         (const_string "SI")
2389         (const_string "QI")))])
2390
2391 (define_insn "*movqi_extzv_2_rex64"
2392   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2393         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2394                                     (const_int 8)
2395                                     (const_int 8)) 0))]
2396   "TARGET_64BIT"
2397 {
2398   switch (get_attr_type (insn))
2399     {
2400     case TYPE_IMOVX:
2401       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2402     default:
2403       return "mov{b}\t{%h1, %0|%0, %h1}";
2404     }
2405 }
2406   [(set (attr "type")
2407      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2408                         (ne (symbol_ref "TARGET_MOVX")
2409                             (const_int 0)))
2410         (const_string "imovx")
2411         (const_string "imov")))
2412    (set (attr "mode")
2413      (if_then_else (eq_attr "type" "imovx")
2414         (const_string "SI")
2415         (const_string "QI")))])
2416
2417 (define_insn "movsi_insv_1"
2418   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2419                          (const_int 8)
2420                          (const_int 8))
2421         (match_operand:SI 1 "general_operand" "Qmn"))]
2422   "!TARGET_64BIT"
2423   "mov{b}\t{%b1, %h0|%h0, %b1}"
2424   [(set_attr "type" "imov")
2425    (set_attr "mode" "QI")])
2426
2427 (define_insn "*movsi_insv_1_rex64"
2428   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2429                          (const_int 8)
2430                          (const_int 8))
2431         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2432   "TARGET_64BIT"
2433   "mov{b}\t{%b1, %h0|%h0, %b1}"
2434   [(set_attr "type" "imov")
2435    (set_attr "mode" "QI")])
2436
2437 (define_insn "movdi_insv_1_rex64"
2438   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2439                          (const_int 8)
2440                          (const_int 8))
2441         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2442   "TARGET_64BIT"
2443   "mov{b}\t{%b1, %h0|%h0, %b1}"
2444   [(set_attr "type" "imov")
2445    (set_attr "mode" "QI")])
2446
2447 (define_insn "*movqi_insv_2"
2448   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2449                          (const_int 8)
2450                          (const_int 8))
2451         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2452                      (const_int 8)))]
2453   ""
2454   "mov{b}\t{%h1, %h0|%h0, %h1}"
2455   [(set_attr "type" "imov")
2456    (set_attr "mode" "QI")])
2457
2458 (define_expand "movdi"
2459   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2460         (match_operand:DI 1 "general_operand" ""))]
2461   ""
2462   "ix86_expand_move (DImode, operands); DONE;")
2463
2464 (define_insn "*pushdi"
2465   [(set (match_operand:DI 0 "push_operand" "=<")
2466         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2467   "!TARGET_64BIT"
2468   "#")
2469
2470 (define_insn "*pushdi2_rex64"
2471   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2472         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2473   "TARGET_64BIT"
2474   "@
2475    push{q}\t%1
2476    #"
2477   [(set_attr "type" "push,multi")
2478    (set_attr "mode" "DI")])
2479
2480 ;; Convert impossible pushes of immediate to existing instructions.
2481 ;; First try to get scratch register and go through it.  In case this
2482 ;; fails, push sign extended lower part first and then overwrite
2483 ;; upper part by 32bit move.
2484 (define_peephole2
2485   [(match_scratch:DI 2 "r")
2486    (set (match_operand:DI 0 "push_operand" "")
2487         (match_operand:DI 1 "immediate_operand" ""))]
2488   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2489    && !x86_64_immediate_operand (operands[1], DImode)"
2490   [(set (match_dup 2) (match_dup 1))
2491    (set (match_dup 0) (match_dup 2))]
2492   "")
2493
2494 ;; We need to define this as both peepholer and splitter for case
2495 ;; peephole2 pass is not run.
2496 ;; "&& 1" is needed to keep it from matching the previous pattern.
2497 (define_peephole2
2498   [(set (match_operand:DI 0 "push_operand" "")
2499         (match_operand:DI 1 "immediate_operand" ""))]
2500   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2501    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2502   [(set (match_dup 0) (match_dup 1))
2503    (set (match_dup 2) (match_dup 3))]
2504   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2505    operands[1] = gen_lowpart (DImode, operands[2]);
2506    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2507                                                     GEN_INT (4)));
2508   ")
2509
2510 (define_split
2511   [(set (match_operand:DI 0 "push_operand" "")
2512         (match_operand:DI 1 "immediate_operand" ""))]
2513   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2514                     ? epilogue_completed : reload_completed)
2515    && !symbolic_operand (operands[1], DImode)
2516    && !x86_64_immediate_operand (operands[1], DImode)"
2517   [(set (match_dup 0) (match_dup 1))
2518    (set (match_dup 2) (match_dup 3))]
2519   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2520    operands[1] = gen_lowpart (DImode, operands[2]);
2521    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2522                                                     GEN_INT (4)));
2523   ")
2524
2525 (define_insn "*pushdi2_prologue_rex64"
2526   [(set (match_operand:DI 0 "push_operand" "=<")
2527         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2528    (clobber (mem:BLK (scratch)))]
2529   "TARGET_64BIT"
2530   "push{q}\t%1"
2531   [(set_attr "type" "push")
2532    (set_attr "mode" "DI")])
2533
2534 (define_insn "*popdi1_epilogue_rex64"
2535   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2536         (mem:DI (reg:DI SP_REG)))
2537    (set (reg:DI SP_REG)
2538         (plus:DI (reg:DI SP_REG) (const_int 8)))
2539    (clobber (mem:BLK (scratch)))]
2540   "TARGET_64BIT"
2541   "pop{q}\t%0"
2542   [(set_attr "type" "pop")
2543    (set_attr "mode" "DI")])
2544
2545 (define_insn "popdi1"
2546   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2547         (mem:DI (reg:DI SP_REG)))
2548    (set (reg:DI SP_REG)
2549         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2550   "TARGET_64BIT"
2551   "pop{q}\t%0"
2552   [(set_attr "type" "pop")
2553    (set_attr "mode" "DI")])
2554
2555 (define_insn "*movdi_xor_rex64"
2556   [(set (match_operand:DI 0 "register_operand" "=r")
2557         (match_operand:DI 1 "const0_operand" ""))
2558    (clobber (reg:CC FLAGS_REG))]
2559   "TARGET_64BIT
2560    && reload_completed"
2561   "xor{l}\t%k0, %k0";
2562   [(set_attr "type" "alu1")
2563    (set_attr "mode" "SI")
2564    (set_attr "length_immediate" "0")])
2565
2566 (define_insn "*movdi_or_rex64"
2567   [(set (match_operand:DI 0 "register_operand" "=r")
2568         (match_operand:DI 1 "const_int_operand" "i"))
2569    (clobber (reg:CC FLAGS_REG))]
2570   "TARGET_64BIT
2571    && reload_completed
2572    && operands[1] == constm1_rtx"
2573 {
2574   operands[1] = constm1_rtx;
2575   return "or{q}\t{%1, %0|%0, %1}";
2576 }
2577   [(set_attr "type" "alu1")
2578    (set_attr "mode" "DI")
2579    (set_attr "length_immediate" "1")])
2580
2581 (define_insn "*movdi_2"
2582   [(set (match_operand:DI 0 "nonimmediate_operand"
2583                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2584         (match_operand:DI 1 "general_operand"
2585                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2586   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2587   "@
2588    #
2589    #
2590    pxor\t%0, %0
2591    movq\t{%1, %0|%0, %1}
2592    movq\t{%1, %0|%0, %1}
2593    %vpxor\t%0, %d0
2594    %vmovq\t{%1, %0|%0, %1}
2595    %vmovdqa\t{%1, %0|%0, %1}
2596    %vmovq\t{%1, %0|%0, %1}
2597    xorps\t%0, %0
2598    movlps\t{%1, %0|%0, %1}
2599    movaps\t{%1, %0|%0, %1}
2600    movlps\t{%1, %0|%0, %1}"
2601   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2602    (set (attr "prefix")
2603      (if_then_else (eq_attr "alternative" "5,6,7,8")
2604        (const_string "vex")
2605        (const_string "orig")))
2606    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2607
2608 (define_split
2609   [(set (match_operand:DI 0 "push_operand" "")
2610         (match_operand:DI 1 "general_operand" ""))]
2611   "!TARGET_64BIT && reload_completed
2612    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2613   [(const_int 0)]
2614   "ix86_split_long_move (operands); DONE;")
2615
2616 ;; %%% This multiword shite has got to go.
2617 (define_split
2618   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2619         (match_operand:DI 1 "general_operand" ""))]
2620   "!TARGET_64BIT && reload_completed
2621    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2622    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2623   [(const_int 0)]
2624   "ix86_split_long_move (operands); DONE;")
2625
2626 (define_insn "*movdi_1_rex64"
2627   [(set (match_operand:DI 0 "nonimmediate_operand"
2628           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2629         (match_operand:DI 1 "general_operand"
2630           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2631   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2632 {
2633   switch (get_attr_type (insn))
2634     {
2635     case TYPE_SSECVT:
2636       if (SSE_REG_P (operands[0]))
2637         return "movq2dq\t{%1, %0|%0, %1}";
2638       else
2639         return "movdq2q\t{%1, %0|%0, %1}";
2640
2641     case TYPE_SSEMOV:
2642       if (TARGET_AVX)
2643         {
2644           if (get_attr_mode (insn) == MODE_TI)
2645             return "vmovdqa\t{%1, %0|%0, %1}";
2646           else
2647             return "vmovq\t{%1, %0|%0, %1}";
2648         }
2649
2650       if (get_attr_mode (insn) == MODE_TI)
2651         return "movdqa\t{%1, %0|%0, %1}";
2652       /* FALLTHRU */
2653
2654     case TYPE_MMXMOV:
2655       /* Moves from and into integer register is done using movd
2656          opcode with REX prefix.  */
2657       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2658         return "movd\t{%1, %0|%0, %1}";
2659       return "movq\t{%1, %0|%0, %1}";
2660
2661     case TYPE_SSELOG1:
2662       return "%vpxor\t%0, %d0";
2663
2664     case TYPE_MMX:
2665       return "pxor\t%0, %0";
2666
2667     case TYPE_MULTI:
2668       return "#";
2669
2670     case TYPE_LEA:
2671       return "lea{q}\t{%a1, %0|%0, %a1}";
2672
2673     default:
2674       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2675       if (get_attr_mode (insn) == MODE_SI)
2676         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2677       else if (which_alternative == 2)
2678         return "movabs{q}\t{%1, %0|%0, %1}";
2679       else
2680         return "mov{q}\t{%1, %0|%0, %1}";
2681     }
2682 }
2683   [(set (attr "type")
2684      (cond [(eq_attr "alternative" "5")
2685               (const_string "mmx")
2686             (eq_attr "alternative" "6,7,8,9,10")
2687               (const_string "mmxmov")
2688             (eq_attr "alternative" "11")
2689               (const_string "sselog1")
2690             (eq_attr "alternative" "12,13,14,15,16")
2691               (const_string "ssemov")
2692             (eq_attr "alternative" "17,18")
2693               (const_string "ssecvt")
2694             (eq_attr "alternative" "4")
2695               (const_string "multi")
2696             (match_operand:DI 1 "pic_32bit_operand" "")
2697               (const_string "lea")
2698            ]
2699            (const_string "imov")))
2700    (set (attr "modrm")
2701      (if_then_else
2702        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2703          (const_string "0")
2704          (const_string "*")))
2705    (set (attr "length_immediate")
2706      (if_then_else
2707        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2708          (const_string "8")
2709          (const_string "*")))
2710    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2711    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2712    (set (attr "prefix")
2713      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2714        (const_string "maybe_vex")
2715        (const_string "orig")))
2716    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2717
2718 ;; Stores and loads of ax to arbitrary constant address.
2719 ;; We fake an second form of instruction to force reload to load address
2720 ;; into register when rax is not available
2721 (define_insn "*movabsdi_1_rex64"
2722   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2723         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2724   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2725   "@
2726    movabs{q}\t{%1, %P0|%P0, %1}
2727    mov{q}\t{%1, %a0|%a0, %1}"
2728   [(set_attr "type" "imov")
2729    (set_attr "modrm" "0,*")
2730    (set_attr "length_address" "8,0")
2731    (set_attr "length_immediate" "0,*")
2732    (set_attr "memory" "store")
2733    (set_attr "mode" "DI")])
2734
2735 (define_insn "*movabsdi_2_rex64"
2736   [(set (match_operand:DI 0 "register_operand" "=a,r")
2737         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2738   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2739   "@
2740    movabs{q}\t{%P1, %0|%0, %P1}
2741    mov{q}\t{%a1, %0|%0, %a1}"
2742   [(set_attr "type" "imov")
2743    (set_attr "modrm" "0,*")
2744    (set_attr "length_address" "8,0")
2745    (set_attr "length_immediate" "0")
2746    (set_attr "memory" "load")
2747    (set_attr "mode" "DI")])
2748
2749 ;; Convert impossible stores of immediate to existing instructions.
2750 ;; First try to get scratch register and go through it.  In case this
2751 ;; fails, move by 32bit parts.
2752 (define_peephole2
2753   [(match_scratch:DI 2 "r")
2754    (set (match_operand:DI 0 "memory_operand" "")
2755         (match_operand:DI 1 "immediate_operand" ""))]
2756   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2757    && !x86_64_immediate_operand (operands[1], DImode)"
2758   [(set (match_dup 2) (match_dup 1))
2759    (set (match_dup 0) (match_dup 2))]
2760   "")
2761
2762 ;; We need to define this as both peepholer and splitter for case
2763 ;; peephole2 pass is not run.
2764 ;; "&& 1" is needed to keep it from matching the previous pattern.
2765 (define_peephole2
2766   [(set (match_operand:DI 0 "memory_operand" "")
2767         (match_operand:DI 1 "immediate_operand" ""))]
2768   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2769    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2770   [(set (match_dup 2) (match_dup 3))
2771    (set (match_dup 4) (match_dup 5))]
2772   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2773
2774 (define_split
2775   [(set (match_operand:DI 0 "memory_operand" "")
2776         (match_operand:DI 1 "immediate_operand" ""))]
2777   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2778                     ? epilogue_completed : reload_completed)
2779    && !symbolic_operand (operands[1], DImode)
2780    && !x86_64_immediate_operand (operands[1], DImode)"
2781   [(set (match_dup 2) (match_dup 3))
2782    (set (match_dup 4) (match_dup 5))]
2783   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2784
2785 (define_insn "*swapdi_rex64"
2786   [(set (match_operand:DI 0 "register_operand" "+r")
2787         (match_operand:DI 1 "register_operand" "+r"))
2788    (set (match_dup 1)
2789         (match_dup 0))]
2790   "TARGET_64BIT"
2791   "xchg{q}\t%1, %0"
2792   [(set_attr "type" "imov")
2793    (set_attr "mode" "DI")
2794    (set_attr "pent_pair" "np")
2795    (set_attr "athlon_decode" "vector")
2796    (set_attr "amdfam10_decode" "double")])
2797
2798 (define_expand "movoi"
2799   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2800         (match_operand:OI 1 "general_operand" ""))]
2801   "TARGET_AVX"
2802   "ix86_expand_move (OImode, operands); DONE;")
2803
2804 (define_insn "*movoi_internal"
2805   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2806         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2807   "TARGET_AVX
2808    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2809 {
2810   switch (which_alternative)
2811     {
2812     case 0:
2813       return "vxorps\t%0, %0, %0";
2814     case 1:
2815     case 2:
2816       if (misaligned_operand (operands[0], OImode)
2817           || misaligned_operand (operands[1], OImode))
2818         return "vmovdqu\t{%1, %0|%0, %1}";
2819       else
2820         return "vmovdqa\t{%1, %0|%0, %1}";
2821     default:
2822       gcc_unreachable ();
2823     }
2824 }
2825   [(set_attr "type" "sselog1,ssemov,ssemov")
2826    (set_attr "prefix" "vex")
2827    (set_attr "mode" "OI")])
2828
2829 (define_expand "movti"
2830   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2831         (match_operand:TI 1 "nonimmediate_operand" ""))]
2832   "TARGET_SSE || TARGET_64BIT"
2833 {
2834   if (TARGET_64BIT)
2835     ix86_expand_move (TImode, operands);
2836   else if (push_operand (operands[0], TImode))
2837     ix86_expand_push (TImode, operands[1]);
2838   else
2839     ix86_expand_vector_move (TImode, operands);
2840   DONE;
2841 })
2842
2843 (define_insn "*movti_internal"
2844   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2845         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2846   "TARGET_SSE && !TARGET_64BIT
2847    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2848 {
2849   switch (which_alternative)
2850     {
2851     case 0:
2852       if (get_attr_mode (insn) == MODE_V4SF)
2853         return "%vxorps\t%0, %d0";
2854       else
2855         return "%vpxor\t%0, %d0";
2856     case 1:
2857     case 2:
2858       /* TDmode values are passed as TImode on the stack.  Moving them
2859          to stack may result in unaligned memory access.  */
2860       if (misaligned_operand (operands[0], TImode)
2861           || misaligned_operand (operands[1], TImode))
2862         {
2863           if (get_attr_mode (insn) == MODE_V4SF)
2864             return "%vmovups\t{%1, %0|%0, %1}";
2865          else
2866            return "%vmovdqu\t{%1, %0|%0, %1}";
2867         }
2868       else
2869         {
2870           if (get_attr_mode (insn) == MODE_V4SF)
2871             return "%vmovaps\t{%1, %0|%0, %1}";
2872          else
2873            return "%vmovdqa\t{%1, %0|%0, %1}";
2874         }
2875     default:
2876       gcc_unreachable ();
2877     }
2878 }
2879   [(set_attr "type" "sselog1,ssemov,ssemov")
2880    (set_attr "prefix" "maybe_vex")
2881    (set (attr "mode")
2882         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2883                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2884                  (const_string "V4SF")
2885                (and (eq_attr "alternative" "2")
2886                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2887                         (const_int 0)))
2888                  (const_string "V4SF")]
2889               (const_string "TI")))])
2890
2891 (define_insn "*movti_rex64"
2892   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2893         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2894   "TARGET_64BIT
2895    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2896 {
2897   switch (which_alternative)
2898     {
2899     case 0:
2900     case 1:
2901       return "#";
2902     case 2:
2903       if (get_attr_mode (insn) == MODE_V4SF)
2904         return "%vxorps\t%0, %d0";
2905       else
2906         return "%vpxor\t%0, %d0";
2907     case 3:
2908     case 4:
2909       /* TDmode values are passed as TImode on the stack.  Moving them
2910          to stack may result in unaligned memory access.  */
2911       if (misaligned_operand (operands[0], TImode)
2912           || misaligned_operand (operands[1], TImode))
2913         {
2914           if (get_attr_mode (insn) == MODE_V4SF)
2915             return "%vmovups\t{%1, %0|%0, %1}";
2916          else
2917            return "%vmovdqu\t{%1, %0|%0, %1}";
2918         }
2919       else
2920         {
2921           if (get_attr_mode (insn) == MODE_V4SF)
2922             return "%vmovaps\t{%1, %0|%0, %1}";
2923          else
2924            return "%vmovdqa\t{%1, %0|%0, %1}";
2925         }
2926     default:
2927       gcc_unreachable ();
2928     }
2929 }
2930   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2931    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2932    (set (attr "mode")
2933         (cond [(eq_attr "alternative" "2,3")
2934                  (if_then_else
2935                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2936                        (const_int 0))
2937                    (const_string "V4SF")
2938                    (const_string "TI"))
2939                (eq_attr "alternative" "4")
2940                  (if_then_else
2941                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2942                             (const_int 0))
2943                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2944                             (const_int 0)))
2945                    (const_string "V4SF")
2946                    (const_string "TI"))]
2947                (const_string "DI")))])
2948
2949 (define_split
2950   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2951         (match_operand:TI 1 "general_operand" ""))]
2952   "reload_completed && !SSE_REG_P (operands[0])
2953    && !SSE_REG_P (operands[1])"
2954   [(const_int 0)]
2955   "ix86_split_long_move (operands); DONE;")
2956
2957 ;; This expands to what emit_move_complex would generate if we didn't
2958 ;; have a movti pattern.  Having this avoids problems with reload on
2959 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2960 ;; to have around all the time.
2961 (define_expand "movcdi"
2962   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2963         (match_operand:CDI 1 "general_operand" ""))]
2964   ""
2965 {
2966   if (push_operand (operands[0], CDImode))
2967     emit_move_complex_push (CDImode, operands[0], operands[1]);
2968   else
2969     emit_move_complex_parts (operands[0], operands[1]);
2970   DONE;
2971 })
2972
2973 (define_expand "movsf"
2974   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2975         (match_operand:SF 1 "general_operand" ""))]
2976   ""
2977   "ix86_expand_move (SFmode, operands); DONE;")
2978
2979 (define_insn "*pushsf"
2980   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2981         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2982   "!TARGET_64BIT"
2983 {
2984   /* Anything else should be already split before reg-stack.  */
2985   gcc_assert (which_alternative == 1);
2986   return "push{l}\t%1";
2987 }
2988   [(set_attr "type" "multi,push,multi")
2989    (set_attr "unit" "i387,*,*")
2990    (set_attr "mode" "SF,SI,SF")])
2991
2992 (define_insn "*pushsf_rex64"
2993   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2994         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2995   "TARGET_64BIT"
2996 {
2997   /* Anything else should be already split before reg-stack.  */
2998   gcc_assert (which_alternative == 1);
2999   return "push{q}\t%q1";
3000 }
3001   [(set_attr "type" "multi,push,multi")
3002    (set_attr "unit" "i387,*,*")
3003    (set_attr "mode" "SF,DI,SF")])
3004
3005 (define_split
3006   [(set (match_operand:SF 0 "push_operand" "")
3007         (match_operand:SF 1 "memory_operand" ""))]
3008   "reload_completed
3009    && MEM_P (operands[1])
3010    && (operands[2] = find_constant_src (insn))"
3011   [(set (match_dup 0)
3012         (match_dup 2))])
3013
3014
3015 ;; %%% Kill this when call knows how to work this out.
3016 (define_split
3017   [(set (match_operand:SF 0 "push_operand" "")
3018         (match_operand:SF 1 "any_fp_register_operand" ""))]
3019   "!TARGET_64BIT"
3020   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3021    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3022
3023 (define_split
3024   [(set (match_operand:SF 0 "push_operand" "")
3025         (match_operand:SF 1 "any_fp_register_operand" ""))]
3026   "TARGET_64BIT"
3027   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3028    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3029
3030 (define_insn "*movsf_1"
3031   [(set (match_operand:SF 0 "nonimmediate_operand"
3032           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3033         (match_operand:SF 1 "general_operand"
3034           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3035   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3036    && (reload_in_progress || reload_completed
3037        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3038        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3039            && standard_80387_constant_p (operands[1]))
3040        || GET_CODE (operands[1]) != CONST_DOUBLE
3041        || memory_operand (operands[0], SFmode))"
3042 {
3043   switch (which_alternative)
3044     {
3045     case 0:
3046     case 1:
3047       return output_387_reg_move (insn, operands);
3048
3049     case 2:
3050       return standard_80387_constant_opcode (operands[1]);
3051
3052     case 3:
3053     case 4:
3054       return "mov{l}\t{%1, %0|%0, %1}";
3055     case 5:
3056       if (get_attr_mode (insn) == MODE_TI)
3057         return "%vpxor\t%0, %d0";
3058       else
3059         return "%vxorps\t%0, %d0";
3060     case 6:
3061       if (get_attr_mode (insn) == MODE_V4SF)
3062         return "%vmovaps\t{%1, %0|%0, %1}";
3063       else
3064         return "%vmovss\t{%1, %d0|%d0, %1}";
3065     case 7:
3066       if (TARGET_AVX)
3067         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3068                                    : "vmovss\t{%1, %0|%0, %1}";
3069       else
3070         return "movss\t{%1, %0|%0, %1}";
3071     case 8:
3072       return "%vmovss\t{%1, %0|%0, %1}";
3073
3074     case 9: case 10: case 14: case 15:
3075       return "movd\t{%1, %0|%0, %1}";
3076     case 12: case 13:
3077       return "%vmovd\t{%1, %0|%0, %1}";
3078
3079     case 11:
3080       return "movq\t{%1, %0|%0, %1}";
3081
3082     default:
3083       gcc_unreachable ();
3084     }
3085 }
3086   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3087    (set (attr "prefix")
3088      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3089        (const_string "maybe_vex")
3090        (const_string "orig")))
3091    (set (attr "mode")
3092         (cond [(eq_attr "alternative" "3,4,9,10")
3093                  (const_string "SI")
3094                (eq_attr "alternative" "5")
3095                  (if_then_else
3096                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3097                                  (const_int 0))
3098                              (ne (symbol_ref "TARGET_SSE2")
3099                                  (const_int 0)))
3100                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3101                             (const_int 0)))
3102                    (const_string "TI")
3103                    (const_string "V4SF"))
3104                /* For architectures resolving dependencies on
3105                   whole SSE registers use APS move to break dependency
3106                   chains, otherwise use short move to avoid extra work.
3107
3108                   Do the same for architectures resolving dependencies on
3109                   the parts.  While in DF mode it is better to always handle
3110                   just register parts, the SF mode is different due to lack
3111                   of instructions to load just part of the register.  It is
3112                   better to maintain the whole registers in single format
3113                   to avoid problems on using packed logical operations.  */
3114                (eq_attr "alternative" "6")
3115                  (if_then_else
3116                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3117                             (const_int 0))
3118                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3119                             (const_int 0)))
3120                    (const_string "V4SF")
3121                    (const_string "SF"))
3122                (eq_attr "alternative" "11")
3123                  (const_string "DI")]
3124                (const_string "SF")))])
3125
3126 (define_insn "*swapsf"
3127   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3128         (match_operand:SF 1 "fp_register_operand" "+f"))
3129    (set (match_dup 1)
3130         (match_dup 0))]
3131   "reload_completed || TARGET_80387"
3132 {
3133   if (STACK_TOP_P (operands[0]))
3134     return "fxch\t%1";
3135   else
3136     return "fxch\t%0";
3137 }
3138   [(set_attr "type" "fxch")
3139    (set_attr "mode" "SF")])
3140
3141 (define_expand "movdf"
3142   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3143         (match_operand:DF 1 "general_operand" ""))]
3144   ""
3145   "ix86_expand_move (DFmode, operands); DONE;")
3146
3147 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3148 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3149 ;; On the average, pushdf using integers can be still shorter.  Allow this
3150 ;; pattern for optimize_size too.
3151
3152 (define_insn "*pushdf_nointeger"
3153   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3154         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3155   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3156 {
3157   /* This insn should be already split before reg-stack.  */
3158   gcc_unreachable ();
3159 }
3160   [(set_attr "type" "multi")
3161    (set_attr "unit" "i387,*,*,*")
3162    (set_attr "mode" "DF,SI,SI,DF")])
3163
3164 (define_insn "*pushdf_integer"
3165   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3166         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3167   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3168 {
3169   /* This insn should be already split before reg-stack.  */
3170   gcc_unreachable ();
3171 }
3172   [(set_attr "type" "multi")
3173    (set_attr "unit" "i387,*,*")
3174    (set_attr "mode" "DF,SI,DF")])
3175
3176 ;; %%% Kill this when call knows how to work this out.
3177 (define_split
3178   [(set (match_operand:DF 0 "push_operand" "")
3179         (match_operand:DF 1 "any_fp_register_operand" ""))]
3180   "reload_completed"
3181   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3182    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3183   "")
3184
3185 (define_split
3186   [(set (match_operand:DF 0 "push_operand" "")
3187         (match_operand:DF 1 "general_operand" ""))]
3188   "reload_completed"
3189   [(const_int 0)]
3190   "ix86_split_long_move (operands); DONE;")
3191
3192 ;; Moving is usually shorter when only FP registers are used. This separate
3193 ;; movdf pattern avoids the use of integer registers for FP operations
3194 ;; when optimizing for size.
3195
3196 (define_insn "*movdf_nointeger"
3197   [(set (match_operand:DF 0 "nonimmediate_operand"
3198                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3199         (match_operand:DF 1 "general_operand"
3200                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3201   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3202    && ((optimize_function_for_size_p (cfun)
3203        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3204    && (reload_in_progress || reload_completed
3205        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3206        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3207            && optimize_function_for_size_p (cfun)
3208            && !memory_operand (operands[0], DFmode)
3209            && standard_80387_constant_p (operands[1]))
3210        || GET_CODE (operands[1]) != CONST_DOUBLE
3211        || ((optimize_function_for_size_p (cfun)
3212             || !TARGET_MEMORY_MISMATCH_STALL
3213             || reload_in_progress || reload_completed)
3214            && memory_operand (operands[0], DFmode)))"
3215 {
3216   switch (which_alternative)
3217     {
3218     case 0:
3219     case 1:
3220       return output_387_reg_move (insn, operands);
3221
3222     case 2:
3223       return standard_80387_constant_opcode (operands[1]);
3224
3225     case 3:
3226     case 4:
3227       return "#";
3228     case 5:
3229       switch (get_attr_mode (insn))
3230         {
3231         case MODE_V4SF:
3232           return "%vxorps\t%0, %d0";
3233         case MODE_V2DF:
3234           return "%vxorpd\t%0, %d0";
3235         case MODE_TI:
3236           return "%vpxor\t%0, %d0";
3237         default:
3238           gcc_unreachable ();
3239         }
3240     case 6:
3241     case 7:
3242     case 8:
3243       switch (get_attr_mode (insn))
3244         {
3245         case MODE_V4SF:
3246           return "%vmovaps\t{%1, %0|%0, %1}";
3247         case MODE_V2DF:
3248           return "%vmovapd\t{%1, %0|%0, %1}";
3249         case MODE_TI:
3250           return "%vmovdqa\t{%1, %0|%0, %1}";
3251         case MODE_DI:
3252           return "%vmovq\t{%1, %0|%0, %1}";
3253         case MODE_DF:
3254           if (TARGET_AVX)
3255             {
3256               if (REG_P (operands[0]) && REG_P (operands[1]))
3257                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3258               else
3259                 return "vmovsd\t{%1, %0|%0, %1}";
3260             }
3261           else
3262             return "movsd\t{%1, %0|%0, %1}";
3263         case MODE_V1DF:
3264           if (TARGET_AVX)
3265             {
3266               if (REG_P (operands[0]))
3267                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3268               else
3269                 return "vmovlpd\t{%1, %0|%0, %1}";
3270             }
3271           else
3272             return "movlpd\t{%1, %0|%0, %1}";
3273         case MODE_V2SF:
3274           if (TARGET_AVX)
3275             {
3276               if (REG_P (operands[0]))
3277                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3278               else
3279                 return "vmovlps\t{%1, %0|%0, %1}";
3280             }
3281           else
3282             return "movlps\t{%1, %0|%0, %1}";
3283         default:
3284           gcc_unreachable ();
3285         }
3286
3287     default:
3288       gcc_unreachable ();
3289     }
3290 }
3291   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3292    (set (attr "prefix")
3293      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3294        (const_string "orig")
3295        (const_string "maybe_vex")))
3296    (set (attr "prefix_data16")
3297      (if_then_else (eq_attr "mode" "V1DF")
3298        (const_string "1")
3299        (const_string "*")))
3300    (set (attr "mode")
3301         (cond [(eq_attr "alternative" "0,1,2")
3302                  (const_string "DF")
3303                (eq_attr "alternative" "3,4")
3304                  (const_string "SI")
3305
3306                /* For SSE1, we have many fewer alternatives.  */
3307                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3308                  (cond [(eq_attr "alternative" "5,6")
3309                           (const_string "V4SF")
3310                        ]
3311                    (const_string "V2SF"))
3312
3313                /* xorps is one byte shorter.  */
3314                (eq_attr "alternative" "5")
3315                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3316                             (const_int 0))
3317                           (const_string "V4SF")
3318                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3319                             (const_int 0))
3320                           (const_string "TI")
3321                        ]
3322                        (const_string "V2DF"))
3323
3324                /* For architectures resolving dependencies on
3325                   whole SSE registers use APD move to break dependency
3326                   chains, otherwise use short move to avoid extra work.
3327
3328                   movaps encodes one byte shorter.  */
3329                (eq_attr "alternative" "6")
3330                  (cond
3331                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3332                         (const_int 0))
3333                       (const_string "V4SF")
3334                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3335                         (const_int 0))
3336                       (const_string "V2DF")
3337                    ]
3338                    (const_string "DF"))
3339                /* For architectures resolving dependencies on register
3340                   parts we may avoid extra work to zero out upper part
3341                   of register.  */
3342                (eq_attr "alternative" "7")
3343                  (if_then_else
3344                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3345                        (const_int 0))
3346                    (const_string "V1DF")
3347                    (const_string "DF"))
3348               ]
3349               (const_string "DF")))])
3350
3351 (define_insn "*movdf_integer_rex64"
3352   [(set (match_operand:DF 0 "nonimmediate_operand"
3353                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3354         (match_operand:DF 1 "general_operand"
3355                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3356   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3357    && (reload_in_progress || reload_completed
3358        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3359        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3360            && optimize_function_for_size_p (cfun)
3361            && standard_80387_constant_p (operands[1]))
3362        || GET_CODE (operands[1]) != CONST_DOUBLE
3363        || memory_operand (operands[0], DFmode))"
3364 {
3365   switch (which_alternative)
3366     {
3367     case 0:
3368     case 1:
3369       return output_387_reg_move (insn, operands);
3370
3371     case 2:
3372       return standard_80387_constant_opcode (operands[1]);
3373
3374     case 3:
3375     case 4:
3376       return "#";
3377
3378     case 5:
3379       switch (get_attr_mode (insn))
3380         {
3381         case MODE_V4SF:
3382           return "%vxorps\t%0, %d0";
3383         case MODE_V2DF:
3384           return "%vxorpd\t%0, %d0";
3385         case MODE_TI:
3386           return "%vpxor\t%0, %d0";
3387         default:
3388           gcc_unreachable ();
3389         }
3390     case 6:
3391     case 7:
3392     case 8:
3393       switch (get_attr_mode (insn))
3394         {
3395         case MODE_V4SF:
3396           return "%vmovaps\t{%1, %0|%0, %1}";
3397         case MODE_V2DF:
3398           return "%vmovapd\t{%1, %0|%0, %1}";
3399         case MODE_TI:
3400           return "%vmovdqa\t{%1, %0|%0, %1}";
3401         case MODE_DI:
3402           return "%vmovq\t{%1, %0|%0, %1}";
3403         case MODE_DF:
3404           if (TARGET_AVX)
3405             {
3406               if (REG_P (operands[0]) && REG_P (operands[1]))
3407                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3408               else
3409                 return "vmovsd\t{%1, %0|%0, %1}";
3410             }
3411           else
3412             return "movsd\t{%1, %0|%0, %1}";
3413         case MODE_V1DF:
3414           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3415         case MODE_V2SF:
3416           return "%vmovlps\t{%1, %d0|%d0, %1}";
3417         default:
3418           gcc_unreachable ();
3419         }
3420
3421     case 9:
3422     case 10:
3423     return "%vmovd\t{%1, %0|%0, %1}";
3424
3425     default:
3426       gcc_unreachable();
3427     }
3428 }
3429   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3430    (set (attr "prefix")
3431      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3432        (const_string "orig")
3433        (const_string "maybe_vex")))
3434    (set (attr "prefix_data16")
3435      (if_then_else (eq_attr "mode" "V1DF")
3436        (const_string "1")
3437        (const_string "*")))
3438    (set (attr "mode")
3439         (cond [(eq_attr "alternative" "0,1,2")
3440                  (const_string "DF")
3441                (eq_attr "alternative" "3,4,9,10")
3442                  (const_string "DI")
3443
3444                /* For SSE1, we have many fewer alternatives.  */
3445                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3446                  (cond [(eq_attr "alternative" "5,6")
3447                           (const_string "V4SF")
3448                        ]
3449                    (const_string "V2SF"))
3450
3451                /* xorps is one byte shorter.  */
3452                (eq_attr "alternative" "5")
3453                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3454                             (const_int 0))
3455                           (const_string "V4SF")
3456                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3457                             (const_int 0))
3458                           (const_string "TI")
3459                        ]
3460                        (const_string "V2DF"))
3461
3462                /* For architectures resolving dependencies on
3463                   whole SSE registers use APD move to break dependency
3464                   chains, otherwise use short move to avoid extra work.
3465
3466                   movaps encodes one byte shorter.  */
3467                (eq_attr "alternative" "6")
3468                  (cond
3469                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3470                         (const_int 0))
3471                       (const_string "V4SF")
3472                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3473                         (const_int 0))
3474                       (const_string "V2DF")
3475                    ]
3476                    (const_string "DF"))
3477                /* For architectures resolving dependencies on register
3478                   parts we may avoid extra work to zero out upper part
3479                   of register.  */
3480                (eq_attr "alternative" "7")
3481                  (if_then_else
3482                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3483                        (const_int 0))
3484                    (const_string "V1DF")
3485                    (const_string "DF"))
3486               ]
3487               (const_string "DF")))])
3488
3489 (define_insn "*movdf_integer"
3490   [(set (match_operand:DF 0 "nonimmediate_operand"
3491                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3492         (match_operand:DF 1 "general_operand"
3493                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3494   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3495    && optimize_function_for_speed_p (cfun)
3496    && TARGET_INTEGER_DFMODE_MOVES
3497    && (reload_in_progress || reload_completed
3498        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3499        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3500            && optimize_function_for_size_p (cfun)
3501            && standard_80387_constant_p (operands[1]))
3502        || GET_CODE (operands[1]) != CONST_DOUBLE
3503        || memory_operand (operands[0], DFmode))"
3504 {
3505   switch (which_alternative)
3506     {
3507     case 0:
3508     case 1:
3509       return output_387_reg_move (insn, operands);
3510
3511     case 2:
3512       return standard_80387_constant_opcode (operands[1]);
3513
3514     case 3:
3515     case 4:
3516       return "#";
3517
3518     case 5:
3519       switch (get_attr_mode (insn))
3520         {
3521         case MODE_V4SF:
3522           return "xorps\t%0, %0";
3523         case MODE_V2DF:
3524           return "xorpd\t%0, %0";
3525         case MODE_TI:
3526           return "pxor\t%0, %0";
3527         default:
3528           gcc_unreachable ();
3529         }
3530     case 6:
3531     case 7:
3532     case 8:
3533       switch (get_attr_mode (insn))
3534         {
3535         case MODE_V4SF:
3536           return "movaps\t{%1, %0|%0, %1}";
3537         case MODE_V2DF:
3538           return "movapd\t{%1, %0|%0, %1}";
3539         case MODE_TI:
3540           return "movdqa\t{%1, %0|%0, %1}";
3541         case MODE_DI:
3542           return "movq\t{%1, %0|%0, %1}";
3543         case MODE_DF:
3544           return "movsd\t{%1, %0|%0, %1}";
3545         case MODE_V1DF:
3546           return "movlpd\t{%1, %0|%0, %1}";
3547         case MODE_V2SF:
3548           return "movlps\t{%1, %0|%0, %1}";
3549         default:
3550           gcc_unreachable ();
3551         }
3552
3553     default:
3554       gcc_unreachable();
3555     }
3556 }
3557   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3558    (set (attr "prefix_data16")
3559      (if_then_else (eq_attr "mode" "V1DF")
3560        (const_string "1")
3561        (const_string "*")))
3562    (set (attr "mode")
3563         (cond [(eq_attr "alternative" "0,1,2")
3564                  (const_string "DF")
3565                (eq_attr "alternative" "3,4")
3566                  (const_string "SI")
3567
3568                /* For SSE1, we have many fewer alternatives.  */
3569                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3570                  (cond [(eq_attr "alternative" "5,6")
3571                           (const_string "V4SF")
3572                        ]
3573                    (const_string "V2SF"))
3574
3575                /* xorps is one byte shorter.  */
3576                (eq_attr "alternative" "5")
3577                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3578                             (const_int 0))
3579                           (const_string "V4SF")
3580                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3581                             (const_int 0))
3582                           (const_string "TI")
3583                        ]
3584                        (const_string "V2DF"))
3585
3586                /* For architectures resolving dependencies on
3587                   whole SSE registers use APD move to break dependency
3588                   chains, otherwise use short move to avoid extra work.
3589
3590                   movaps encodes one byte shorter.  */
3591                (eq_attr "alternative" "6")
3592                  (cond
3593                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3594                         (const_int 0))
3595                       (const_string "V4SF")
3596                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3597                         (const_int 0))
3598                       (const_string "V2DF")
3599                    ]
3600                    (const_string "DF"))
3601                /* For architectures resolving dependencies on register
3602                   parts we may avoid extra work to zero out upper part
3603                   of register.  */
3604                (eq_attr "alternative" "7")
3605                  (if_then_else
3606                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3607                        (const_int 0))
3608                    (const_string "V1DF")
3609                    (const_string "DF"))
3610               ]
3611               (const_string "DF")))])
3612
3613 (define_split
3614   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3615         (match_operand:DF 1 "general_operand" ""))]
3616   "reload_completed
3617    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3618    && ! (ANY_FP_REG_P (operands[0]) ||
3619          (GET_CODE (operands[0]) == SUBREG
3620           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3621    && ! (ANY_FP_REG_P (operands[1]) ||
3622          (GET_CODE (operands[1]) == SUBREG
3623           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3624   [(const_int 0)]
3625   "ix86_split_long_move (operands); DONE;")
3626
3627 (define_insn "*swapdf"
3628   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3629         (match_operand:DF 1 "fp_register_operand" "+f"))
3630    (set (match_dup 1)
3631         (match_dup 0))]
3632   "reload_completed || TARGET_80387"
3633 {
3634   if (STACK_TOP_P (operands[0]))
3635     return "fxch\t%1";
3636   else
3637     return "fxch\t%0";
3638 }
3639   [(set_attr "type" "fxch")
3640    (set_attr "mode" "DF")])
3641
3642 (define_expand "movxf"
3643   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3644         (match_operand:XF 1 "general_operand" ""))]
3645   ""
3646   "ix86_expand_move (XFmode, operands); DONE;")
3647
3648 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3649 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3650 ;; Pushing using integer instructions is longer except for constants
3651 ;; and direct memory references.
3652 ;; (assuming that any given constant is pushed only once, but this ought to be
3653 ;;  handled elsewhere).
3654
3655 (define_insn "*pushxf_nointeger"
3656   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3657         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3658   "optimize_function_for_size_p (cfun)"
3659 {
3660   /* This insn should be already split before reg-stack.  */
3661   gcc_unreachable ();
3662 }
3663   [(set_attr "type" "multi")
3664    (set_attr "unit" "i387,*,*")
3665    (set_attr "mode" "XF,SI,SI")])
3666
3667 (define_insn "*pushxf_integer"
3668   [(set (match_operand:XF 0 "push_operand" "=<,<")
3669         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3670   "optimize_function_for_speed_p (cfun)"
3671 {
3672   /* This insn should be already split before reg-stack.  */
3673   gcc_unreachable ();
3674 }
3675   [(set_attr "type" "multi")
3676    (set_attr "unit" "i387,*")
3677    (set_attr "mode" "XF,SI")])
3678
3679 (define_split
3680   [(set (match_operand 0 "push_operand" "")
3681         (match_operand 1 "general_operand" ""))]
3682   "reload_completed
3683    && (GET_MODE (operands[0]) == XFmode
3684        || GET_MODE (operands[0]) == DFmode)
3685    && !ANY_FP_REG_P (operands[1])"
3686   [(const_int 0)]
3687   "ix86_split_long_move (operands); DONE;")
3688
3689 (define_split
3690   [(set (match_operand:XF 0 "push_operand" "")
3691         (match_operand:XF 1 "any_fp_register_operand" ""))]
3692   ""
3693   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3694    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3695   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3696
3697 ;; Do not use integer registers when optimizing for size
3698 (define_insn "*movxf_nointeger"
3699   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3700         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3701   "optimize_function_for_size_p (cfun)
3702    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3703    && (reload_in_progress || reload_completed
3704        || standard_80387_constant_p (operands[1])
3705        || GET_CODE (operands[1]) != CONST_DOUBLE
3706        || memory_operand (operands[0], XFmode))"
3707 {
3708   switch (which_alternative)
3709     {
3710     case 0:
3711     case 1:
3712       return output_387_reg_move (insn, operands);
3713
3714     case 2:
3715       return standard_80387_constant_opcode (operands[1]);
3716
3717     case 3: case 4:
3718       return "#";
3719     default:
3720       gcc_unreachable ();
3721     }
3722 }
3723   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3724    (set_attr "mode" "XF,XF,XF,SI,SI")])
3725
3726 (define_insn "*movxf_integer"
3727   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3728         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3729   "optimize_function_for_speed_p (cfun)
3730    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3731    && (reload_in_progress || reload_completed
3732        || GET_CODE (operands[1]) != CONST_DOUBLE
3733        || memory_operand (operands[0], XFmode))"
3734 {
3735   switch (which_alternative)
3736     {
3737     case 0:
3738     case 1:
3739       return output_387_reg_move (insn, operands);
3740
3741     case 2:
3742       return standard_80387_constant_opcode (operands[1]);
3743
3744     case 3: case 4:
3745       return "#";
3746
3747     default:
3748       gcc_unreachable ();
3749     }
3750 }
3751   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3752    (set_attr "mode" "XF,XF,XF,SI,SI")])
3753
3754 (define_expand "movtf"
3755   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3756         (match_operand:TF 1 "nonimmediate_operand" ""))]
3757   "TARGET_SSE2"
3758 {
3759   ix86_expand_move (TFmode, operands);
3760   DONE;
3761 })
3762
3763 (define_insn "*movtf_internal"
3764   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3765         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3766   "TARGET_SSE2
3767    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3768 {
3769   switch (which_alternative)
3770     {
3771     case 0:
3772     case 1:
3773       if (get_attr_mode (insn) == MODE_V4SF)
3774         return "%vmovaps\t{%1, %0|%0, %1}";
3775       else
3776         return "%vmovdqa\t{%1, %0|%0, %1}";
3777     case 2:
3778       if (get_attr_mode (insn) == MODE_V4SF)
3779         return "%vxorps\t%0, %d0";
3780       else
3781         return "%vpxor\t%0, %d0";
3782     case 3:
3783     case 4:
3784         return "#";
3785     default:
3786       gcc_unreachable ();
3787     }
3788 }
3789   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3790    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3791    (set (attr "mode")
3792         (cond [(eq_attr "alternative" "0,2")
3793                  (if_then_else
3794                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3795                        (const_int 0))
3796                    (const_string "V4SF")
3797                    (const_string "TI"))
3798                (eq_attr "alternative" "1")
3799                  (if_then_else
3800                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3801                             (const_int 0))
3802                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3803                             (const_int 0)))
3804                    (const_string "V4SF")
3805                    (const_string "TI"))]
3806                (const_string "DI")))])
3807
3808 (define_insn "*pushtf_sse"
3809   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3810         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3811   "TARGET_SSE2"
3812 {
3813   /* This insn should be already split before reg-stack.  */
3814   gcc_unreachable ();
3815 }
3816   [(set_attr "type" "multi")
3817    (set_attr "unit" "sse,*,*")
3818    (set_attr "mode" "TF,SI,SI")])
3819
3820 (define_split
3821   [(set (match_operand:TF 0 "push_operand" "")
3822         (match_operand:TF 1 "general_operand" ""))]
3823   "TARGET_SSE2 && reload_completed
3824    && !SSE_REG_P (operands[1])"
3825   [(const_int 0)]
3826   "ix86_split_long_move (operands); DONE;")
3827
3828 (define_split
3829   [(set (match_operand:TF 0 "push_operand" "")
3830         (match_operand:TF 1 "any_fp_register_operand" ""))]
3831   "TARGET_SSE2"
3832   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3833    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3834   "")
3835
3836 (define_split
3837   [(set (match_operand 0 "nonimmediate_operand" "")
3838         (match_operand 1 "general_operand" ""))]
3839   "reload_completed
3840    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3841    && GET_MODE (operands[0]) == XFmode
3842    && ! (ANY_FP_REG_P (operands[0]) ||
3843          (GET_CODE (operands[0]) == SUBREG
3844           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3845    && ! (ANY_FP_REG_P (operands[1]) ||
3846          (GET_CODE (operands[1]) == SUBREG
3847           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3848   [(const_int 0)]
3849   "ix86_split_long_move (operands); DONE;")
3850
3851 (define_split
3852   [(set (match_operand 0 "register_operand" "")
3853         (match_operand 1 "memory_operand" ""))]
3854   "reload_completed
3855    && MEM_P (operands[1])
3856    && (GET_MODE (operands[0]) == TFmode
3857        || GET_MODE (operands[0]) == XFmode
3858        || GET_MODE (operands[0]) == SFmode
3859        || GET_MODE (operands[0]) == DFmode)
3860    && (operands[2] = find_constant_src (insn))"
3861   [(set (match_dup 0) (match_dup 2))]
3862 {
3863   rtx c = operands[2];
3864   rtx r = operands[0];
3865
3866   if (GET_CODE (r) == SUBREG)
3867     r = SUBREG_REG (r);
3868
3869   if (SSE_REG_P (r))
3870     {
3871       if (!standard_sse_constant_p (c))
3872         FAIL;
3873     }
3874   else if (FP_REG_P (r))
3875     {
3876       if (!standard_80387_constant_p (c))
3877         FAIL;
3878     }
3879   else if (MMX_REG_P (r))
3880     FAIL;
3881 })
3882
3883 (define_split
3884   [(set (match_operand 0 "register_operand" "")
3885         (float_extend (match_operand 1 "memory_operand" "")))]
3886   "reload_completed
3887    && MEM_P (operands[1])
3888    && (GET_MODE (operands[0]) == TFmode
3889        || GET_MODE (operands[0]) == XFmode
3890        || GET_MODE (operands[0]) == SFmode
3891        || GET_MODE (operands[0]) == DFmode)
3892    && (operands[2] = find_constant_src (insn))"
3893   [(set (match_dup 0) (match_dup 2))]
3894 {
3895   rtx c = operands[2];
3896   rtx r = operands[0];
3897
3898   if (GET_CODE (r) == SUBREG)
3899     r = SUBREG_REG (r);
3900
3901   if (SSE_REG_P (r))
3902     {
3903       if (!standard_sse_constant_p (c))
3904         FAIL;
3905     }
3906   else if (FP_REG_P (r))
3907     {
3908       if (!standard_80387_constant_p (c))
3909         FAIL;
3910     }
3911   else if (MMX_REG_P (r))
3912     FAIL;
3913 })
3914
3915 (define_insn "swapxf"
3916   [(set (match_operand:XF 0 "register_operand" "+f")
3917         (match_operand:XF 1 "register_operand" "+f"))
3918    (set (match_dup 1)
3919         (match_dup 0))]
3920   "TARGET_80387"
3921 {
3922   if (STACK_TOP_P (operands[0]))
3923     return "fxch\t%1";
3924   else
3925     return "fxch\t%0";
3926 }
3927   [(set_attr "type" "fxch")
3928    (set_attr "mode" "XF")])
3929
3930 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3931 (define_split
3932   [(set (match_operand:X87MODEF 0 "register_operand" "")
3933         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3934   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3935    && (standard_80387_constant_p (operands[1]) == 8
3936        || standard_80387_constant_p (operands[1]) == 9)"
3937   [(set (match_dup 0)(match_dup 1))
3938    (set (match_dup 0)
3939         (neg:X87MODEF (match_dup 0)))]
3940 {
3941   REAL_VALUE_TYPE r;
3942
3943   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3944   if (real_isnegzero (&r))
3945     operands[1] = CONST0_RTX (<MODE>mode);
3946   else
3947     operands[1] = CONST1_RTX (<MODE>mode);
3948 })
3949
3950 (define_split
3951   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3952         (match_operand:TF 1 "general_operand" ""))]
3953   "reload_completed
3954    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3955   [(const_int 0)]
3956   "ix86_split_long_move (operands); DONE;")
3957 \f
3958 ;; Zero extension instructions
3959
3960 (define_expand "zero_extendhisi2"
3961   [(set (match_operand:SI 0 "register_operand" "")
3962      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3963   ""
3964 {
3965   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3966     {
3967       operands[1] = force_reg (HImode, operands[1]);
3968       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3969       DONE;
3970     }
3971 })
3972
3973 (define_insn "zero_extendhisi2_and"
3974   [(set (match_operand:SI 0 "register_operand" "=r")
3975      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3976    (clobber (reg:CC FLAGS_REG))]
3977   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3978   "#"
3979   [(set_attr "type" "alu1")
3980    (set_attr "mode" "SI")])
3981
3982 (define_split
3983   [(set (match_operand:SI 0 "register_operand" "")
3984         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3985    (clobber (reg:CC FLAGS_REG))]
3986   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3987    && optimize_function_for_speed_p (cfun)"
3988   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3989               (clobber (reg:CC FLAGS_REG))])]
3990   "")
3991
3992 (define_insn "*zero_extendhisi2_movzwl"
3993   [(set (match_operand:SI 0 "register_operand" "=r")
3994      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3995   "!TARGET_ZERO_EXTEND_WITH_AND
3996    || optimize_function_for_size_p (cfun)"
3997   "movz{wl|x}\t{%1, %0|%0, %1}"
3998   [(set_attr "type" "imovx")
3999    (set_attr "mode" "SI")])
4000
4001 (define_expand "zero_extendqihi2"
4002   [(parallel
4003     [(set (match_operand:HI 0 "register_operand" "")
4004        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4005      (clobber (reg:CC FLAGS_REG))])]
4006   ""
4007   "")
4008
4009 (define_insn "*zero_extendqihi2_and"
4010   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4011      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4012    (clobber (reg:CC FLAGS_REG))]
4013   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4014   "#"
4015   [(set_attr "type" "alu1")
4016    (set_attr "mode" "HI")])
4017
4018 (define_insn "*zero_extendqihi2_movzbw_and"
4019   [(set (match_operand:HI 0 "register_operand" "=r,r")
4020      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4021    (clobber (reg:CC FLAGS_REG))]
4022   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4023   "#"
4024   [(set_attr "type" "imovx,alu1")
4025    (set_attr "mode" "HI")])
4026
4027 ; zero extend to SImode here to avoid partial register stalls
4028 (define_insn "*zero_extendqihi2_movzbl"
4029   [(set (match_operand:HI 0 "register_operand" "=r")
4030      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4031   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4032    && reload_completed"
4033   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4034   [(set_attr "type" "imovx")
4035    (set_attr "mode" "SI")])
4036
4037 ;; For the movzbw case strip only the clobber
4038 (define_split
4039   [(set (match_operand:HI 0 "register_operand" "")
4040         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4041    (clobber (reg:CC FLAGS_REG))]
4042   "reload_completed
4043    && (!TARGET_ZERO_EXTEND_WITH_AND
4044        || optimize_function_for_size_p (cfun))
4045    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4046   [(set (match_operand:HI 0 "register_operand" "")
4047         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4048
4049 ;; When source and destination does not overlap, clear destination
4050 ;; first and then do the movb
4051 (define_split
4052   [(set (match_operand:HI 0 "register_operand" "")
4053         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4054    (clobber (reg:CC FLAGS_REG))]
4055   "reload_completed
4056    && ANY_QI_REG_P (operands[0])
4057    && (TARGET_ZERO_EXTEND_WITH_AND
4058        && optimize_function_for_speed_p (cfun))
4059    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4060   [(set (match_dup 0) (const_int 0))
4061    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4062   "operands[2] = gen_lowpart (QImode, operands[0]);")
4063
4064 ;; Rest is handled by single and.
4065 (define_split
4066   [(set (match_operand:HI 0 "register_operand" "")
4067         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4068    (clobber (reg:CC FLAGS_REG))]
4069   "reload_completed
4070    && true_regnum (operands[0]) == true_regnum (operands[1])"
4071   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4072               (clobber (reg:CC FLAGS_REG))])]
4073   "")
4074
4075 (define_expand "zero_extendqisi2"
4076   [(parallel
4077     [(set (match_operand:SI 0 "register_operand" "")
4078        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4079      (clobber (reg:CC FLAGS_REG))])]
4080   ""
4081   "")
4082
4083 (define_insn "*zero_extendqisi2_and"
4084   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4085      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4086    (clobber (reg:CC FLAGS_REG))]
4087   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4088   "#"
4089   [(set_attr "type" "alu1")
4090    (set_attr "mode" "SI")])
4091
4092 (define_insn "*zero_extendqisi2_movzbw_and"
4093   [(set (match_operand:SI 0 "register_operand" "=r,r")
4094      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4095    (clobber (reg:CC FLAGS_REG))]
4096   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4097   "#"
4098   [(set_attr "type" "imovx,alu1")
4099    (set_attr "mode" "SI")])
4100
4101 (define_insn "*zero_extendqisi2_movzbw"
4102   [(set (match_operand:SI 0 "register_operand" "=r")
4103      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4104   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4105    && reload_completed"
4106   "movz{bl|x}\t{%1, %0|%0, %1}"
4107   [(set_attr "type" "imovx")
4108    (set_attr "mode" "SI")])
4109
4110 ;; For the movzbl case strip only the clobber
4111 (define_split
4112   [(set (match_operand:SI 0 "register_operand" "")
4113         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4114    (clobber (reg:CC FLAGS_REG))]
4115   "reload_completed
4116    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4117    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4118   [(set (match_dup 0)
4119         (zero_extend:SI (match_dup 1)))])
4120
4121 ;; When source and destination does not overlap, clear destination
4122 ;; first and then do the movb
4123 (define_split
4124   [(set (match_operand:SI 0 "register_operand" "")
4125         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4126    (clobber (reg:CC FLAGS_REG))]
4127   "reload_completed
4128    && ANY_QI_REG_P (operands[0])
4129    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4130    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4131    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4132   [(set (match_dup 0) (const_int 0))
4133    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4134   "operands[2] = gen_lowpart (QImode, operands[0]);")
4135
4136 ;; Rest is handled by single and.
4137 (define_split
4138   [(set (match_operand:SI 0 "register_operand" "")
4139         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4140    (clobber (reg:CC FLAGS_REG))]
4141   "reload_completed
4142    && true_regnum (operands[0]) == true_regnum (operands[1])"
4143   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4144               (clobber (reg:CC FLAGS_REG))])]
4145   "")
4146
4147 ;; %%% Kill me once multi-word ops are sane.
4148 (define_expand "zero_extendsidi2"
4149   [(set (match_operand:DI 0 "register_operand" "")
4150      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4151   ""
4152 {
4153   if (!TARGET_64BIT)
4154     {
4155       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4156       DONE;
4157     }
4158 })
4159
4160 (define_insn "zero_extendsidi2_32"
4161   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4162         (zero_extend:DI
4163          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4164    (clobber (reg:CC FLAGS_REG))]
4165   "!TARGET_64BIT"
4166   "@
4167    #
4168    #
4169    #
4170    movd\t{%1, %0|%0, %1}
4171    movd\t{%1, %0|%0, %1}
4172    %vmovd\t{%1, %0|%0, %1}
4173    %vmovd\t{%1, %0|%0, %1}"
4174   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4175    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4176    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4177
4178 (define_insn "zero_extendsidi2_rex64"
4179   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4180      (zero_extend:DI
4181        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4182   "TARGET_64BIT"
4183   "@
4184    mov\t{%k1, %k0|%k0, %k1}
4185    #
4186    movd\t{%1, %0|%0, %1}
4187    movd\t{%1, %0|%0, %1}
4188    %vmovd\t{%1, %0|%0, %1}
4189    %vmovd\t{%1, %0|%0, %1}"
4190   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4191    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4192    (set_attr "prefix_0f" "0,*,*,*,*,*")
4193    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4194
4195 (define_split
4196   [(set (match_operand:DI 0 "memory_operand" "")
4197      (zero_extend:DI (match_dup 0)))]
4198   "TARGET_64BIT"
4199   [(set (match_dup 4) (const_int 0))]
4200   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4201
4202 (define_split
4203   [(set (match_operand:DI 0 "register_operand" "")
4204         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4205    (clobber (reg:CC FLAGS_REG))]
4206   "!TARGET_64BIT && reload_completed
4207    && true_regnum (operands[0]) == true_regnum (operands[1])"
4208   [(set (match_dup 4) (const_int 0))]
4209   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4210
4211 (define_split
4212   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4214    (clobber (reg:CC FLAGS_REG))]
4215   "!TARGET_64BIT && reload_completed
4216    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4217   [(set (match_dup 3) (match_dup 1))
4218    (set (match_dup 4) (const_int 0))]
4219   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4220
4221 (define_insn "zero_extendhidi2"
4222   [(set (match_operand:DI 0 "register_operand" "=r")
4223      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4224   "TARGET_64BIT"
4225   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4226   [(set_attr "type" "imovx")
4227    (set_attr "mode" "SI")])
4228
4229 (define_insn "zero_extendqidi2"
4230   [(set (match_operand:DI 0 "register_operand" "=r")
4231      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4232   "TARGET_64BIT"
4233   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4234   [(set_attr "type" "imovx")
4235    (set_attr "mode" "SI")])
4236 \f
4237 ;; Sign extension instructions
4238
4239 (define_expand "extendsidi2"
4240   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4241                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4242               (clobber (reg:CC FLAGS_REG))
4243               (clobber (match_scratch:SI 2 ""))])]
4244   ""
4245 {
4246   if (TARGET_64BIT)
4247     {
4248       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4249       DONE;
4250     }
4251 })
4252
4253 (define_insn "*extendsidi2_1"
4254   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4255         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4256    (clobber (reg:CC FLAGS_REG))
4257    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4258   "!TARGET_64BIT"
4259   "#")
4260
4261 (define_insn "extendsidi2_rex64"
4262   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4263         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4264   "TARGET_64BIT"
4265   "@
4266    {cltq|cdqe}
4267    movs{lq|x}\t{%1, %0|%0, %1}"
4268   [(set_attr "type" "imovx")
4269    (set_attr "mode" "DI")
4270    (set_attr "prefix_0f" "0")
4271    (set_attr "modrm" "0,1")])
4272
4273 (define_insn "extendhidi2"
4274   [(set (match_operand:DI 0 "register_operand" "=r")
4275         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4276   "TARGET_64BIT"
4277   "movs{wq|x}\t{%1, %0|%0, %1}"
4278   [(set_attr "type" "imovx")
4279    (set_attr "mode" "DI")])
4280
4281 (define_insn "extendqidi2"
4282   [(set (match_operand:DI 0 "register_operand" "=r")
4283         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4284   "TARGET_64BIT"
4285   "movs{bq|x}\t{%1, %0|%0, %1}"
4286    [(set_attr "type" "imovx")
4287     (set_attr "mode" "DI")])
4288
4289 ;; Extend to memory case when source register does die.
4290 (define_split
4291   [(set (match_operand:DI 0 "memory_operand" "")
4292         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4293    (clobber (reg:CC FLAGS_REG))
4294    (clobber (match_operand:SI 2 "register_operand" ""))]
4295   "(reload_completed
4296     && dead_or_set_p (insn, operands[1])
4297     && !reg_mentioned_p (operands[1], operands[0]))"
4298   [(set (match_dup 3) (match_dup 1))
4299    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4300               (clobber (reg:CC FLAGS_REG))])
4301    (set (match_dup 4) (match_dup 1))]
4302   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4303
4304 ;; Extend to memory case when source register does not die.
4305 (define_split
4306   [(set (match_operand:DI 0 "memory_operand" "")
4307         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4308    (clobber (reg:CC FLAGS_REG))
4309    (clobber (match_operand:SI 2 "register_operand" ""))]
4310   "reload_completed"
4311   [(const_int 0)]
4312 {
4313   split_di (&operands[0], 1, &operands[3], &operands[4]);
4314
4315   emit_move_insn (operands[3], operands[1]);
4316
4317   /* Generate a cltd if possible and doing so it profitable.  */
4318   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4319       && true_regnum (operands[1]) == AX_REG
4320       && true_regnum (operands[2]) == DX_REG)
4321     {
4322       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4323     }
4324   else
4325     {
4326       emit_move_insn (operands[2], operands[1]);
4327       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4328     }
4329   emit_move_insn (operands[4], operands[2]);
4330   DONE;
4331 })
4332
4333 ;; Extend to register case.  Optimize case where source and destination
4334 ;; registers match and cases where we can use cltd.
4335 (define_split
4336   [(set (match_operand:DI 0 "register_operand" "")
4337         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4338    (clobber (reg:CC FLAGS_REG))
4339    (clobber (match_scratch:SI 2 ""))]
4340   "reload_completed"
4341   [(const_int 0)]
4342 {
4343   split_di (&operands[0], 1, &operands[3], &operands[4]);
4344
4345   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4346     emit_move_insn (operands[3], operands[1]);
4347
4348   /* Generate a cltd if possible and doing so it profitable.  */
4349   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4350       && true_regnum (operands[3]) == AX_REG)
4351     {
4352       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4353       DONE;
4354     }
4355
4356   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4357     emit_move_insn (operands[4], operands[1]);
4358
4359   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4360   DONE;
4361 })
4362
4363 (define_insn "extendhisi2"
4364   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4365         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4366   ""
4367 {
4368   switch (get_attr_prefix_0f (insn))
4369     {
4370     case 0:
4371       return "{cwtl|cwde}";
4372     default:
4373       return "movs{wl|x}\t{%1, %0|%0, %1}";
4374     }
4375 }
4376   [(set_attr "type" "imovx")
4377    (set_attr "mode" "SI")
4378    (set (attr "prefix_0f")
4379      ;; movsx is short decodable while cwtl is vector decoded.
4380      (if_then_else (and (eq_attr "cpu" "!k6")
4381                         (eq_attr "alternative" "0"))
4382         (const_string "0")
4383         (const_string "1")))
4384    (set (attr "modrm")
4385      (if_then_else (eq_attr "prefix_0f" "0")
4386         (const_string "0")
4387         (const_string "1")))])
4388
4389 (define_insn "*extendhisi2_zext"
4390   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4391         (zero_extend:DI
4392           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4393   "TARGET_64BIT"
4394 {
4395   switch (get_attr_prefix_0f (insn))
4396     {
4397     case 0:
4398       return "{cwtl|cwde}";
4399     default:
4400       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4401     }
4402 }
4403   [(set_attr "type" "imovx")
4404    (set_attr "mode" "SI")
4405    (set (attr "prefix_0f")
4406      ;; movsx is short decodable while cwtl is vector decoded.
4407      (if_then_else (and (eq_attr "cpu" "!k6")
4408                         (eq_attr "alternative" "0"))
4409         (const_string "0")
4410         (const_string "1")))
4411    (set (attr "modrm")
4412      (if_then_else (eq_attr "prefix_0f" "0")
4413         (const_string "0")
4414         (const_string "1")))])
4415
4416 (define_insn "extendqihi2"
4417   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4418         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4419   ""
4420 {
4421   switch (get_attr_prefix_0f (insn))
4422     {
4423     case 0:
4424       return "{cbtw|cbw}";
4425     default:
4426       return "movs{bw|x}\t{%1, %0|%0, %1}";
4427     }
4428 }
4429   [(set_attr "type" "imovx")
4430    (set_attr "mode" "HI")
4431    (set (attr "prefix_0f")
4432      ;; movsx is short decodable while cwtl is vector decoded.
4433      (if_then_else (and (eq_attr "cpu" "!k6")
4434                         (eq_attr "alternative" "0"))
4435         (const_string "0")
4436         (const_string "1")))
4437    (set (attr "modrm")
4438      (if_then_else (eq_attr "prefix_0f" "0")
4439         (const_string "0")
4440         (const_string "1")))])
4441
4442 (define_insn "extendqisi2"
4443   [(set (match_operand:SI 0 "register_operand" "=r")
4444         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4445   ""
4446   "movs{bl|x}\t{%1, %0|%0, %1}"
4447    [(set_attr "type" "imovx")
4448     (set_attr "mode" "SI")])
4449
4450 (define_insn "*extendqisi2_zext"
4451   [(set (match_operand:DI 0 "register_operand" "=r")
4452         (zero_extend:DI
4453           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4454   "TARGET_64BIT"
4455   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4456    [(set_attr "type" "imovx")
4457     (set_attr "mode" "SI")])
4458 \f
4459 ;; Conversions between float and double.
4460
4461 ;; These are all no-ops in the model used for the 80387.  So just
4462 ;; emit moves.
4463
4464 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4465 (define_insn "*dummy_extendsfdf2"
4466   [(set (match_operand:DF 0 "push_operand" "=<")
4467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4468   "0"
4469   "#")
4470
4471 (define_split
4472   [(set (match_operand:DF 0 "push_operand" "")
4473         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4474   ""
4475   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4476    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4477
4478 (define_insn "*dummy_extendsfxf2"
4479   [(set (match_operand:XF 0 "push_operand" "=<")
4480         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4481   "0"
4482   "#")
4483
4484 (define_split
4485   [(set (match_operand:XF 0 "push_operand" "")
4486         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4487   ""
4488   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4489    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4490   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4491
4492 (define_split
4493   [(set (match_operand:XF 0 "push_operand" "")
4494         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4495   ""
4496   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4497    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4498   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4499
4500 (define_expand "extendsfdf2"
4501   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4502         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4503   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4504 {
4505   /* ??? Needed for compress_float_constant since all fp constants
4506      are LEGITIMATE_CONSTANT_P.  */
4507   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4508     {
4509       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4510           && standard_80387_constant_p (operands[1]) > 0)
4511         {
4512           operands[1] = simplify_const_unary_operation
4513             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4514           emit_move_insn_1 (operands[0], operands[1]);
4515           DONE;
4516         }
4517       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4518     }
4519 })
4520
4521 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4522    cvtss2sd:
4523       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4524       cvtps2pd xmm2,xmm1
4525    We do the conversion post reload to avoid producing of 128bit spills
4526    that might lead to ICE on 32bit target.  The sequence unlikely combine
4527    anyway.  */
4528 (define_split
4529   [(set (match_operand:DF 0 "register_operand" "")
4530         (float_extend:DF
4531           (match_operand:SF 1 "nonimmediate_operand" "")))]
4532   "TARGET_USE_VECTOR_FP_CONVERTS
4533    && optimize_insn_for_speed_p ()
4534    && reload_completed && SSE_REG_P (operands[0])"
4535    [(set (match_dup 2)
4536          (float_extend:V2DF
4537            (vec_select:V2SF
4538              (match_dup 3)
4539              (parallel [(const_int 0) (const_int 1)]))))]
4540 {
4541   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4542   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4543   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4544      Try to avoid move when unpacking can be done in source.  */
4545   if (REG_P (operands[1]))
4546     {
4547       /* If it is unsafe to overwrite upper half of source, we need
4548          to move to destination and unpack there.  */
4549       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4550            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4551           && true_regnum (operands[0]) != true_regnum (operands[1]))
4552         {
4553           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4554           emit_move_insn (tmp, operands[1]);
4555         }
4556       else
4557         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4558       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4559     }
4560   else
4561     emit_insn (gen_vec_setv4sf_0 (operands[3],
4562                                   CONST0_RTX (V4SFmode), operands[1]));
4563 })
4564
4565 (define_insn "*extendsfdf2_mixed"
4566   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4567         (float_extend:DF
4568           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4569   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4570 {
4571   switch (which_alternative)
4572     {
4573     case 0:
4574     case 1:
4575       return output_387_reg_move (insn, operands);
4576
4577     case 2:
4578       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4579
4580     default:
4581       gcc_unreachable ();
4582     }
4583 }
4584   [(set_attr "type" "fmov,fmov,ssecvt")
4585    (set_attr "prefix" "orig,orig,maybe_vex")
4586    (set_attr "mode" "SF,XF,DF")])
4587
4588 (define_insn "*extendsfdf2_sse"
4589   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4590         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4591   "TARGET_SSE2 && TARGET_SSE_MATH"
4592   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4593   [(set_attr "type" "ssecvt")
4594    (set_attr "prefix" "maybe_vex")
4595    (set_attr "mode" "DF")])
4596
4597 (define_insn "*extendsfdf2_i387"
4598   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4599         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4600   "TARGET_80387"
4601   "* return output_387_reg_move (insn, operands);"
4602   [(set_attr "type" "fmov")
4603    (set_attr "mode" "SF,XF")])
4604
4605 (define_expand "extend<mode>xf2"
4606   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4607         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4608   "TARGET_80387"
4609 {
4610   /* ??? Needed for compress_float_constant since all fp constants
4611      are LEGITIMATE_CONSTANT_P.  */
4612   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4613     {
4614       if (standard_80387_constant_p (operands[1]) > 0)
4615         {
4616           operands[1] = simplify_const_unary_operation
4617             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4618           emit_move_insn_1 (operands[0], operands[1]);
4619           DONE;
4620         }
4621       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4622     }
4623 })
4624
4625 (define_insn "*extend<mode>xf2_i387"
4626   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4627         (float_extend:XF
4628           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4629   "TARGET_80387"
4630   "* return output_387_reg_move (insn, operands);"
4631   [(set_attr "type" "fmov")
4632    (set_attr "mode" "<MODE>,XF")])
4633
4634 ;; %%% This seems bad bad news.
4635 ;; This cannot output into an f-reg because there is no way to be sure
4636 ;; of truncating in that case.  Otherwise this is just like a simple move
4637 ;; insn.  So we pretend we can output to a reg in order to get better
4638 ;; register preferencing, but we really use a stack slot.
4639
4640 ;; Conversion from DFmode to SFmode.
4641
4642 (define_expand "truncdfsf2"
4643   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4644         (float_truncate:SF
4645           (match_operand:DF 1 "nonimmediate_operand" "")))]
4646   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4647 {
4648   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4649     ;
4650   else if (flag_unsafe_math_optimizations)
4651     ;
4652   else
4653     {
4654       enum ix86_stack_slot slot = (virtuals_instantiated
4655                                    ? SLOT_TEMP
4656                                    : SLOT_VIRTUAL);
4657       rtx temp = assign_386_stack_local (SFmode, slot);
4658       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4659       DONE;
4660     }
4661 })
4662
4663 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4664    cvtsd2ss:
4665       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4666       cvtpd2ps xmm2,xmm1
4667    We do the conversion post reload to avoid producing of 128bit spills
4668    that might lead to ICE on 32bit target.  The sequence unlikely combine
4669    anyway.  */
4670 (define_split
4671   [(set (match_operand:SF 0 "register_operand" "")
4672         (float_truncate:SF
4673           (match_operand:DF 1 "nonimmediate_operand" "")))]
4674   "TARGET_USE_VECTOR_FP_CONVERTS
4675    && optimize_insn_for_speed_p ()
4676    && reload_completed && SSE_REG_P (operands[0])"
4677    [(set (match_dup 2)
4678          (vec_concat:V4SF
4679            (float_truncate:V2SF
4680              (match_dup 4))
4681            (match_dup 3)))]
4682 {
4683   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4684   operands[3] = CONST0_RTX (V2SFmode);
4685   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4686   /* Use movsd for loading from memory, unpcklpd for registers.
4687      Try to avoid move when unpacking can be done in source, or SSE3
4688      movddup is available.  */
4689   if (REG_P (operands[1]))
4690     {
4691       if (!TARGET_SSE3
4692           && true_regnum (operands[0]) != true_regnum (operands[1])
4693           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4694               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4695         {
4696           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4697           emit_move_insn (tmp, operands[1]);
4698           operands[1] = tmp;
4699         }
4700       else if (!TARGET_SSE3)
4701         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4702       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4703     }
4704   else
4705     emit_insn (gen_sse2_loadlpd (operands[4],
4706                                  CONST0_RTX (V2DFmode), operands[1]));
4707 })
4708
4709 (define_expand "truncdfsf2_with_temp"
4710   [(parallel [(set (match_operand:SF 0 "" "")
4711                    (float_truncate:SF (match_operand:DF 1 "" "")))
4712               (clobber (match_operand:SF 2 "" ""))])]
4713   "")
4714
4715 (define_insn "*truncdfsf_fast_mixed"
4716   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4717         (float_truncate:SF
4718           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4719   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4720 {
4721   switch (which_alternative)
4722     {
4723     case 0:
4724       return output_387_reg_move (insn, operands);
4725     case 1:
4726       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4727     default:
4728       gcc_unreachable ();
4729     }
4730 }
4731   [(set_attr "type" "fmov,ssecvt")
4732    (set_attr "prefix" "orig,maybe_vex")
4733    (set_attr "mode" "SF")])
4734
4735 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4736 ;; because nothing we do here is unsafe.
4737 (define_insn "*truncdfsf_fast_sse"
4738   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4739         (float_truncate:SF
4740           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4741   "TARGET_SSE2 && TARGET_SSE_MATH"
4742   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4743   [(set_attr "type" "ssecvt")
4744    (set_attr "prefix" "maybe_vex")
4745    (set_attr "mode" "SF")])
4746
4747 (define_insn "*truncdfsf_fast_i387"
4748   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4749         (float_truncate:SF
4750           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4751   "TARGET_80387 && flag_unsafe_math_optimizations"
4752   "* return output_387_reg_move (insn, operands);"
4753   [(set_attr "type" "fmov")
4754    (set_attr "mode" "SF")])
4755
4756 (define_insn "*truncdfsf_mixed"
4757   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4758         (float_truncate:SF
4759           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4760    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4761   "TARGET_MIX_SSE_I387"
4762 {
4763   switch (which_alternative)
4764     {
4765     case 0:
4766       return output_387_reg_move (insn, operands);
4767     case 1:
4768       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4769
4770     default:
4771       return "#";
4772     }
4773 }
4774   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4775    (set_attr "unit" "*,*,i387,i387,i387")
4776    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4777    (set_attr "mode" "SF")])
4778
4779 (define_insn "*truncdfsf_i387"
4780   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4781         (float_truncate:SF
4782           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4783    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4784   "TARGET_80387"
4785 {
4786   switch (which_alternative)
4787     {
4788     case 0:
4789       return output_387_reg_move (insn, operands);
4790
4791     default:
4792       return "#";
4793     }
4794 }
4795   [(set_attr "type" "fmov,multi,multi,multi")
4796    (set_attr "unit" "*,i387,i387,i387")
4797    (set_attr "mode" "SF")])
4798
4799 (define_insn "*truncdfsf2_i387_1"
4800   [(set (match_operand:SF 0 "memory_operand" "=m")
4801         (float_truncate:SF
4802           (match_operand:DF 1 "register_operand" "f")))]
4803   "TARGET_80387
4804    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4805    && !TARGET_MIX_SSE_I387"
4806   "* return output_387_reg_move (insn, operands);"
4807   [(set_attr "type" "fmov")
4808    (set_attr "mode" "SF")])
4809
4810 (define_split
4811   [(set (match_operand:SF 0 "register_operand" "")
4812         (float_truncate:SF
4813          (match_operand:DF 1 "fp_register_operand" "")))
4814    (clobber (match_operand 2 "" ""))]
4815   "reload_completed"
4816   [(set (match_dup 2) (match_dup 1))
4817    (set (match_dup 0) (match_dup 2))]
4818 {
4819   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4820 })
4821
4822 ;; Conversion from XFmode to {SF,DF}mode
4823
4824 (define_expand "truncxf<mode>2"
4825   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4826                    (float_truncate:MODEF
4827                      (match_operand:XF 1 "register_operand" "")))
4828               (clobber (match_dup 2))])]
4829   "TARGET_80387"
4830 {
4831   if (flag_unsafe_math_optimizations)
4832     {
4833       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4834       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4835       if (reg != operands[0])
4836         emit_move_insn (operands[0], reg);
4837       DONE;
4838     }
4839   else
4840     {
4841      enum ix86_stack_slot slot = (virtuals_instantiated
4842                                   ? SLOT_TEMP
4843                                   : SLOT_VIRTUAL);
4844       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4845     }
4846 })
4847
4848 (define_insn "*truncxfsf2_mixed"
4849   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4850         (float_truncate:SF
4851           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4852    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4853   "TARGET_80387"
4854 {
4855   gcc_assert (!which_alternative);
4856   return output_387_reg_move (insn, operands);
4857 }
4858   [(set_attr "type" "fmov,multi,multi,multi")
4859    (set_attr "unit" "*,i387,i387,i387")
4860    (set_attr "mode" "SF")])
4861
4862 (define_insn "*truncxfdf2_mixed"
4863   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4864         (float_truncate:DF
4865           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4866    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4867   "TARGET_80387"
4868 {
4869   gcc_assert (!which_alternative);
4870   return output_387_reg_move (insn, operands);
4871 }
4872   [(set_attr "type" "fmov,multi,multi,multi")
4873    (set_attr "unit" "*,i387,i387,i387")
4874    (set_attr "mode" "DF")])
4875
4876 (define_insn "truncxf<mode>2_i387_noop"
4877   [(set (match_operand:MODEF 0 "register_operand" "=f")
4878         (float_truncate:MODEF
4879           (match_operand:XF 1 "register_operand" "f")))]
4880   "TARGET_80387 && flag_unsafe_math_optimizations"
4881   "* return output_387_reg_move (insn, operands);"
4882   [(set_attr "type" "fmov")
4883    (set_attr "mode" "<MODE>")])
4884
4885 (define_insn "*truncxf<mode>2_i387"
4886   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4887         (float_truncate:MODEF
4888           (match_operand:XF 1 "register_operand" "f")))]
4889   "TARGET_80387"
4890   "* return output_387_reg_move (insn, operands);"
4891   [(set_attr "type" "fmov")
4892    (set_attr "mode" "<MODE>")])
4893
4894 (define_split
4895   [(set (match_operand:MODEF 0 "register_operand" "")
4896         (float_truncate:MODEF
4897           (match_operand:XF 1 "register_operand" "")))
4898    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4899   "TARGET_80387 && reload_completed"
4900   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4901    (set (match_dup 0) (match_dup 2))]
4902   "")
4903
4904 (define_split
4905   [(set (match_operand:MODEF 0 "memory_operand" "")
4906         (float_truncate:MODEF
4907           (match_operand:XF 1 "register_operand" "")))
4908    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4909   "TARGET_80387"
4910   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4911   "")
4912 \f
4913 ;; Signed conversion to DImode.
4914
4915 (define_expand "fix_truncxfdi2"
4916   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4918               (clobber (reg:CC FLAGS_REG))])]
4919   "TARGET_80387"
4920 {
4921   if (TARGET_FISTTP)
4922    {
4923      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4924      DONE;
4925    }
4926 })
4927
4928 (define_expand "fix_trunc<mode>di2"
4929   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4930                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4931               (clobber (reg:CC FLAGS_REG))])]
4932   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4933 {
4934   if (TARGET_FISTTP
4935       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4936    {
4937      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4938      DONE;
4939    }
4940   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4941    {
4942      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4943      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4944      if (out != operands[0])
4945         emit_move_insn (operands[0], out);
4946      DONE;
4947    }
4948 })
4949
4950 ;; Signed conversion to SImode.
4951
4952 (define_expand "fix_truncxfsi2"
4953   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4954                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4955               (clobber (reg:CC FLAGS_REG))])]
4956   "TARGET_80387"
4957 {
4958   if (TARGET_FISTTP)
4959    {
4960      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4961      DONE;
4962    }
4963 })
4964
4965 (define_expand "fix_trunc<mode>si2"
4966   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4967                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4968               (clobber (reg:CC FLAGS_REG))])]
4969   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4970 {
4971   if (TARGET_FISTTP
4972       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4973    {
4974      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4975      DONE;
4976    }
4977   if (SSE_FLOAT_MODE_P (<MODE>mode))
4978    {
4979      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4980      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4981      if (out != operands[0])
4982         emit_move_insn (operands[0], out);
4983      DONE;
4984    }
4985 })
4986
4987 ;; Signed conversion to HImode.
4988
4989 (define_expand "fix_trunc<mode>hi2"
4990   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4991                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4992               (clobber (reg:CC FLAGS_REG))])]
4993   "TARGET_80387
4994    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4995 {
4996   if (TARGET_FISTTP)
4997    {
4998      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4999      DONE;
5000    }
5001 })
5002
5003 ;; Unsigned conversion to SImode.
5004
5005 (define_expand "fixuns_trunc<mode>si2"
5006   [(parallel
5007     [(set (match_operand:SI 0 "register_operand" "")
5008           (unsigned_fix:SI
5009             (match_operand:MODEF 1 "nonimmediate_operand" "")))
5010      (use (match_dup 2))
5011      (clobber (match_scratch:<ssevecmode> 3 ""))
5012      (clobber (match_scratch:<ssevecmode> 4 ""))])]
5013   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5014 {
5015   enum machine_mode mode = <MODE>mode;
5016   enum machine_mode vecmode = <ssevecmode>mode;
5017   REAL_VALUE_TYPE TWO31r;
5018   rtx two31;
5019
5020   if (optimize_insn_for_size_p ())
5021     FAIL;
5022
5023   real_ldexp (&TWO31r, &dconst1, 31);
5024   two31 = const_double_from_real_value (TWO31r, mode);
5025   two31 = ix86_build_const_vector (mode, true, two31);
5026   operands[2] = force_reg (vecmode, two31);
5027 })
5028
5029 (define_insn_and_split "*fixuns_trunc<mode>_1"
5030   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5031         (unsigned_fix:SI
5032           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5033    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5034    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5035    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5036   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5037    && optimize_function_for_speed_p (cfun)"
5038   "#"
5039   "&& reload_completed"
5040   [(const_int 0)]
5041 {
5042   ix86_split_convert_uns_si_sse (operands);
5043   DONE;
5044 })
5045
5046 ;; Unsigned conversion to HImode.
5047 ;; Without these patterns, we'll try the unsigned SI conversion which
5048 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5049
5050 (define_expand "fixuns_trunc<mode>hi2"
5051   [(set (match_dup 2)
5052         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5053    (set (match_operand:HI 0 "nonimmediate_operand" "")
5054         (subreg:HI (match_dup 2) 0))]
5055   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5056   "operands[2] = gen_reg_rtx (SImode);")
5057
5058 ;; When SSE is available, it is always faster to use it!
5059 (define_insn "fix_trunc<mode>di_sse"
5060   [(set (match_operand:DI 0 "register_operand" "=r,r")
5061         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5062   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5063    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5064   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5065   [(set_attr "type" "sseicvt")
5066    (set_attr "prefix" "maybe_vex")
5067    (set_attr "prefix_rex" "1")
5068    (set_attr "mode" "<MODE>")
5069    (set_attr "athlon_decode" "double,vector")
5070    (set_attr "amdfam10_decode" "double,double")])
5071
5072 (define_insn "fix_trunc<mode>si_sse"
5073   [(set (match_operand:SI 0 "register_operand" "=r,r")
5074         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5075   "SSE_FLOAT_MODE_P (<MODE>mode)
5076    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5077   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5078   [(set_attr "type" "sseicvt")
5079    (set_attr "prefix" "maybe_vex")
5080    (set_attr "mode" "<MODE>")
5081    (set_attr "athlon_decode" "double,vector")
5082    (set_attr "amdfam10_decode" "double,double")])
5083
5084 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5085 (define_peephole2
5086   [(set (match_operand:MODEF 0 "register_operand" "")
5087         (match_operand:MODEF 1 "memory_operand" ""))
5088    (set (match_operand:SSEMODEI24 2 "register_operand" "")
5089         (fix:SSEMODEI24 (match_dup 0)))]
5090   "TARGET_SHORTEN_X87_SSE
5091    && peep2_reg_dead_p (2, operands[0])"
5092   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5093   "")
5094
5095 ;; Avoid vector decoded forms of the instruction.
5096 (define_peephole2
5097   [(match_scratch:DF 2 "Y2")
5098    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5099         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5100   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5101   [(set (match_dup 2) (match_dup 1))
5102    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5103   "")
5104
5105 (define_peephole2
5106   [(match_scratch:SF 2 "x")
5107    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5108         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5109   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5110   [(set (match_dup 2) (match_dup 1))
5111    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5112   "")
5113
5114 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5115   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5116         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5117   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5118    && TARGET_FISTTP
5119    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5120          && (TARGET_64BIT || <MODE>mode != DImode))
5121         && TARGET_SSE_MATH)
5122    && !(reload_completed || reload_in_progress)"
5123   "#"
5124   "&& 1"
5125   [(const_int 0)]
5126 {
5127   if (memory_operand (operands[0], VOIDmode))
5128     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5129   else
5130     {
5131       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5132       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5133                                                             operands[1],
5134                                                             operands[2]));
5135     }
5136   DONE;
5137 }
5138   [(set_attr "type" "fisttp")
5139    (set_attr "mode" "<MODE>")])
5140
5141 (define_insn "fix_trunc<mode>_i387_fisttp"
5142   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5143         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5144    (clobber (match_scratch:XF 2 "=&1f"))]
5145   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5146    && TARGET_FISTTP
5147    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5148          && (TARGET_64BIT || <MODE>mode != DImode))
5149         && TARGET_SSE_MATH)"
5150   "* return output_fix_trunc (insn, operands, 1);"
5151   [(set_attr "type" "fisttp")
5152    (set_attr "mode" "<MODE>")])
5153
5154 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5155   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5156         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5157    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5158    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5159   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5160    && TARGET_FISTTP
5161    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5162         && (TARGET_64BIT || <MODE>mode != DImode))
5163         && TARGET_SSE_MATH)"
5164   "#"
5165   [(set_attr "type" "fisttp")
5166    (set_attr "mode" "<MODE>")])
5167
5168 (define_split
5169   [(set (match_operand:X87MODEI 0 "register_operand" "")
5170         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5171    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5172    (clobber (match_scratch 3 ""))]
5173   "reload_completed"
5174   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5175               (clobber (match_dup 3))])
5176    (set (match_dup 0) (match_dup 2))]
5177   "")
5178
5179 (define_split
5180   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5181         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5182    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5183    (clobber (match_scratch 3 ""))]
5184   "reload_completed"
5185   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5186               (clobber (match_dup 3))])]
5187   "")
5188
5189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5190 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5191 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5192 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5193 ;; function in i386.c.
5194 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5195   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5196         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5197    (clobber (reg:CC FLAGS_REG))]
5198   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5199    && !TARGET_FISTTP
5200    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5201          && (TARGET_64BIT || <MODE>mode != DImode))
5202    && !(reload_completed || reload_in_progress)"
5203   "#"
5204   "&& 1"
5205   [(const_int 0)]
5206 {
5207   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5208
5209   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5210   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5211   if (memory_operand (operands[0], VOIDmode))
5212     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5213                                          operands[2], operands[3]));
5214   else
5215     {
5216       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5217       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5218                                                      operands[2], operands[3],
5219                                                      operands[4]));
5220     }
5221   DONE;
5222 }
5223   [(set_attr "type" "fistp")
5224    (set_attr "i387_cw" "trunc")
5225    (set_attr "mode" "<MODE>")])
5226
5227 (define_insn "fix_truncdi_i387"
5228   [(set (match_operand:DI 0 "memory_operand" "=m")
5229         (fix:DI (match_operand 1 "register_operand" "f")))
5230    (use (match_operand:HI 2 "memory_operand" "m"))
5231    (use (match_operand:HI 3 "memory_operand" "m"))
5232    (clobber (match_scratch:XF 4 "=&1f"))]
5233   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5234    && !TARGET_FISTTP
5235    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5236   "* return output_fix_trunc (insn, operands, 0);"
5237   [(set_attr "type" "fistp")
5238    (set_attr "i387_cw" "trunc")
5239    (set_attr "mode" "DI")])
5240
5241 (define_insn "fix_truncdi_i387_with_temp"
5242   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5243         (fix:DI (match_operand 1 "register_operand" "f,f")))
5244    (use (match_operand:HI 2 "memory_operand" "m,m"))
5245    (use (match_operand:HI 3 "memory_operand" "m,m"))
5246    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5247    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5248   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5249    && !TARGET_FISTTP
5250    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5251   "#"
5252   [(set_attr "type" "fistp")
5253    (set_attr "i387_cw" "trunc")
5254    (set_attr "mode" "DI")])
5255
5256 (define_split
5257   [(set (match_operand:DI 0 "register_operand" "")
5258         (fix:DI (match_operand 1 "register_operand" "")))
5259    (use (match_operand:HI 2 "memory_operand" ""))
5260    (use (match_operand:HI 3 "memory_operand" ""))
5261    (clobber (match_operand:DI 4 "memory_operand" ""))
5262    (clobber (match_scratch 5 ""))]
5263   "reload_completed"
5264   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5265               (use (match_dup 2))
5266               (use (match_dup 3))
5267               (clobber (match_dup 5))])
5268    (set (match_dup 0) (match_dup 4))]
5269   "")
5270
5271 (define_split
5272   [(set (match_operand:DI 0 "memory_operand" "")
5273         (fix:DI (match_operand 1 "register_operand" "")))
5274    (use (match_operand:HI 2 "memory_operand" ""))
5275    (use (match_operand:HI 3 "memory_operand" ""))
5276    (clobber (match_operand:DI 4 "memory_operand" ""))
5277    (clobber (match_scratch 5 ""))]
5278   "reload_completed"
5279   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5280               (use (match_dup 2))
5281               (use (match_dup 3))
5282               (clobber (match_dup 5))])]
5283   "")
5284
5285 (define_insn "fix_trunc<mode>_i387"
5286   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5287         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5288    (use (match_operand:HI 2 "memory_operand" "m"))
5289    (use (match_operand:HI 3 "memory_operand" "m"))]
5290   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5291    && !TARGET_FISTTP
5292    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5293   "* return output_fix_trunc (insn, operands, 0);"
5294   [(set_attr "type" "fistp")
5295    (set_attr "i387_cw" "trunc")
5296    (set_attr "mode" "<MODE>")])
5297
5298 (define_insn "fix_trunc<mode>_i387_with_temp"
5299   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5300         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5301    (use (match_operand:HI 2 "memory_operand" "m,m"))
5302    (use (match_operand:HI 3 "memory_operand" "m,m"))
5303    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5304   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5305    && !TARGET_FISTTP
5306    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5307   "#"
5308   [(set_attr "type" "fistp")
5309    (set_attr "i387_cw" "trunc")
5310    (set_attr "mode" "<MODE>")])
5311
5312 (define_split
5313   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5314         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5315    (use (match_operand:HI 2 "memory_operand" ""))
5316    (use (match_operand:HI 3 "memory_operand" ""))
5317    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5318   "reload_completed"
5319   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5320               (use (match_dup 2))
5321               (use (match_dup 3))])
5322    (set (match_dup 0) (match_dup 4))]
5323   "")
5324
5325 (define_split
5326   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5327         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5328    (use (match_operand:HI 2 "memory_operand" ""))
5329    (use (match_operand:HI 3 "memory_operand" ""))
5330    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5331   "reload_completed"
5332   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5333               (use (match_dup 2))
5334               (use (match_dup 3))])]
5335   "")
5336
5337 (define_insn "x86_fnstcw_1"
5338   [(set (match_operand:HI 0 "memory_operand" "=m")
5339         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5340   "TARGET_80387"
5341   "fnstcw\t%0"
5342   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5343    (set_attr "mode" "HI")
5344    (set_attr "unit" "i387")])
5345
5346 (define_insn "x86_fldcw_1"
5347   [(set (reg:HI FPCR_REG)
5348         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5349   "TARGET_80387"
5350   "fldcw\t%0"
5351   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5352    (set_attr "mode" "HI")
5353    (set_attr "unit" "i387")
5354    (set_attr "athlon_decode" "vector")
5355    (set_attr "amdfam10_decode" "vector")])
5356 \f
5357 ;; Conversion between fixed point and floating point.
5358
5359 ;; Even though we only accept memory inputs, the backend _really_
5360 ;; wants to be able to do this between registers.
5361
5362 (define_expand "floathi<mode>2"
5363   [(set (match_operand:X87MODEF 0 "register_operand" "")
5364         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5365   "TARGET_80387
5366    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5367        || TARGET_MIX_SSE_I387)"
5368   "")
5369
5370 ;; Pre-reload splitter to add memory clobber to the pattern.
5371 (define_insn_and_split "*floathi<mode>2_1"
5372   [(set (match_operand:X87MODEF 0 "register_operand" "")
5373         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5374   "TARGET_80387
5375    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5376        || TARGET_MIX_SSE_I387)
5377    && !(reload_completed || reload_in_progress)"
5378   "#"
5379   "&& 1"
5380   [(parallel [(set (match_dup 0)
5381               (float:X87MODEF (match_dup 1)))
5382    (clobber (match_dup 2))])]
5383   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5384
5385 (define_insn "*floathi<mode>2_i387_with_temp"
5386   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5387         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5388   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5389   "TARGET_80387
5390    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5391        || TARGET_MIX_SSE_I387)"
5392   "#"
5393   [(set_attr "type" "fmov,multi")
5394    (set_attr "mode" "<MODE>")
5395    (set_attr "unit" "*,i387")
5396    (set_attr "fp_int_src" "true")])
5397
5398 (define_insn "*floathi<mode>2_i387"
5399   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5400         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5401   "TARGET_80387
5402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5403        || TARGET_MIX_SSE_I387)"
5404   "fild%Z1\t%1"
5405   [(set_attr "type" "fmov")
5406    (set_attr "mode" "<MODE>")
5407    (set_attr "fp_int_src" "true")])
5408
5409 (define_split
5410   [(set (match_operand:X87MODEF 0 "register_operand" "")
5411         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5412    (clobber (match_operand:HI 2 "memory_operand" ""))]
5413   "TARGET_80387
5414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5415        || TARGET_MIX_SSE_I387)
5416    && reload_completed"
5417   [(set (match_dup 2) (match_dup 1))
5418    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5419   "")
5420
5421 (define_split
5422   [(set (match_operand:X87MODEF 0 "register_operand" "")
5423         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5424    (clobber (match_operand:HI 2 "memory_operand" ""))]
5425    "TARGET_80387
5426     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5427         || TARGET_MIX_SSE_I387)
5428     && reload_completed"
5429   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5430   "")
5431
5432 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5433   [(set (match_operand:X87MODEF 0 "register_operand" "")
5434         (float:X87MODEF
5435           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5436   "TARGET_80387
5437    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5438        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5439   "
5440 {
5441   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5442         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5443       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5444     {
5445       rtx reg = gen_reg_rtx (XFmode);
5446       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5447 /* Avoid references to nonexistent function in dead code in XFmode case.  */
5448 #define gen_truncxfxf2 gen_truncxfdf2
5449       emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5450 #undef gen_truncxfxf2
5451       DONE;
5452     }
5453 }")
5454
5455 ;; Pre-reload splitter to add memory clobber to the pattern.
5456 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5457   [(set (match_operand:X87MODEF 0 "register_operand" "")
5458         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5459   "((TARGET_80387
5460      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5461      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5462            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5463          || TARGET_MIX_SSE_I387))
5464     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5465         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5466         && ((<SSEMODEI24:MODE>mode == SImode
5467              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5468              && optimize_function_for_speed_p (cfun)
5469              && flag_trapping_math)
5470             || !(TARGET_INTER_UNIT_CONVERSIONS
5471                  || optimize_function_for_size_p (cfun)))))
5472    && !(reload_completed || reload_in_progress)"
5473   "#"
5474   "&& 1"
5475   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5476               (clobber (match_dup 2))])]
5477 {
5478   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5479
5480   /* Avoid store forwarding (partial memory) stall penalty
5481      by passing DImode value through XMM registers.  */
5482   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5483       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5484       && optimize_function_for_speed_p (cfun))
5485     {
5486       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5487                                                             operands[1],
5488                                                             operands[2]));
5489       DONE;
5490     }
5491 })
5492
5493 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5494   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5495         (float:MODEF
5496           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5497    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5498   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5499    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5500   "#"
5501   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5502    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5503    (set_attr "unit" "*,i387,*,*,*")
5504    (set_attr "athlon_decode" "*,*,double,direct,double")
5505    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5506    (set_attr "fp_int_src" "true")])
5507
5508 (define_insn "*floatsi<mode>2_vector_mixed"
5509   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5510         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5511   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5512    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5513   "@
5514    fild%Z1\t%1
5515    #"
5516   [(set_attr "type" "fmov,sseicvt")
5517    (set_attr "mode" "<MODE>,<ssevecmode>")
5518    (set_attr "unit" "i387,*")
5519    (set_attr "athlon_decode" "*,direct")
5520    (set_attr "amdfam10_decode" "*,double")
5521    (set_attr "fp_int_src" "true")])
5522
5523 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5524   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5525         (float:MODEF
5526           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5527   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5528   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5529    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5530   "#"
5531   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5532    (set_attr "mode" "<MODEF:MODE>")
5533    (set_attr "unit" "*,i387,*,*")
5534    (set_attr "athlon_decode" "*,*,double,direct")
5535    (set_attr "amdfam10_decode" "*,*,vector,double")
5536    (set_attr "fp_int_src" "true")])
5537
5538 (define_split
5539   [(set (match_operand:MODEF 0 "register_operand" "")
5540         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5541    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5542   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5543    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5544    && TARGET_INTER_UNIT_CONVERSIONS
5545    && reload_completed
5546    && (SSE_REG_P (operands[0])
5547        || (GET_CODE (operands[0]) == SUBREG
5548            && SSE_REG_P (operands[0])))"
5549   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5550   "")
5551
5552 (define_split
5553   [(set (match_operand:MODEF 0 "register_operand" "")
5554         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5555    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5556   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5557    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5558    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5559    && reload_completed
5560    && (SSE_REG_P (operands[0])
5561        || (GET_CODE (operands[0]) == SUBREG
5562            && SSE_REG_P (operands[0])))"
5563   [(set (match_dup 2) (match_dup 1))
5564    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5565   "")
5566
5567 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5568   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5569         (float:MODEF
5570           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5571   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5572    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5573    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5574   "@
5575    fild%Z1\t%1
5576    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5577    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5578   [(set_attr "type" "fmov,sseicvt,sseicvt")
5579    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5580    (set_attr "mode" "<MODEF:MODE>")
5581    (set (attr "prefix_rex")
5582      (if_then_else
5583        (and (eq_attr "prefix" "maybe_vex")
5584             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5585        (const_string "1")
5586        (const_string "*")))
5587    (set_attr "unit" "i387,*,*")
5588    (set_attr "athlon_decode" "*,double,direct")
5589    (set_attr "amdfam10_decode" "*,vector,double")
5590    (set_attr "fp_int_src" "true")])
5591
5592 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5593   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5594         (float:MODEF
5595           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5596   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5597    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5598    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5599   "@
5600    fild%Z1\t%1
5601    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5602   [(set_attr "type" "fmov,sseicvt")
5603    (set_attr "prefix" "orig,maybe_vex")
5604    (set_attr "mode" "<MODEF:MODE>")
5605    (set (attr "prefix_rex")
5606      (if_then_else
5607        (and (eq_attr "prefix" "maybe_vex")
5608             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5609        (const_string "1")
5610        (const_string "*")))
5611    (set_attr "athlon_decode" "*,direct")
5612    (set_attr "amdfam10_decode" "*,double")
5613    (set_attr "fp_int_src" "true")])
5614
5615 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5616   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5617         (float:MODEF
5618           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5619    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5620   "TARGET_SSE2 && TARGET_SSE_MATH
5621    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5622   "#"
5623   [(set_attr "type" "sseicvt")
5624    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5625    (set_attr "athlon_decode" "double,direct,double")
5626    (set_attr "amdfam10_decode" "vector,double,double")
5627    (set_attr "fp_int_src" "true")])
5628
5629 (define_insn "*floatsi<mode>2_vector_sse"
5630   [(set (match_operand:MODEF 0 "register_operand" "=x")
5631         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5632   "TARGET_SSE2 && TARGET_SSE_MATH
5633    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5634   "#"
5635   [(set_attr "type" "sseicvt")
5636    (set_attr "mode" "<MODE>")
5637    (set_attr "athlon_decode" "direct")
5638    (set_attr "amdfam10_decode" "double")
5639    (set_attr "fp_int_src" "true")])
5640
5641 (define_split
5642   [(set (match_operand:MODEF 0 "register_operand" "")
5643         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5644    (clobber (match_operand:SI 2 "memory_operand" ""))]
5645   "TARGET_SSE2 && TARGET_SSE_MATH
5646    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5647    && reload_completed
5648    && (SSE_REG_P (operands[0])
5649        || (GET_CODE (operands[0]) == SUBREG
5650            && SSE_REG_P (operands[0])))"
5651   [(const_int 0)]
5652 {
5653   rtx op1 = operands[1];
5654
5655   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5656                                      <MODE>mode, 0);
5657   if (GET_CODE (op1) == SUBREG)
5658     op1 = SUBREG_REG (op1);
5659
5660   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5661     {
5662       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5663       emit_insn (gen_sse2_loadld (operands[4],
5664                                   CONST0_RTX (V4SImode), operands[1]));
5665     }
5666   /* We can ignore possible trapping value in the
5667      high part of SSE register for non-trapping math. */
5668   else if (SSE_REG_P (op1) && !flag_trapping_math)
5669     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5670   else
5671     {
5672       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5673       emit_move_insn (operands[2], operands[1]);
5674       emit_insn (gen_sse2_loadld (operands[4],
5675                                   CONST0_RTX (V4SImode), operands[2]));
5676     }
5677   emit_insn
5678     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5679   DONE;
5680 })
5681
5682 (define_split
5683   [(set (match_operand:MODEF 0 "register_operand" "")
5684         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5685    (clobber (match_operand:SI 2 "memory_operand" ""))]
5686   "TARGET_SSE2 && TARGET_SSE_MATH
5687    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5688    && reload_completed
5689    && (SSE_REG_P (operands[0])
5690        || (GET_CODE (operands[0]) == SUBREG
5691            && SSE_REG_P (operands[0])))"
5692   [(const_int 0)]
5693 {
5694   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5695                                      <MODE>mode, 0);
5696   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5697
5698   emit_insn (gen_sse2_loadld (operands[4],
5699                               CONST0_RTX (V4SImode), operands[1]));
5700   emit_insn
5701     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5702   DONE;
5703 })
5704
5705 (define_split
5706   [(set (match_operand:MODEF 0 "register_operand" "")
5707         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5708   "TARGET_SSE2 && TARGET_SSE_MATH
5709    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5710    && reload_completed
5711    && (SSE_REG_P (operands[0])
5712        || (GET_CODE (operands[0]) == SUBREG
5713            && SSE_REG_P (operands[0])))"
5714   [(const_int 0)]
5715 {
5716   rtx op1 = operands[1];
5717
5718   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5719                                      <MODE>mode, 0);
5720   if (GET_CODE (op1) == SUBREG)
5721     op1 = SUBREG_REG (op1);
5722
5723   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5724     {
5725       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5726       emit_insn (gen_sse2_loadld (operands[4],
5727                                   CONST0_RTX (V4SImode), operands[1]));
5728     }
5729   /* We can ignore possible trapping value in the
5730      high part of SSE register for non-trapping math. */
5731   else if (SSE_REG_P (op1) && !flag_trapping_math)
5732     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5733   else
5734     gcc_unreachable ();
5735   emit_insn
5736     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5737   DONE;
5738 })
5739
5740 (define_split
5741   [(set (match_operand:MODEF 0 "register_operand" "")
5742         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5743   "TARGET_SSE2 && TARGET_SSE_MATH
5744    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5745    && reload_completed
5746    && (SSE_REG_P (operands[0])
5747        || (GET_CODE (operands[0]) == SUBREG
5748            && SSE_REG_P (operands[0])))"
5749   [(const_int 0)]
5750 {
5751   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5752                                      <MODE>mode, 0);
5753   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5754
5755   emit_insn (gen_sse2_loadld (operands[4],
5756                               CONST0_RTX (V4SImode), operands[1]));
5757   emit_insn
5758     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5759   DONE;
5760 })
5761
5762 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5763   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5764         (float:MODEF
5765           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5766   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5767   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5768    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5769   "#"
5770   [(set_attr "type" "sseicvt")
5771    (set_attr "mode" "<MODEF:MODE>")
5772    (set_attr "athlon_decode" "double,direct")
5773    (set_attr "amdfam10_decode" "vector,double")
5774    (set_attr "fp_int_src" "true")])
5775
5776 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5777   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5778         (float:MODEF
5779           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5780   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5781    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5782    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5783   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5784   [(set_attr "type" "sseicvt")
5785    (set_attr "prefix" "maybe_vex")
5786    (set_attr "mode" "<MODEF:MODE>")
5787    (set (attr "prefix_rex")
5788      (if_then_else
5789        (and (eq_attr "prefix" "maybe_vex")
5790             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5791        (const_string "1")
5792        (const_string "*")))
5793    (set_attr "athlon_decode" "double,direct")
5794    (set_attr "amdfam10_decode" "vector,double")
5795    (set_attr "fp_int_src" "true")])
5796
5797 (define_split
5798   [(set (match_operand:MODEF 0 "register_operand" "")
5799         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5800    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5801   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5802    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5803    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5804    && reload_completed
5805    && (SSE_REG_P (operands[0])
5806        || (GET_CODE (operands[0]) == SUBREG
5807            && SSE_REG_P (operands[0])))"
5808   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5809   "")
5810
5811 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5812   [(set (match_operand:MODEF 0 "register_operand" "=x")
5813         (float:MODEF
5814           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5815   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5816    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5817    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5818   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5819   [(set_attr "type" "sseicvt")
5820    (set_attr "prefix" "maybe_vex")
5821    (set_attr "mode" "<MODEF:MODE>")
5822    (set (attr "prefix_rex")
5823      (if_then_else
5824        (and (eq_attr "prefix" "maybe_vex")
5825             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5826        (const_string "1")
5827        (const_string "*")))
5828    (set_attr "athlon_decode" "direct")
5829    (set_attr "amdfam10_decode" "double")
5830    (set_attr "fp_int_src" "true")])
5831
5832 (define_split
5833   [(set (match_operand:MODEF 0 "register_operand" "")
5834         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5835    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5836   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5837    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5838    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5839    && reload_completed
5840    && (SSE_REG_P (operands[0])
5841        || (GET_CODE (operands[0]) == SUBREG
5842            && SSE_REG_P (operands[0])))"
5843   [(set (match_dup 2) (match_dup 1))
5844    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5845   "")
5846
5847 (define_split
5848   [(set (match_operand:MODEF 0 "register_operand" "")
5849         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5850    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5851   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5852    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5853    && reload_completed
5854    && (SSE_REG_P (operands[0])
5855        || (GET_CODE (operands[0]) == SUBREG
5856            && SSE_REG_P (operands[0])))"
5857   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5858   "")
5859
5860 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5861   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5862         (float:X87MODEF
5863           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5864   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5865   "TARGET_80387
5866    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5867   "@
5868    fild%Z1\t%1
5869    #"
5870   [(set_attr "type" "fmov,multi")
5871    (set_attr "mode" "<X87MODEF:MODE>")
5872    (set_attr "unit" "*,i387")
5873    (set_attr "fp_int_src" "true")])
5874
5875 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5876   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5877         (float:X87MODEF
5878           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5879   "TARGET_80387
5880    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5881   "fild%Z1\t%1"
5882   [(set_attr "type" "fmov")
5883    (set_attr "mode" "<X87MODEF:MODE>")
5884    (set_attr "fp_int_src" "true")])
5885
5886 (define_split
5887   [(set (match_operand:X87MODEF 0 "register_operand" "")
5888         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5889    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5890   "TARGET_80387
5891    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5892    && reload_completed
5893    && FP_REG_P (operands[0])"
5894   [(set (match_dup 2) (match_dup 1))
5895    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5896   "")
5897
5898 (define_split
5899   [(set (match_operand:X87MODEF 0 "register_operand" "")
5900         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5901    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5902   "TARGET_80387
5903    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5904    && reload_completed
5905    && FP_REG_P (operands[0])"
5906   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5907   "")
5908
5909 ;; Avoid store forwarding (partial memory) stall penalty
5910 ;; by passing DImode value through XMM registers.  */
5911
5912 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5913   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5914         (float:X87MODEF
5915           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5916    (clobber (match_scratch:V4SI 3 "=X,x"))
5917    (clobber (match_scratch:V4SI 4 "=X,x"))
5918    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5919   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5920    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5921    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5922   "#"
5923   [(set_attr "type" "multi")
5924    (set_attr "mode" "<X87MODEF:MODE>")
5925    (set_attr "unit" "i387")
5926    (set_attr "fp_int_src" "true")])
5927
5928 (define_split
5929   [(set (match_operand:X87MODEF 0 "register_operand" "")
5930         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5931    (clobber (match_scratch:V4SI 3 ""))
5932    (clobber (match_scratch:V4SI 4 ""))
5933    (clobber (match_operand:DI 2 "memory_operand" ""))]
5934   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5935    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5936    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5937    && reload_completed
5938    && FP_REG_P (operands[0])"
5939   [(set (match_dup 2) (match_dup 3))
5940    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5941 {
5942   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5943      Assemble the 64-bit DImode value in an xmm register.  */
5944   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5945                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5946   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5947                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5948   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5949
5950   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5951 })
5952
5953 (define_split
5954   [(set (match_operand:X87MODEF 0 "register_operand" "")
5955         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5956    (clobber (match_scratch:V4SI 3 ""))
5957    (clobber (match_scratch:V4SI 4 ""))
5958    (clobber (match_operand:DI 2 "memory_operand" ""))]
5959   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5960    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5961    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5962    && reload_completed
5963    && FP_REG_P (operands[0])"
5964   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5965   "")
5966
5967 ;; Avoid store forwarding (partial memory) stall penalty by extending
5968 ;; SImode value to DImode through XMM register instead of pushing two
5969 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5970 ;; targets benefit from this optimization. Also note that fild
5971 ;; loads from memory only.
5972
5973 (define_insn "*floatunssi<mode>2_1"
5974   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5975         (unsigned_float:X87MODEF
5976           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5977    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5978    (clobber (match_scratch:SI 3 "=X,x"))]
5979   "!TARGET_64BIT
5980    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5981    && TARGET_SSE"
5982   "#"
5983   [(set_attr "type" "multi")
5984    (set_attr "mode" "<MODE>")])
5985
5986 (define_split
5987   [(set (match_operand:X87MODEF 0 "register_operand" "")
5988         (unsigned_float:X87MODEF
5989           (match_operand:SI 1 "register_operand" "")))
5990    (clobber (match_operand:DI 2 "memory_operand" ""))
5991    (clobber (match_scratch:SI 3 ""))]
5992   "!TARGET_64BIT
5993    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5994    && TARGET_SSE
5995    && reload_completed"
5996   [(set (match_dup 2) (match_dup 1))
5997    (set (match_dup 0)
5998         (float:X87MODEF (match_dup 2)))]
5999   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6000
6001 (define_split
6002   [(set (match_operand:X87MODEF 0 "register_operand" "")
6003         (unsigned_float:X87MODEF
6004           (match_operand:SI 1 "memory_operand" "")))
6005    (clobber (match_operand:DI 2 "memory_operand" ""))
6006    (clobber (match_scratch:SI 3 ""))]
6007   "!TARGET_64BIT
6008    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6009    && TARGET_SSE
6010    && reload_completed"
6011   [(set (match_dup 2) (match_dup 3))
6012    (set (match_dup 0)
6013         (float:X87MODEF (match_dup 2)))]
6014 {
6015   emit_move_insn (operands[3], operands[1]);
6016   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6017 })
6018
6019 (define_expand "floatunssi<mode>2"
6020   [(parallel
6021      [(set (match_operand:X87MODEF 0 "register_operand" "")
6022            (unsigned_float:X87MODEF
6023              (match_operand:SI 1 "nonimmediate_operand" "")))
6024       (clobber (match_dup 2))
6025       (clobber (match_scratch:SI 3 ""))])]
6026   "!TARGET_64BIT
6027    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6028         && TARGET_SSE)
6029        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6030 {
6031   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6032     {
6033       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6034       DONE;
6035     }
6036   else
6037     {
6038       enum ix86_stack_slot slot = (virtuals_instantiated
6039                                    ? SLOT_TEMP
6040                                    : SLOT_VIRTUAL);
6041       operands[2] = assign_386_stack_local (DImode, slot);
6042     }
6043 })
6044
6045 (define_expand "floatunsdisf2"
6046   [(use (match_operand:SF 0 "register_operand" ""))
6047    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6048   "TARGET_64BIT && TARGET_SSE_MATH"
6049   "x86_emit_floatuns (operands); DONE;")
6050
6051 (define_expand "floatunsdidf2"
6052   [(use (match_operand:DF 0 "register_operand" ""))
6053    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6054   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6055    && TARGET_SSE2 && TARGET_SSE_MATH"
6056 {
6057   if (TARGET_64BIT)
6058     x86_emit_floatuns (operands);
6059   else
6060     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6061   DONE;
6062 })
6063 \f
6064 ;; Add instructions
6065
6066 ;; %%% splits for addditi3
6067
6068 (define_expand "addti3"
6069   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6070         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6071                  (match_operand:TI 2 "x86_64_general_operand" "")))]
6072   "TARGET_64BIT"
6073   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
6074
6075 (define_insn "*addti3_1"
6076   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6077         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
6078                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6079    (clobber (reg:CC FLAGS_REG))]
6080   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
6081   "#")
6082
6083 (define_split
6084   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6085         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6086                  (match_operand:TI 2 "x86_64_general_operand" "")))
6087    (clobber (reg:CC FLAGS_REG))]
6088   "TARGET_64BIT && reload_completed"
6089   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6090                                           UNSPEC_ADD_CARRY))
6091               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
6092    (parallel [(set (match_dup 3)
6093                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6094                                      (match_dup 4))
6095                             (match_dup 5)))
6096               (clobber (reg:CC FLAGS_REG))])]
6097   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
6098
6099 ;; %%% splits for addsidi3
6100 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6101 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
6102 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
6103
6104 (define_expand "adddi3"
6105   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6106         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6107                  (match_operand:DI 2 "x86_64_general_operand" "")))]
6108   ""
6109   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
6110
6111 (define_insn "*adddi3_1"
6112   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6113         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6114                  (match_operand:DI 2 "general_operand" "roiF,riF")))
6115    (clobber (reg:CC FLAGS_REG))]
6116   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6117   "#")
6118
6119 (define_split
6120   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6121         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6122                  (match_operand:DI 2 "general_operand" "")))
6123    (clobber (reg:CC FLAGS_REG))]
6124   "!TARGET_64BIT && reload_completed"
6125   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6126                                           UNSPEC_ADD_CARRY))
6127               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
6128    (parallel [(set (match_dup 3)
6129                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6130                                      (match_dup 4))
6131                             (match_dup 5)))
6132               (clobber (reg:CC FLAGS_REG))])]
6133   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
6134
6135 (define_insn "adddi3_carry_rex64"
6136   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6137           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6138                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
6139                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6140    (clobber (reg:CC FLAGS_REG))]
6141   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6142   "adc{q}\t{%2, %0|%0, %2}"
6143   [(set_attr "type" "alu")
6144    (set_attr "use_carry" "1")
6145    (set_attr "pent_pair" "pu")
6146    (set_attr "mode" "DI")])
6147
6148 (define_insn "*adddi3_cc_rex64"
6149   [(set (reg:CC FLAGS_REG)
6150         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
6151                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
6152                    UNSPEC_ADD_CARRY))
6153    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6154         (plus:DI (match_dup 1) (match_dup 2)))]
6155   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6156   "add{q}\t{%2, %0|%0, %2}"
6157   [(set_attr "type" "alu")
6158    (set_attr "mode" "DI")])
6159
6160 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6161   [(set (reg:CCC FLAGS_REG)
6162         (compare:CCC
6163             (plusminus:SWI
6164                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6165                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6166             (match_dup 1)))
6167    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6168         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6169   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6170   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6171   [(set_attr "type" "alu")
6172    (set_attr "mode" "<MODE>")])
6173
6174 (define_insn "*add<mode>3_cconly_overflow"
6175   [(set (reg:CCC FLAGS_REG)
6176         (compare:CCC
6177                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
6178                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6179                 (match_dup 1)))
6180    (clobber (match_scratch:SWI 0 "=<r>"))]
6181   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6182   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6183   [(set_attr "type" "alu")
6184    (set_attr "mode" "<MODE>")])
6185
6186 (define_insn "*sub<mode>3_cconly_overflow"
6187   [(set (reg:CCC FLAGS_REG)
6188         (compare:CCC
6189              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6190                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6191              (match_dup 0)))]
6192   ""
6193   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6194   [(set_attr "type" "icmp")
6195    (set_attr "mode" "<MODE>")])
6196
6197 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6198   [(set (reg:CCC FLAGS_REG)
6199         (compare:CCC
6200             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6201                           (match_operand:SI 2 "general_operand" "g"))
6202             (match_dup 1)))
6203    (set (match_operand:DI 0 "register_operand" "=r")
6204         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6205   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6206   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6207   [(set_attr "type" "alu")
6208    (set_attr "mode" "SI")])
6209
6210 (define_insn "addqi3_carry"
6211   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6212           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6213                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
6214                    (match_operand:QI 2 "general_operand" "qn,qm")))
6215    (clobber (reg:CC FLAGS_REG))]
6216   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6217   "adc{b}\t{%2, %0|%0, %2}"
6218   [(set_attr "type" "alu")
6219    (set_attr "use_carry" "1")
6220    (set_attr "pent_pair" "pu")
6221    (set_attr "mode" "QI")])
6222
6223 (define_insn "addhi3_carry"
6224   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6225           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6226                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
6227                    (match_operand:HI 2 "general_operand" "rn,rm")))
6228    (clobber (reg:CC FLAGS_REG))]
6229   "ix86_binary_operator_ok (PLUS, HImode, operands)"
6230   "adc{w}\t{%2, %0|%0, %2}"
6231   [(set_attr "type" "alu")
6232    (set_attr "use_carry" "1")
6233    (set_attr "pent_pair" "pu")
6234    (set_attr "mode" "HI")])
6235
6236 (define_insn "addsi3_carry"
6237   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6238           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6239                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
6240                    (match_operand:SI 2 "general_operand" "ri,rm")))
6241    (clobber (reg:CC FLAGS_REG))]
6242   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6243   "adc{l}\t{%2, %0|%0, %2}"
6244   [(set_attr "type" "alu")
6245    (set_attr "use_carry" "1")
6246    (set_attr "pent_pair" "pu")
6247    (set_attr "mode" "SI")])
6248
6249 (define_insn "*addsi3_carry_zext"
6250   [(set (match_operand:DI 0 "register_operand" "=r")
6251           (zero_extend:DI
6252             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6253                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
6254                      (match_operand:SI 2 "general_operand" "g"))))
6255    (clobber (reg:CC FLAGS_REG))]
6256   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6257   "adc{l}\t{%2, %k0|%k0, %2}"
6258   [(set_attr "type" "alu")
6259    (set_attr "use_carry" "1")
6260    (set_attr "pent_pair" "pu")
6261    (set_attr "mode" "SI")])
6262
6263 (define_insn "*addsi3_cc"
6264   [(set (reg:CC FLAGS_REG)
6265         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
6266                     (match_operand:SI 2 "general_operand" "ri,rm")]
6267                    UNSPEC_ADD_CARRY))
6268    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6269         (plus:SI (match_dup 1) (match_dup 2)))]
6270   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6271   "add{l}\t{%2, %0|%0, %2}"
6272   [(set_attr "type" "alu")
6273    (set_attr "mode" "SI")])
6274
6275 (define_insn "addqi3_cc"
6276   [(set (reg:CC FLAGS_REG)
6277         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6278                     (match_operand:QI 2 "general_operand" "qn,qm")]
6279                    UNSPEC_ADD_CARRY))
6280    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6281         (plus:QI (match_dup 1) (match_dup 2)))]
6282   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6283   "add{b}\t{%2, %0|%0, %2}"
6284   [(set_attr "type" "alu")
6285    (set_attr "mode" "QI")])
6286
6287 (define_expand "addsi3"
6288   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6289         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6290                  (match_operand:SI 2 "general_operand" "")))]
6291   ""
6292   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6293
6294 (define_insn "*lea_1"
6295   [(set (match_operand:SI 0 "register_operand" "=r")
6296         (match_operand:SI 1 "no_seg_address_operand" "p"))]
6297   "!TARGET_64BIT"
6298   "lea{l}\t{%a1, %0|%0, %a1}"
6299   [(set_attr "type" "lea")
6300    (set_attr "mode" "SI")])
6301
6302 (define_insn "*lea_1_rex64"
6303   [(set (match_operand:SI 0 "register_operand" "=r")
6304         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6305   "TARGET_64BIT"
6306   "lea{l}\t{%a1, %0|%0, %a1}"
6307   [(set_attr "type" "lea")
6308    (set_attr "mode" "SI")])
6309
6310 (define_insn "*lea_1_zext"
6311   [(set (match_operand:DI 0 "register_operand" "=r")
6312         (zero_extend:DI
6313          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6314   "TARGET_64BIT"
6315   "lea{l}\t{%a1, %k0|%k0, %a1}"
6316   [(set_attr "type" "lea")
6317    (set_attr "mode" "SI")])
6318
6319 (define_insn "*lea_2_rex64"
6320   [(set (match_operand:DI 0 "register_operand" "=r")
6321         (match_operand:DI 1 "no_seg_address_operand" "p"))]
6322   "TARGET_64BIT"
6323   "lea{q}\t{%a1, %0|%0, %a1}"
6324   [(set_attr "type" "lea")
6325    (set_attr "mode" "DI")])
6326
6327 ;; The lea patterns for non-Pmodes needs to be matched by several
6328 ;; insns converted to real lea by splitters.
6329
6330 (define_insn_and_split "*lea_general_1"
6331   [(set (match_operand 0 "register_operand" "=r")
6332         (plus (plus (match_operand 1 "index_register_operand" "l")
6333                     (match_operand 2 "register_operand" "r"))
6334               (match_operand 3 "immediate_operand" "i")))]
6335   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6336     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6337    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6338    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6339    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6340    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6341        || GET_MODE (operands[3]) == VOIDmode)"
6342   "#"
6343   "&& reload_completed"
6344   [(const_int 0)]
6345 {
6346   rtx pat;
6347   operands[0] = gen_lowpart (SImode, operands[0]);
6348   operands[1] = gen_lowpart (Pmode, operands[1]);
6349   operands[2] = gen_lowpart (Pmode, operands[2]);
6350   operands[3] = gen_lowpart (Pmode, operands[3]);
6351   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6352                       operands[3]);
6353   if (Pmode != SImode)
6354     pat = gen_rtx_SUBREG (SImode, pat, 0);
6355   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6356   DONE;
6357 }
6358   [(set_attr "type" "lea")
6359    (set_attr "mode" "SI")])
6360
6361 (define_insn_and_split "*lea_general_1_zext"
6362   [(set (match_operand:DI 0 "register_operand" "=r")
6363         (zero_extend:DI
6364           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6365                             (match_operand:SI 2 "register_operand" "r"))
6366                    (match_operand:SI 3 "immediate_operand" "i"))))]
6367   "TARGET_64BIT"
6368   "#"
6369   "&& reload_completed"
6370   [(set (match_dup 0)
6371         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6372                                                      (match_dup 2))
6373                                             (match_dup 3)) 0)))]
6374 {
6375   operands[1] = gen_lowpart (Pmode, operands[1]);
6376   operands[2] = gen_lowpart (Pmode, operands[2]);
6377   operands[3] = gen_lowpart (Pmode, operands[3]);
6378 }
6379   [(set_attr "type" "lea")
6380    (set_attr "mode" "SI")])
6381
6382 (define_insn_and_split "*lea_general_2"
6383   [(set (match_operand 0 "register_operand" "=r")
6384         (plus (mult (match_operand 1 "index_register_operand" "l")
6385                     (match_operand 2 "const248_operand" "i"))
6386               (match_operand 3 "nonmemory_operand" "ri")))]
6387   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6388     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6389    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6390    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6391    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6392        || GET_MODE (operands[3]) == VOIDmode)"
6393   "#"
6394   "&& reload_completed"
6395   [(const_int 0)]
6396 {
6397   rtx pat;
6398   operands[0] = gen_lowpart (SImode, operands[0]);
6399   operands[1] = gen_lowpart (Pmode, operands[1]);
6400   operands[3] = gen_lowpart (Pmode, operands[3]);
6401   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6402                       operands[3]);
6403   if (Pmode != SImode)
6404     pat = gen_rtx_SUBREG (SImode, pat, 0);
6405   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6406   DONE;
6407 }
6408   [(set_attr "type" "lea")
6409    (set_attr "mode" "SI")])
6410
6411 (define_insn_and_split "*lea_general_2_zext"
6412   [(set (match_operand:DI 0 "register_operand" "=r")
6413         (zero_extend:DI
6414           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6415                             (match_operand:SI 2 "const248_operand" "n"))
6416                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6417   "TARGET_64BIT"
6418   "#"
6419   "&& reload_completed"
6420   [(set (match_dup 0)
6421         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6422                                                      (match_dup 2))
6423                                             (match_dup 3)) 0)))]
6424 {
6425   operands[1] = gen_lowpart (Pmode, operands[1]);
6426   operands[3] = gen_lowpart (Pmode, operands[3]);
6427 }
6428   [(set_attr "type" "lea")
6429    (set_attr "mode" "SI")])
6430
6431 (define_insn_and_split "*lea_general_3"
6432   [(set (match_operand 0 "register_operand" "=r")
6433         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6434                           (match_operand 2 "const248_operand" "i"))
6435                     (match_operand 3 "register_operand" "r"))
6436               (match_operand 4 "immediate_operand" "i")))]
6437   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6438     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6439    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6440    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6441    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6442   "#"
6443   "&& reload_completed"
6444   [(const_int 0)]
6445 {
6446   rtx pat;
6447   operands[0] = gen_lowpart (SImode, operands[0]);
6448   operands[1] = gen_lowpart (Pmode, operands[1]);
6449   operands[3] = gen_lowpart (Pmode, operands[3]);
6450   operands[4] = gen_lowpart (Pmode, operands[4]);
6451   pat = gen_rtx_PLUS (Pmode,
6452                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6453                                                          operands[2]),
6454                                     operands[3]),
6455                       operands[4]);
6456   if (Pmode != SImode)
6457     pat = gen_rtx_SUBREG (SImode, pat, 0);
6458   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6459   DONE;
6460 }
6461   [(set_attr "type" "lea")
6462    (set_attr "mode" "SI")])
6463
6464 (define_insn_and_split "*lea_general_3_zext"
6465   [(set (match_operand:DI 0 "register_operand" "=r")
6466         (zero_extend:DI
6467           (plus:SI (plus:SI (mult:SI
6468                               (match_operand:SI 1 "index_register_operand" "l")
6469                               (match_operand:SI 2 "const248_operand" "n"))
6470                             (match_operand:SI 3 "register_operand" "r"))
6471                    (match_operand:SI 4 "immediate_operand" "i"))))]
6472   "TARGET_64BIT"
6473   "#"
6474   "&& reload_completed"
6475   [(set (match_dup 0)
6476         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6477                                                               (match_dup 2))
6478                                                      (match_dup 3))
6479                                             (match_dup 4)) 0)))]
6480 {
6481   operands[1] = gen_lowpart (Pmode, operands[1]);
6482   operands[3] = gen_lowpart (Pmode, operands[3]);
6483   operands[4] = gen_lowpart (Pmode, operands[4]);
6484 }
6485   [(set_attr "type" "lea")
6486    (set_attr "mode" "SI")])
6487
6488 (define_insn "*adddi_1_rex64"
6489   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6490         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6491                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6492    (clobber (reg:CC FLAGS_REG))]
6493   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6494 {
6495   switch (get_attr_type (insn))
6496     {
6497     case TYPE_LEA:
6498       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6499       return "lea{q}\t{%a2, %0|%0, %a2}";
6500
6501     case TYPE_INCDEC:
6502       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6503       if (operands[2] == const1_rtx)
6504         return "inc{q}\t%0";
6505       else
6506         {
6507           gcc_assert (operands[2] == constm1_rtx);
6508           return "dec{q}\t%0";
6509         }
6510
6511     default:
6512       /* Use add as much as possible to replace lea for AGU optimization. */
6513       if (which_alternative == 2 && TARGET_OPT_AGU)
6514         return "add{q}\t{%1, %0|%0, %1}";
6515         
6516       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6517
6518       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6519          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6520       if (CONST_INT_P (operands[2])
6521           /* Avoid overflows.  */
6522           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6523           && (INTVAL (operands[2]) == 128
6524               || (INTVAL (operands[2]) < 0
6525                   && INTVAL (operands[2]) != -128)))
6526         {
6527           operands[2] = GEN_INT (-INTVAL (operands[2]));
6528           return "sub{q}\t{%2, %0|%0, %2}";
6529         }
6530       return "add{q}\t{%2, %0|%0, %2}";
6531     }
6532 }
6533   [(set (attr "type")
6534      (cond [(and (eq_attr "alternative" "2") 
6535                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6536               (const_string "lea")
6537             (eq_attr "alternative" "3")
6538               (const_string "lea")
6539             ; Current assemblers are broken and do not allow @GOTOFF in
6540             ; ought but a memory context.
6541             (match_operand:DI 2 "pic_symbolic_operand" "")
6542               (const_string "lea")
6543             (match_operand:DI 2 "incdec_operand" "")
6544               (const_string "incdec")
6545            ]
6546            (const_string "alu")))
6547    (set (attr "length_immediate")
6548       (if_then_else
6549         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6550         (const_string "1")
6551         (const_string "*")))
6552    (set_attr "mode" "DI")])
6553
6554 ;; Convert lea to the lea pattern to avoid flags dependency.
6555 (define_split
6556   [(set (match_operand:DI 0 "register_operand" "")
6557         (plus:DI (match_operand:DI 1 "register_operand" "")
6558                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6559    (clobber (reg:CC FLAGS_REG))]
6560   "TARGET_64BIT && reload_completed 
6561    && ix86_lea_for_add_ok (PLUS, insn, operands)"
6562   [(set (match_dup 0)
6563         (plus:DI (match_dup 1)
6564                  (match_dup 2)))]
6565   "")
6566
6567 (define_insn "*adddi_2_rex64"
6568   [(set (reg FLAGS_REG)
6569         (compare
6570           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6571                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6572           (const_int 0)))
6573    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6574         (plus:DI (match_dup 1) (match_dup 2)))]
6575   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6576    && ix86_binary_operator_ok (PLUS, DImode, operands)
6577    /* Current assemblers are broken and do not allow @GOTOFF in
6578       ought but a memory context.  */
6579    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6580 {
6581   switch (get_attr_type (insn))
6582     {
6583     case TYPE_INCDEC:
6584       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6585       if (operands[2] == const1_rtx)
6586         return "inc{q}\t%0";
6587       else
6588         {
6589           gcc_assert (operands[2] == constm1_rtx);
6590           return "dec{q}\t%0";
6591         }
6592
6593     default:
6594       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6595       /* ???? We ought to handle there the 32bit case too
6596          - do we need new constraint?  */
6597       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6598          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6599       if (CONST_INT_P (operands[2])
6600           /* Avoid overflows.  */
6601           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6602           && (INTVAL (operands[2]) == 128
6603               || (INTVAL (operands[2]) < 0
6604                   && INTVAL (operands[2]) != -128)))
6605         {
6606           operands[2] = GEN_INT (-INTVAL (operands[2]));
6607           return "sub{q}\t{%2, %0|%0, %2}";
6608         }
6609       return "add{q}\t{%2, %0|%0, %2}";
6610     }
6611 }
6612   [(set (attr "type")
6613      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6614         (const_string "incdec")
6615         (const_string "alu")))
6616    (set (attr "length_immediate")
6617       (if_then_else
6618         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6619         (const_string "1")
6620         (const_string "*")))
6621    (set_attr "mode" "DI")])
6622
6623 (define_insn "*adddi_3_rex64"
6624   [(set (reg FLAGS_REG)
6625         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6626                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6627    (clobber (match_scratch:DI 0 "=r"))]
6628   "TARGET_64BIT
6629    && ix86_match_ccmode (insn, CCZmode)
6630    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6631    /* Current assemblers are broken and do not allow @GOTOFF in
6632       ought but a memory context.  */
6633    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6634 {
6635   switch (get_attr_type (insn))
6636     {
6637     case TYPE_INCDEC:
6638       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6639       if (operands[2] == const1_rtx)
6640         return "inc{q}\t%0";
6641       else
6642         {
6643           gcc_assert (operands[2] == constm1_rtx);
6644           return "dec{q}\t%0";
6645         }
6646
6647     default:
6648       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6649       /* ???? We ought to handle there the 32bit case too
6650          - do we need new constraint?  */
6651       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6652          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6653       if (CONST_INT_P (operands[2])
6654           /* Avoid overflows.  */
6655           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6656           && (INTVAL (operands[2]) == 128
6657               || (INTVAL (operands[2]) < 0
6658                   && INTVAL (operands[2]) != -128)))
6659         {
6660           operands[2] = GEN_INT (-INTVAL (operands[2]));
6661           return "sub{q}\t{%2, %0|%0, %2}";
6662         }
6663       return "add{q}\t{%2, %0|%0, %2}";
6664     }
6665 }
6666   [(set (attr "type")
6667      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6668         (const_string "incdec")
6669         (const_string "alu")))
6670    (set (attr "length_immediate")
6671       (if_then_else
6672         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6673         (const_string "1")
6674         (const_string "*")))
6675    (set_attr "mode" "DI")])
6676
6677 ; For comparisons against 1, -1 and 128, we may generate better code
6678 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6679 ; is matched then.  We can't accept general immediate, because for
6680 ; case of overflows,  the result is messed up.
6681 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6682 ; when negated.
6683 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6684 ; only for comparisons not depending on it.
6685 (define_insn "*adddi_4_rex64"
6686   [(set (reg FLAGS_REG)
6687         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6688                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6689    (clobber (match_scratch:DI 0 "=rm"))]
6690   "TARGET_64BIT
6691    &&  ix86_match_ccmode (insn, CCGCmode)"
6692 {
6693   switch (get_attr_type (insn))
6694     {
6695     case TYPE_INCDEC:
6696       if (operands[2] == constm1_rtx)
6697         return "inc{q}\t%0";
6698       else
6699         {
6700           gcc_assert (operands[2] == const1_rtx);
6701           return "dec{q}\t%0";
6702         }
6703
6704     default:
6705       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6706       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6707          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6708       if ((INTVAL (operands[2]) == -128
6709            || (INTVAL (operands[2]) > 0
6710                && INTVAL (operands[2]) != 128))
6711           /* Avoid overflows.  */
6712           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6713         return "sub{q}\t{%2, %0|%0, %2}";
6714       operands[2] = GEN_INT (-INTVAL (operands[2]));
6715       return "add{q}\t{%2, %0|%0, %2}";
6716     }
6717 }
6718   [(set (attr "type")
6719      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6720         (const_string "incdec")
6721         (const_string "alu")))
6722    (set (attr "length_immediate")
6723       (if_then_else
6724         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6725         (const_string "1")
6726         (const_string "*")))
6727    (set_attr "mode" "DI")])
6728
6729 (define_insn "*adddi_5_rex64"
6730   [(set (reg FLAGS_REG)
6731         (compare
6732           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6733                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6734           (const_int 0)))
6735    (clobber (match_scratch:DI 0 "=r"))]
6736   "TARGET_64BIT
6737    && ix86_match_ccmode (insn, CCGOCmode)
6738    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6739    /* Current assemblers are broken and do not allow @GOTOFF in
6740       ought but a memory context.  */
6741    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6742 {
6743   switch (get_attr_type (insn))
6744     {
6745     case TYPE_INCDEC:
6746       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6747       if (operands[2] == const1_rtx)
6748         return "inc{q}\t%0";
6749       else
6750         {
6751           gcc_assert (operands[2] == constm1_rtx);
6752           return "dec{q}\t%0";
6753         }
6754
6755     default:
6756       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6757       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6758          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6759       if (CONST_INT_P (operands[2])
6760           /* Avoid overflows.  */
6761           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6762           && (INTVAL (operands[2]) == 128
6763               || (INTVAL (operands[2]) < 0
6764                   && INTVAL (operands[2]) != -128)))
6765         {
6766           operands[2] = GEN_INT (-INTVAL (operands[2]));
6767           return "sub{q}\t{%2, %0|%0, %2}";
6768         }
6769       return "add{q}\t{%2, %0|%0, %2}";
6770     }
6771 }
6772   [(set (attr "type")
6773      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6774         (const_string "incdec")
6775         (const_string "alu")))
6776    (set (attr "length_immediate")
6777       (if_then_else
6778         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6779         (const_string "1")
6780         (const_string "*")))
6781    (set_attr "mode" "DI")])
6782
6783
6784 (define_insn "*addsi_1"
6785   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6786         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6787                  (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6790 {
6791   switch (get_attr_type (insn))
6792     {
6793     case TYPE_LEA:
6794       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6795       return "lea{l}\t{%a2, %0|%0, %a2}";
6796
6797     case TYPE_INCDEC:
6798       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6799       if (operands[2] == const1_rtx)
6800         return "inc{l}\t%0";
6801       else
6802         {
6803           gcc_assert (operands[2] == constm1_rtx);
6804           return "dec{l}\t%0";
6805         }
6806
6807     default:
6808       /* Use add as much as possible to replace lea for AGU optimization. */
6809       if (which_alternative == 2 && TARGET_OPT_AGU)
6810         return "add{l}\t{%1, %0|%0, %1}";
6811
6812       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6813
6814       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6815          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6816       if (CONST_INT_P (operands[2])
6817           && (INTVAL (operands[2]) == 128
6818               || (INTVAL (operands[2]) < 0
6819                   && INTVAL (operands[2]) != -128)))
6820         {
6821           operands[2] = GEN_INT (-INTVAL (operands[2]));
6822           return "sub{l}\t{%2, %0|%0, %2}";
6823         }
6824       return "add{l}\t{%2, %0|%0, %2}";
6825     }
6826 }
6827   [(set (attr "type")
6828      (cond [(and (eq_attr "alternative" "2") 
6829                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6830                (const_string "lea")
6831             (eq_attr "alternative" "3")
6832               (const_string "lea")
6833             ; Current assemblers are broken and do not allow @GOTOFF in
6834             ; ought but a memory context.
6835             (match_operand:SI 2 "pic_symbolic_operand" "")
6836               (const_string "lea")
6837             (match_operand:SI 2 "incdec_operand" "")
6838               (const_string "incdec")
6839            ]
6840            (const_string "alu")))
6841    (set (attr "length_immediate")
6842       (if_then_else
6843         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6844         (const_string "1")
6845         (const_string "*")))
6846    (set_attr "mode" "SI")])
6847
6848 ;; Convert lea to the lea pattern to avoid flags dependency.
6849 (define_split
6850   [(set (match_operand 0 "register_operand" "")
6851         (plus (match_operand 1 "register_operand" "")
6852               (match_operand 2 "nonmemory_operand" "")))
6853    (clobber (reg:CC FLAGS_REG))]
6854   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
6855   [(const_int 0)]
6856 {
6857   rtx pat;
6858   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6859      may confuse gen_lowpart.  */
6860   if (GET_MODE (operands[0]) != Pmode)
6861     {
6862       operands[1] = gen_lowpart (Pmode, operands[1]);
6863       operands[2] = gen_lowpart (Pmode, operands[2]);
6864     }
6865   operands[0] = gen_lowpart (SImode, operands[0]);
6866   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6867   if (Pmode != SImode)
6868     pat = gen_rtx_SUBREG (SImode, pat, 0);
6869   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6870   DONE;
6871 })
6872
6873 ;; It may seem that nonimmediate operand is proper one for operand 1.
6874 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6875 ;; we take care in ix86_binary_operator_ok to not allow two memory
6876 ;; operands so proper swapping will be done in reload.  This allow
6877 ;; patterns constructed from addsi_1 to match.
6878 (define_insn "addsi_1_zext"
6879   [(set (match_operand:DI 0 "register_operand" "=r,r")
6880         (zero_extend:DI
6881           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6882                    (match_operand:SI 2 "general_operand" "g,li"))))
6883    (clobber (reg:CC FLAGS_REG))]
6884   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6885 {
6886   switch (get_attr_type (insn))
6887     {
6888     case TYPE_LEA:
6889       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6890       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6891
6892     case TYPE_INCDEC:
6893       if (operands[2] == const1_rtx)
6894         return "inc{l}\t%k0";
6895       else
6896         {
6897           gcc_assert (operands[2] == constm1_rtx);
6898           return "dec{l}\t%k0";
6899         }
6900
6901     default:
6902       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6903          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6904       if (CONST_INT_P (operands[2])
6905           && (INTVAL (operands[2]) == 128
6906               || (INTVAL (operands[2]) < 0
6907                   && INTVAL (operands[2]) != -128)))
6908         {
6909           operands[2] = GEN_INT (-INTVAL (operands[2]));
6910           return "sub{l}\t{%2, %k0|%k0, %2}";
6911         }
6912       return "add{l}\t{%2, %k0|%k0, %2}";
6913     }
6914 }
6915   [(set (attr "type")
6916      (cond [(eq_attr "alternative" "1")
6917               (const_string "lea")
6918             ; Current assemblers are broken and do not allow @GOTOFF in
6919             ; ought but a memory context.
6920             (match_operand:SI 2 "pic_symbolic_operand" "")
6921               (const_string "lea")
6922             (match_operand:SI 2 "incdec_operand" "")
6923               (const_string "incdec")
6924            ]
6925            (const_string "alu")))
6926    (set (attr "length_immediate")
6927       (if_then_else
6928         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6929         (const_string "1")
6930         (const_string "*")))
6931    (set_attr "mode" "SI")])
6932
6933 ;; Convert lea to the lea pattern to avoid flags dependency.
6934 (define_split
6935   [(set (match_operand:DI 0 "register_operand" "")
6936         (zero_extend:DI
6937           (plus:SI (match_operand:SI 1 "register_operand" "")
6938                    (match_operand:SI 2 "nonmemory_operand" ""))))
6939    (clobber (reg:CC FLAGS_REG))]
6940   "TARGET_64BIT && reload_completed
6941    && true_regnum (operands[0]) != true_regnum (operands[1])"
6942   [(set (match_dup 0)
6943         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6944 {
6945   operands[1] = gen_lowpart (Pmode, operands[1]);
6946   operands[2] = gen_lowpart (Pmode, operands[2]);
6947 })
6948
6949 (define_insn "*addsi_2"
6950   [(set (reg FLAGS_REG)
6951         (compare
6952           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6953                    (match_operand:SI 2 "general_operand" "g,ri"))
6954           (const_int 0)))
6955    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6956         (plus:SI (match_dup 1) (match_dup 2)))]
6957   "ix86_match_ccmode (insn, CCGOCmode)
6958    && ix86_binary_operator_ok (PLUS, SImode, operands)
6959    /* Current assemblers are broken and do not allow @GOTOFF in
6960       ought but a memory context.  */
6961    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6962 {
6963   switch (get_attr_type (insn))
6964     {
6965     case TYPE_INCDEC:
6966       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6967       if (operands[2] == const1_rtx)
6968         return "inc{l}\t%0";
6969       else
6970         {
6971           gcc_assert (operands[2] == constm1_rtx);
6972           return "dec{l}\t%0";
6973         }
6974
6975     default:
6976       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6977       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6978          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6979       if (CONST_INT_P (operands[2])
6980           && (INTVAL (operands[2]) == 128
6981               || (INTVAL (operands[2]) < 0
6982                   && INTVAL (operands[2]) != -128)))
6983         {
6984           operands[2] = GEN_INT (-INTVAL (operands[2]));
6985           return "sub{l}\t{%2, %0|%0, %2}";
6986         }
6987       return "add{l}\t{%2, %0|%0, %2}";
6988     }
6989 }
6990   [(set (attr "type")
6991      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6992         (const_string "incdec")
6993         (const_string "alu")))
6994    (set (attr "length_immediate")
6995       (if_then_else
6996         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6997         (const_string "1")
6998         (const_string "*")))
6999    (set_attr "mode" "SI")])
7000
7001 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7002 (define_insn "*addsi_2_zext"
7003   [(set (reg FLAGS_REG)
7004         (compare
7005           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7006                    (match_operand:SI 2 "general_operand" "g"))
7007           (const_int 0)))
7008    (set (match_operand:DI 0 "register_operand" "=r")
7009         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7010   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7011    && ix86_binary_operator_ok (PLUS, SImode, operands)
7012    /* Current assemblers are broken and do not allow @GOTOFF in
7013       ought but a memory context.  */
7014    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7015 {
7016   switch (get_attr_type (insn))
7017     {
7018     case TYPE_INCDEC:
7019       if (operands[2] == const1_rtx)
7020         return "inc{l}\t%k0";
7021       else
7022         {
7023           gcc_assert (operands[2] == constm1_rtx);
7024           return "dec{l}\t%k0";
7025         }
7026
7027     default:
7028       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7029          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7030       if (CONST_INT_P (operands[2])
7031           && (INTVAL (operands[2]) == 128
7032               || (INTVAL (operands[2]) < 0
7033                   && INTVAL (operands[2]) != -128)))
7034         {
7035           operands[2] = GEN_INT (-INTVAL (operands[2]));
7036           return "sub{l}\t{%2, %k0|%k0, %2}";
7037         }
7038       return "add{l}\t{%2, %k0|%k0, %2}";
7039     }
7040 }
7041   [(set (attr "type")
7042      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7043         (const_string "incdec")
7044         (const_string "alu")))
7045    (set (attr "length_immediate")
7046       (if_then_else
7047         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7048         (const_string "1")
7049         (const_string "*")))
7050    (set_attr "mode" "SI")])
7051
7052 (define_insn "*addsi_3"
7053   [(set (reg FLAGS_REG)
7054         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7055                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
7056    (clobber (match_scratch:SI 0 "=r"))]
7057   "ix86_match_ccmode (insn, CCZmode)
7058    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7059    /* Current assemblers are broken and do not allow @GOTOFF in
7060       ought but a memory context.  */
7061    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7062 {
7063   switch (get_attr_type (insn))
7064     {
7065     case TYPE_INCDEC:
7066       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7067       if (operands[2] == const1_rtx)
7068         return "inc{l}\t%0";
7069       else
7070         {
7071           gcc_assert (operands[2] == constm1_rtx);
7072           return "dec{l}\t%0";
7073         }
7074
7075     default:
7076       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7077       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7078          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7079       if (CONST_INT_P (operands[2])
7080           && (INTVAL (operands[2]) == 128
7081               || (INTVAL (operands[2]) < 0
7082                   && INTVAL (operands[2]) != -128)))
7083         {
7084           operands[2] = GEN_INT (-INTVAL (operands[2]));
7085           return "sub{l}\t{%2, %0|%0, %2}";
7086         }
7087       return "add{l}\t{%2, %0|%0, %2}";
7088     }
7089 }
7090   [(set (attr "type")
7091      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7092         (const_string "incdec")
7093         (const_string "alu")))
7094    (set (attr "length_immediate")
7095       (if_then_else
7096         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7097         (const_string "1")
7098         (const_string "*")))
7099    (set_attr "mode" "SI")])
7100
7101 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7102 (define_insn "*addsi_3_zext"
7103   [(set (reg FLAGS_REG)
7104         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7105                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
7106    (set (match_operand:DI 0 "register_operand" "=r")
7107         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7108   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7109    && ix86_binary_operator_ok (PLUS, SImode, operands)
7110    /* Current assemblers are broken and do not allow @GOTOFF in
7111       ought but a memory context.  */
7112    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7113 {
7114   switch (get_attr_type (insn))
7115     {
7116     case TYPE_INCDEC:
7117       if (operands[2] == const1_rtx)
7118         return "inc{l}\t%k0";
7119       else
7120         {
7121           gcc_assert (operands[2] == constm1_rtx);
7122           return "dec{l}\t%k0";
7123         }
7124
7125     default:
7126       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7127          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7128       if (CONST_INT_P (operands[2])
7129           && (INTVAL (operands[2]) == 128
7130               || (INTVAL (operands[2]) < 0
7131                   && INTVAL (operands[2]) != -128)))
7132         {
7133           operands[2] = GEN_INT (-INTVAL (operands[2]));
7134           return "sub{l}\t{%2, %k0|%k0, %2}";
7135         }
7136       return "add{l}\t{%2, %k0|%k0, %2}";
7137     }
7138 }
7139   [(set (attr "type")
7140      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7141         (const_string "incdec")
7142         (const_string "alu")))
7143    (set (attr "length_immediate")
7144       (if_then_else
7145         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7146         (const_string "1")
7147         (const_string "*")))
7148    (set_attr "mode" "SI")])
7149
7150 ; For comparisons against 1, -1 and 128, we may generate better code
7151 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7152 ; is matched then.  We can't accept general immediate, because for
7153 ; case of overflows,  the result is messed up.
7154 ; This pattern also don't hold of 0x80000000, since the value overflows
7155 ; when negated.
7156 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7157 ; only for comparisons not depending on it.
7158 (define_insn "*addsi_4"
7159   [(set (reg FLAGS_REG)
7160         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7161                  (match_operand:SI 2 "const_int_operand" "n")))
7162    (clobber (match_scratch:SI 0 "=rm"))]
7163   "ix86_match_ccmode (insn, CCGCmode)
7164    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7165 {
7166   switch (get_attr_type (insn))
7167     {
7168     case TYPE_INCDEC:
7169       if (operands[2] == constm1_rtx)
7170         return "inc{l}\t%0";
7171       else
7172         {
7173           gcc_assert (operands[2] == const1_rtx);
7174           return "dec{l}\t%0";
7175         }
7176
7177     default:
7178       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7180          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7181       if ((INTVAL (operands[2]) == -128
7182            || (INTVAL (operands[2]) > 0
7183                && INTVAL (operands[2]) != 128)))
7184         return "sub{l}\t{%2, %0|%0, %2}";
7185       operands[2] = GEN_INT (-INTVAL (operands[2]));
7186       return "add{l}\t{%2, %0|%0, %2}";
7187     }
7188 }
7189   [(set (attr "type")
7190      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7191         (const_string "incdec")
7192         (const_string "alu")))
7193    (set (attr "length_immediate")
7194       (if_then_else
7195         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7196         (const_string "1")
7197         (const_string "*")))
7198    (set_attr "mode" "SI")])
7199
7200 (define_insn "*addsi_5"
7201   [(set (reg FLAGS_REG)
7202         (compare
7203           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7204                    (match_operand:SI 2 "general_operand" "g"))
7205           (const_int 0)))
7206    (clobber (match_scratch:SI 0 "=r"))]
7207   "ix86_match_ccmode (insn, CCGOCmode)
7208    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7209    /* Current assemblers are broken and do not allow @GOTOFF in
7210       ought but a memory context.  */
7211    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7212 {
7213   switch (get_attr_type (insn))
7214     {
7215     case TYPE_INCDEC:
7216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7217       if (operands[2] == const1_rtx)
7218         return "inc{l}\t%0";
7219       else
7220         {
7221           gcc_assert (operands[2] == constm1_rtx);
7222           return "dec{l}\t%0";
7223         }
7224
7225     default:
7226       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7227       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7228          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7229       if (CONST_INT_P (operands[2])
7230           && (INTVAL (operands[2]) == 128
7231               || (INTVAL (operands[2]) < 0
7232                   && INTVAL (operands[2]) != -128)))
7233         {
7234           operands[2] = GEN_INT (-INTVAL (operands[2]));
7235           return "sub{l}\t{%2, %0|%0, %2}";
7236         }
7237       return "add{l}\t{%2, %0|%0, %2}";
7238     }
7239 }
7240   [(set (attr "type")
7241      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7242         (const_string "incdec")
7243         (const_string "alu")))
7244    (set (attr "length_immediate")
7245       (if_then_else
7246         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7247         (const_string "1")
7248         (const_string "*")))
7249    (set_attr "mode" "SI")])
7250
7251 (define_expand "addhi3"
7252   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7253         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7254                  (match_operand:HI 2 "general_operand" "")))]
7255   "TARGET_HIMODE_MATH"
7256   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
7257
7258 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
7259 ;; type optimizations enabled by define-splits.  This is not important
7260 ;; for PII, and in fact harmful because of partial register stalls.
7261
7262 (define_insn "*addhi_1_lea"
7263   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7264         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
7265                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
7266    (clobber (reg:CC FLAGS_REG))]
7267   "!TARGET_PARTIAL_REG_STALL
7268    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7269 {
7270   switch (get_attr_type (insn))
7271     {
7272     case TYPE_LEA:
7273       return "#";
7274     case TYPE_INCDEC:
7275       if (operands[2] == const1_rtx)
7276         return "inc{w}\t%0";
7277       else
7278         {
7279           gcc_assert (operands[2] == constm1_rtx);
7280           return "dec{w}\t%0";
7281         }
7282
7283     default:
7284       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7285          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7286       if (CONST_INT_P (operands[2])
7287           && (INTVAL (operands[2]) == 128
7288               || (INTVAL (operands[2]) < 0
7289                   && INTVAL (operands[2]) != -128)))
7290         {
7291           operands[2] = GEN_INT (-INTVAL (operands[2]));
7292           return "sub{w}\t{%2, %0|%0, %2}";
7293         }
7294       return "add{w}\t{%2, %0|%0, %2}";
7295     }
7296 }
7297   [(set (attr "type")
7298      (if_then_else (eq_attr "alternative" "2")
7299         (const_string "lea")
7300         (if_then_else (match_operand:HI 2 "incdec_operand" "")
7301            (const_string "incdec")
7302            (const_string "alu"))))
7303    (set (attr "length_immediate")
7304       (if_then_else
7305         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7306         (const_string "1")
7307         (const_string "*")))
7308    (set_attr "mode" "HI,HI,SI")])
7309
7310 (define_insn "*addhi_1"
7311   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7312         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7313                  (match_operand:HI 2 "general_operand" "rn,rm")))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "TARGET_PARTIAL_REG_STALL
7316    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7317 {
7318   switch (get_attr_type (insn))
7319     {
7320     case TYPE_INCDEC:
7321       if (operands[2] == const1_rtx)
7322         return "inc{w}\t%0";
7323       else
7324         {
7325           gcc_assert (operands[2] == constm1_rtx);
7326           return "dec{w}\t%0";
7327         }
7328
7329     default:
7330       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7331          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7332       if (CONST_INT_P (operands[2])
7333           && (INTVAL (operands[2]) == 128
7334               || (INTVAL (operands[2]) < 0
7335                   && INTVAL (operands[2]) != -128)))
7336         {
7337           operands[2] = GEN_INT (-INTVAL (operands[2]));
7338           return "sub{w}\t{%2, %0|%0, %2}";
7339         }
7340       return "add{w}\t{%2, %0|%0, %2}";
7341     }
7342 }
7343   [(set (attr "type")
7344      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7345         (const_string "incdec")
7346         (const_string "alu")))
7347    (set (attr "length_immediate")
7348       (if_then_else
7349         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7350         (const_string "1")
7351         (const_string "*")))
7352    (set_attr "mode" "HI")])
7353
7354 (define_insn "*addhi_2"
7355   [(set (reg FLAGS_REG)
7356         (compare
7357           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7358                    (match_operand:HI 2 "general_operand" "rmn,rn"))
7359           (const_int 0)))
7360    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7361         (plus:HI (match_dup 1) (match_dup 2)))]
7362   "ix86_match_ccmode (insn, CCGOCmode)
7363    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7364 {
7365   switch (get_attr_type (insn))
7366     {
7367     case TYPE_INCDEC:
7368       if (operands[2] == const1_rtx)
7369         return "inc{w}\t%0";
7370       else
7371         {
7372           gcc_assert (operands[2] == constm1_rtx);
7373           return "dec{w}\t%0";
7374         }
7375
7376     default:
7377       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7378          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7379       if (CONST_INT_P (operands[2])
7380           && (INTVAL (operands[2]) == 128
7381               || (INTVAL (operands[2]) < 0
7382                   && INTVAL (operands[2]) != -128)))
7383         {
7384           operands[2] = GEN_INT (-INTVAL (operands[2]));
7385           return "sub{w}\t{%2, %0|%0, %2}";
7386         }
7387       return "add{w}\t{%2, %0|%0, %2}";
7388     }
7389 }
7390   [(set (attr "type")
7391      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7392         (const_string "incdec")
7393         (const_string "alu")))
7394    (set (attr "length_immediate")
7395       (if_then_else
7396         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7397         (const_string "1")
7398         (const_string "*")))
7399    (set_attr "mode" "HI")])
7400
7401 (define_insn "*addhi_3"
7402   [(set (reg FLAGS_REG)
7403         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7404                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
7405    (clobber (match_scratch:HI 0 "=r"))]
7406   "ix86_match_ccmode (insn, CCZmode)
7407    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7408 {
7409   switch (get_attr_type (insn))
7410     {
7411     case TYPE_INCDEC:
7412       if (operands[2] == const1_rtx)
7413         return "inc{w}\t%0";
7414       else
7415         {
7416           gcc_assert (operands[2] == constm1_rtx);
7417           return "dec{w}\t%0";
7418         }
7419
7420     default:
7421       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7422          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7423       if (CONST_INT_P (operands[2])
7424           && (INTVAL (operands[2]) == 128
7425               || (INTVAL (operands[2]) < 0
7426                   && INTVAL (operands[2]) != -128)))
7427         {
7428           operands[2] = GEN_INT (-INTVAL (operands[2]));
7429           return "sub{w}\t{%2, %0|%0, %2}";
7430         }
7431       return "add{w}\t{%2, %0|%0, %2}";
7432     }
7433 }
7434   [(set (attr "type")
7435      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7436         (const_string "incdec")
7437         (const_string "alu")))
7438    (set (attr "length_immediate")
7439       (if_then_else
7440         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7441         (const_string "1")
7442         (const_string "*")))
7443    (set_attr "mode" "HI")])
7444
7445 ; See comments above addsi_4 for details.
7446 (define_insn "*addhi_4"
7447   [(set (reg FLAGS_REG)
7448         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7449                  (match_operand:HI 2 "const_int_operand" "n")))
7450    (clobber (match_scratch:HI 0 "=rm"))]
7451   "ix86_match_ccmode (insn, CCGCmode)
7452    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7453 {
7454   switch (get_attr_type (insn))
7455     {
7456     case TYPE_INCDEC:
7457       if (operands[2] == constm1_rtx)
7458         return "inc{w}\t%0";
7459       else
7460         {
7461           gcc_assert (operands[2] == const1_rtx);
7462           return "dec{w}\t%0";
7463         }
7464
7465     default:
7466       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7467       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7468          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7469       if ((INTVAL (operands[2]) == -128
7470            || (INTVAL (operands[2]) > 0
7471                && INTVAL (operands[2]) != 128)))
7472         return "sub{w}\t{%2, %0|%0, %2}";
7473       operands[2] = GEN_INT (-INTVAL (operands[2]));
7474       return "add{w}\t{%2, %0|%0, %2}";
7475     }
7476 }
7477   [(set (attr "type")
7478      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7479         (const_string "incdec")
7480         (const_string "alu")))
7481    (set (attr "length_immediate")
7482       (if_then_else
7483         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7484         (const_string "1")
7485         (const_string "*")))
7486    (set_attr "mode" "HI")])
7487
7488
7489 (define_insn "*addhi_5"
7490   [(set (reg FLAGS_REG)
7491         (compare
7492           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7493                    (match_operand:HI 2 "general_operand" "rmn"))
7494           (const_int 0)))
7495    (clobber (match_scratch:HI 0 "=r"))]
7496   "ix86_match_ccmode (insn, CCGOCmode)
7497    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7498 {
7499   switch (get_attr_type (insn))
7500     {
7501     case TYPE_INCDEC:
7502       if (operands[2] == const1_rtx)
7503         return "inc{w}\t%0";
7504       else
7505         {
7506           gcc_assert (operands[2] == constm1_rtx);
7507           return "dec{w}\t%0";
7508         }
7509
7510     default:
7511       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7512          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7513       if (CONST_INT_P (operands[2])
7514           && (INTVAL (operands[2]) == 128
7515               || (INTVAL (operands[2]) < 0
7516                   && INTVAL (operands[2]) != -128)))
7517         {
7518           operands[2] = GEN_INT (-INTVAL (operands[2]));
7519           return "sub{w}\t{%2, %0|%0, %2}";
7520         }
7521       return "add{w}\t{%2, %0|%0, %2}";
7522     }
7523 }
7524   [(set (attr "type")
7525      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7526         (const_string "incdec")
7527         (const_string "alu")))
7528    (set (attr "length_immediate")
7529       (if_then_else
7530         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7531         (const_string "1")
7532         (const_string "*")))
7533    (set_attr "mode" "HI")])
7534
7535 (define_expand "addqi3"
7536   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7537         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7538                  (match_operand:QI 2 "general_operand" "")))]
7539   "TARGET_QIMODE_MATH"
7540   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7541
7542 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7543 (define_insn "*addqi_1_lea"
7544   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7545         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7546                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7547    (clobber (reg:CC FLAGS_REG))]
7548   "!TARGET_PARTIAL_REG_STALL
7549    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7550 {
7551   int widen = (which_alternative == 2);
7552   switch (get_attr_type (insn))
7553     {
7554     case TYPE_LEA:
7555       return "#";
7556     case TYPE_INCDEC:
7557       if (operands[2] == const1_rtx)
7558         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7559       else
7560         {
7561           gcc_assert (operands[2] == constm1_rtx);
7562           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7563         }
7564
7565     default:
7566       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7567          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7568       if (CONST_INT_P (operands[2])
7569           && (INTVAL (operands[2]) == 128
7570               || (INTVAL (operands[2]) < 0
7571                   && INTVAL (operands[2]) != -128)))
7572         {
7573           operands[2] = GEN_INT (-INTVAL (operands[2]));
7574           if (widen)
7575             return "sub{l}\t{%2, %k0|%k0, %2}";
7576           else
7577             return "sub{b}\t{%2, %0|%0, %2}";
7578         }
7579       if (widen)
7580         return "add{l}\t{%k2, %k0|%k0, %k2}";
7581       else
7582         return "add{b}\t{%2, %0|%0, %2}";
7583     }
7584 }
7585   [(set (attr "type")
7586      (if_then_else (eq_attr "alternative" "3")
7587         (const_string "lea")
7588         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7589            (const_string "incdec")
7590            (const_string "alu"))))
7591    (set (attr "length_immediate")
7592       (if_then_else
7593         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7594         (const_string "1")
7595         (const_string "*")))
7596    (set_attr "mode" "QI,QI,SI,SI")])
7597
7598 (define_insn "*addqi_1"
7599   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7600         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7601                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7602    (clobber (reg:CC FLAGS_REG))]
7603   "TARGET_PARTIAL_REG_STALL
7604    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7605 {
7606   int widen = (which_alternative == 2);
7607   switch (get_attr_type (insn))
7608     {
7609     case TYPE_INCDEC:
7610       if (operands[2] == const1_rtx)
7611         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7612       else
7613         {
7614           gcc_assert (operands[2] == constm1_rtx);
7615           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7616         }
7617
7618     default:
7619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7621       if (CONST_INT_P (operands[2])
7622           && (INTVAL (operands[2]) == 128
7623               || (INTVAL (operands[2]) < 0
7624                   && INTVAL (operands[2]) != -128)))
7625         {
7626           operands[2] = GEN_INT (-INTVAL (operands[2]));
7627           if (widen)
7628             return "sub{l}\t{%2, %k0|%k0, %2}";
7629           else
7630             return "sub{b}\t{%2, %0|%0, %2}";
7631         }
7632       if (widen)
7633         return "add{l}\t{%k2, %k0|%k0, %k2}";
7634       else
7635         return "add{b}\t{%2, %0|%0, %2}";
7636     }
7637 }
7638   [(set (attr "type")
7639      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7640         (const_string "incdec")
7641         (const_string "alu")))
7642    (set (attr "length_immediate")
7643       (if_then_else
7644         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7645         (const_string "1")
7646         (const_string "*")))
7647    (set_attr "mode" "QI,QI,SI")])
7648
7649 (define_insn "*addqi_1_slp"
7650   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7651         (plus:QI (match_dup 0)
7652                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7653    (clobber (reg:CC FLAGS_REG))]
7654   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7655    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7656 {
7657   switch (get_attr_type (insn))
7658     {
7659     case TYPE_INCDEC:
7660       if (operands[1] == const1_rtx)
7661         return "inc{b}\t%0";
7662       else
7663         {
7664           gcc_assert (operands[1] == constm1_rtx);
7665           return "dec{b}\t%0";
7666         }
7667
7668     default:
7669       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7670       if (CONST_INT_P (operands[1])
7671           && INTVAL (operands[1]) < 0)
7672         {
7673           operands[1] = GEN_INT (-INTVAL (operands[1]));
7674           return "sub{b}\t{%1, %0|%0, %1}";
7675         }
7676       return "add{b}\t{%1, %0|%0, %1}";
7677     }
7678 }
7679   [(set (attr "type")
7680      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7681         (const_string "incdec")
7682         (const_string "alu1")))
7683    (set (attr "memory")
7684      (if_then_else (match_operand 1 "memory_operand" "")
7685         (const_string "load")
7686         (const_string "none")))
7687    (set_attr "mode" "QI")])
7688
7689 (define_insn "*addqi_2"
7690   [(set (reg FLAGS_REG)
7691         (compare
7692           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7693                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7694           (const_int 0)))
7695    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7696         (plus:QI (match_dup 1) (match_dup 2)))]
7697   "ix86_match_ccmode (insn, CCGOCmode)
7698    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7699 {
7700   switch (get_attr_type (insn))
7701     {
7702     case TYPE_INCDEC:
7703       if (operands[2] == const1_rtx)
7704         return "inc{b}\t%0";
7705       else
7706         {
7707           gcc_assert (operands[2] == constm1_rtx
7708                       || (CONST_INT_P (operands[2])
7709                           && INTVAL (operands[2]) == 255));
7710           return "dec{b}\t%0";
7711         }
7712
7713     default:
7714       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7715       if (CONST_INT_P (operands[2])
7716           && INTVAL (operands[2]) < 0)
7717         {
7718           operands[2] = GEN_INT (-INTVAL (operands[2]));
7719           return "sub{b}\t{%2, %0|%0, %2}";
7720         }
7721       return "add{b}\t{%2, %0|%0, %2}";
7722     }
7723 }
7724   [(set (attr "type")
7725      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7726         (const_string "incdec")
7727         (const_string "alu")))
7728    (set_attr "mode" "QI")])
7729
7730 (define_insn "*addqi_3"
7731   [(set (reg FLAGS_REG)
7732         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7733                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7734    (clobber (match_scratch:QI 0 "=q"))]
7735   "ix86_match_ccmode (insn, CCZmode)
7736    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7737 {
7738   switch (get_attr_type (insn))
7739     {
7740     case TYPE_INCDEC:
7741       if (operands[2] == const1_rtx)
7742         return "inc{b}\t%0";
7743       else
7744         {
7745           gcc_assert (operands[2] == constm1_rtx
7746                       || (CONST_INT_P (operands[2])
7747                           && INTVAL (operands[2]) == 255));
7748           return "dec{b}\t%0";
7749         }
7750
7751     default:
7752       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7753       if (CONST_INT_P (operands[2])
7754           && INTVAL (operands[2]) < 0)
7755         {
7756           operands[2] = GEN_INT (-INTVAL (operands[2]));
7757           return "sub{b}\t{%2, %0|%0, %2}";
7758         }
7759       return "add{b}\t{%2, %0|%0, %2}";
7760     }
7761 }
7762   [(set (attr "type")
7763      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7764         (const_string "incdec")
7765         (const_string "alu")))
7766    (set_attr "mode" "QI")])
7767
7768 ; See comments above addsi_4 for details.
7769 (define_insn "*addqi_4"
7770   [(set (reg FLAGS_REG)
7771         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7772                  (match_operand:QI 2 "const_int_operand" "n")))
7773    (clobber (match_scratch:QI 0 "=qm"))]
7774   "ix86_match_ccmode (insn, CCGCmode)
7775    && (INTVAL (operands[2]) & 0xff) != 0x80"
7776 {
7777   switch (get_attr_type (insn))
7778     {
7779     case TYPE_INCDEC:
7780       if (operands[2] == constm1_rtx
7781           || (CONST_INT_P (operands[2])
7782               && INTVAL (operands[2]) == 255))
7783         return "inc{b}\t%0";
7784       else
7785         {
7786           gcc_assert (operands[2] == const1_rtx);
7787           return "dec{b}\t%0";
7788         }
7789
7790     default:
7791       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7792       if (INTVAL (operands[2]) < 0)
7793         {
7794           operands[2] = GEN_INT (-INTVAL (operands[2]));
7795           return "add{b}\t{%2, %0|%0, %2}";
7796         }
7797       return "sub{b}\t{%2, %0|%0, %2}";
7798     }
7799 }
7800   [(set (attr "type")
7801      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7802         (const_string "incdec")
7803         (const_string "alu")))
7804    (set_attr "mode" "QI")])
7805
7806
7807 (define_insn "*addqi_5"
7808   [(set (reg FLAGS_REG)
7809         (compare
7810           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7811                    (match_operand:QI 2 "general_operand" "qmn"))
7812           (const_int 0)))
7813    (clobber (match_scratch:QI 0 "=q"))]
7814   "ix86_match_ccmode (insn, CCGOCmode)
7815    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7816 {
7817   switch (get_attr_type (insn))
7818     {
7819     case TYPE_INCDEC:
7820       if (operands[2] == const1_rtx)
7821         return "inc{b}\t%0";
7822       else
7823         {
7824           gcc_assert (operands[2] == constm1_rtx
7825                       || (CONST_INT_P (operands[2])
7826                           && INTVAL (operands[2]) == 255));
7827           return "dec{b}\t%0";
7828         }
7829
7830     default:
7831       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7832       if (CONST_INT_P (operands[2])
7833           && INTVAL (operands[2]) < 0)
7834         {
7835           operands[2] = GEN_INT (-INTVAL (operands[2]));
7836           return "sub{b}\t{%2, %0|%0, %2}";
7837         }
7838       return "add{b}\t{%2, %0|%0, %2}";
7839     }
7840 }
7841   [(set (attr "type")
7842      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7843         (const_string "incdec")
7844         (const_string "alu")))
7845    (set_attr "mode" "QI")])
7846
7847
7848 (define_insn "addqi_ext_1"
7849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7850                          (const_int 8)
7851                          (const_int 8))
7852         (plus:SI
7853           (zero_extract:SI
7854             (match_operand 1 "ext_register_operand" "0")
7855             (const_int 8)
7856             (const_int 8))
7857           (match_operand:QI 2 "general_operand" "Qmn")))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "!TARGET_64BIT"
7860 {
7861   switch (get_attr_type (insn))
7862     {
7863     case TYPE_INCDEC:
7864       if (operands[2] == const1_rtx)
7865         return "inc{b}\t%h0";
7866       else
7867         {
7868           gcc_assert (operands[2] == constm1_rtx
7869                       || (CONST_INT_P (operands[2])
7870                           && INTVAL (operands[2]) == 255));
7871           return "dec{b}\t%h0";
7872         }
7873
7874     default:
7875       return "add{b}\t{%2, %h0|%h0, %2}";
7876     }
7877 }
7878   [(set (attr "type")
7879      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7880         (const_string "incdec")
7881         (const_string "alu")))
7882    (set_attr "modrm" "1")
7883    (set_attr "mode" "QI")])
7884
7885 (define_insn "*addqi_ext_1_rex64"
7886   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7887                          (const_int 8)
7888                          (const_int 8))
7889         (plus:SI
7890           (zero_extract:SI
7891             (match_operand 1 "ext_register_operand" "0")
7892             (const_int 8)
7893             (const_int 8))
7894           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7895    (clobber (reg:CC FLAGS_REG))]
7896   "TARGET_64BIT"
7897 {
7898   switch (get_attr_type (insn))
7899     {
7900     case TYPE_INCDEC:
7901       if (operands[2] == const1_rtx)
7902         return "inc{b}\t%h0";
7903       else
7904         {
7905           gcc_assert (operands[2] == constm1_rtx
7906                       || (CONST_INT_P (operands[2])
7907                           && INTVAL (operands[2]) == 255));
7908           return "dec{b}\t%h0";
7909         }
7910
7911     default:
7912       return "add{b}\t{%2, %h0|%h0, %2}";
7913     }
7914 }
7915   [(set (attr "type")
7916      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7917         (const_string "incdec")
7918         (const_string "alu")))
7919    (set_attr "modrm" "1")
7920    (set_attr "mode" "QI")])
7921
7922 (define_insn "*addqi_ext_2"
7923   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7924                          (const_int 8)
7925                          (const_int 8))
7926         (plus:SI
7927           (zero_extract:SI
7928             (match_operand 1 "ext_register_operand" "%0")
7929             (const_int 8)
7930             (const_int 8))
7931           (zero_extract:SI
7932             (match_operand 2 "ext_register_operand" "Q")
7933             (const_int 8)
7934             (const_int 8))))
7935    (clobber (reg:CC FLAGS_REG))]
7936   ""
7937   "add{b}\t{%h2, %h0|%h0, %h2}"
7938   [(set_attr "type" "alu")
7939    (set_attr "mode" "QI")])
7940
7941 ;; The patterns that match these are at the end of this file.
7942
7943 (define_expand "addxf3"
7944   [(set (match_operand:XF 0 "register_operand" "")
7945         (plus:XF (match_operand:XF 1 "register_operand" "")
7946                  (match_operand:XF 2 "register_operand" "")))]
7947   "TARGET_80387"
7948   "")
7949
7950 (define_expand "add<mode>3"
7951   [(set (match_operand:MODEF 0 "register_operand" "")
7952         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7953                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7954   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7955     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7956   "")
7957 \f
7958 ;; Subtract instructions
7959
7960 ;; %%% splits for subditi3
7961
7962 (define_expand "subti3"
7963   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7964         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7965                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7966   "TARGET_64BIT"
7967   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7968
7969 (define_insn "*subti3_1"
7970   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7971         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7972                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7973    (clobber (reg:CC FLAGS_REG))]
7974   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7975   "#")
7976
7977 (define_split
7978   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7979         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7980                   (match_operand:TI 2 "x86_64_general_operand" "")))
7981    (clobber (reg:CC FLAGS_REG))]
7982   "TARGET_64BIT && reload_completed"
7983   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7984               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7985    (parallel [(set (match_dup 3)
7986                    (minus:DI (match_dup 4)
7987                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7988                                       (match_dup 5))))
7989               (clobber (reg:CC FLAGS_REG))])]
7990   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7991
7992 ;; %%% splits for subsidi3
7993
7994 (define_expand "subdi3"
7995   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7996         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7997                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7998   ""
7999   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
8000
8001 (define_insn "*subdi3_1"
8002   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
8003         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8004                   (match_operand:DI 2 "general_operand" "roiF,riF")))
8005    (clobber (reg:CC FLAGS_REG))]
8006   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8007   "#")
8008
8009 (define_split
8010   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8011         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8012                   (match_operand:DI 2 "general_operand" "")))
8013    (clobber (reg:CC FLAGS_REG))]
8014   "!TARGET_64BIT && reload_completed"
8015   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
8016               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8017    (parallel [(set (match_dup 3)
8018                    (minus:SI (match_dup 4)
8019                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
8020                                       (match_dup 5))))
8021               (clobber (reg:CC FLAGS_REG))])]
8022   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
8023
8024 (define_insn "subdi3_carry_rex64"
8025   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8026           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8027             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
8028                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8031   "sbb{q}\t{%2, %0|%0, %2}"
8032   [(set_attr "type" "alu")
8033    (set_attr "use_carry" "1")
8034    (set_attr "pent_pair" "pu")
8035    (set_attr "mode" "DI")])
8036
8037 (define_insn "*subdi_1_rex64"
8038   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8039         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8040                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8041    (clobber (reg:CC FLAGS_REG))]
8042   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8043   "sub{q}\t{%2, %0|%0, %2}"
8044   [(set_attr "type" "alu")
8045    (set_attr "mode" "DI")])
8046
8047 (define_insn "*subdi_2_rex64"
8048   [(set (reg FLAGS_REG)
8049         (compare
8050           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8051                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
8052           (const_int 0)))
8053    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8054         (minus:DI (match_dup 1) (match_dup 2)))]
8055   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8056    && ix86_binary_operator_ok (MINUS, DImode, operands)"
8057   "sub{q}\t{%2, %0|%0, %2}"
8058   [(set_attr "type" "alu")
8059    (set_attr "mode" "DI")])
8060
8061 (define_insn "*subdi_3_rex63"
8062   [(set (reg FLAGS_REG)
8063         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
8064                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8065    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8066         (minus:DI (match_dup 1) (match_dup 2)))]
8067   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8068    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8069   "sub{q}\t{%2, %0|%0, %2}"
8070   [(set_attr "type" "alu")
8071    (set_attr "mode" "DI")])
8072
8073 (define_insn "subqi3_carry"
8074   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8075           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8076             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
8077                (match_operand:QI 2 "general_operand" "qn,qm"))))
8078    (clobber (reg:CC FLAGS_REG))]
8079   "ix86_binary_operator_ok (MINUS, QImode, operands)"
8080   "sbb{b}\t{%2, %0|%0, %2}"
8081   [(set_attr "type" "alu")
8082    (set_attr "use_carry" "1")
8083    (set_attr "pent_pair" "pu")
8084    (set_attr "mode" "QI")])
8085
8086 (define_insn "subhi3_carry"
8087   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8088           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8089             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
8090                (match_operand:HI 2 "general_operand" "rn,rm"))))
8091    (clobber (reg:CC FLAGS_REG))]
8092   "ix86_binary_operator_ok (MINUS, HImode, operands)"
8093   "sbb{w}\t{%2, %0|%0, %2}"
8094   [(set_attr "type" "alu")
8095    (set_attr "use_carry" "1")
8096    (set_attr "pent_pair" "pu")
8097    (set_attr "mode" "HI")])
8098
8099 (define_insn "subsi3_carry"
8100   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8101           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8102             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8103                (match_operand:SI 2 "general_operand" "ri,rm"))))
8104    (clobber (reg:CC FLAGS_REG))]
8105   "ix86_binary_operator_ok (MINUS, SImode, operands)"
8106   "sbb{l}\t{%2, %0|%0, %2}"
8107   [(set_attr "type" "alu")
8108    (set_attr "use_carry" "1")
8109    (set_attr "pent_pair" "pu")
8110    (set_attr "mode" "SI")])
8111
8112 (define_insn "subsi3_carry_zext"
8113   [(set (match_operand:DI 0 "register_operand" "=r")
8114           (zero_extend:DI
8115             (minus:SI (match_operand:SI 1 "register_operand" "0")
8116               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8117                  (match_operand:SI 2 "general_operand" "g")))))
8118    (clobber (reg:CC FLAGS_REG))]
8119   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8120   "sbb{l}\t{%2, %k0|%k0, %2}"
8121   [(set_attr "type" "alu")
8122    (set_attr "pent_pair" "pu")
8123    (set_attr "mode" "SI")])
8124
8125 (define_expand "subsi3"
8126   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8127         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
8128                   (match_operand:SI 2 "general_operand" "")))]
8129   ""
8130   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
8131
8132 (define_insn "*subsi_1"
8133   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8134         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8135                   (match_operand:SI 2 "general_operand" "ri,rm")))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "ix86_binary_operator_ok (MINUS, SImode, operands)"
8138   "sub{l}\t{%2, %0|%0, %2}"
8139   [(set_attr "type" "alu")
8140    (set_attr "mode" "SI")])
8141
8142 (define_insn "*subsi_1_zext"
8143   [(set (match_operand:DI 0 "register_operand" "=r")
8144         (zero_extend:DI
8145           (minus:SI (match_operand:SI 1 "register_operand" "0")
8146                     (match_operand:SI 2 "general_operand" "g"))))
8147    (clobber (reg:CC FLAGS_REG))]
8148   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8149   "sub{l}\t{%2, %k0|%k0, %2}"
8150   [(set_attr "type" "alu")
8151    (set_attr "mode" "SI")])
8152
8153 (define_insn "*subsi_2"
8154   [(set (reg FLAGS_REG)
8155         (compare
8156           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8157                     (match_operand:SI 2 "general_operand" "ri,rm"))
8158           (const_int 0)))
8159    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8160         (minus:SI (match_dup 1) (match_dup 2)))]
8161   "ix86_match_ccmode (insn, CCGOCmode)
8162    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8163   "sub{l}\t{%2, %0|%0, %2}"
8164   [(set_attr "type" "alu")
8165    (set_attr "mode" "SI")])
8166
8167 (define_insn "*subsi_2_zext"
8168   [(set (reg FLAGS_REG)
8169         (compare
8170           (minus:SI (match_operand:SI 1 "register_operand" "0")
8171                     (match_operand:SI 2 "general_operand" "g"))
8172           (const_int 0)))
8173    (set (match_operand:DI 0 "register_operand" "=r")
8174         (zero_extend:DI
8175           (minus:SI (match_dup 1)
8176                     (match_dup 2))))]
8177   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8178    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8179   "sub{l}\t{%2, %k0|%k0, %2}"
8180   [(set_attr "type" "alu")
8181    (set_attr "mode" "SI")])
8182
8183 (define_insn "*subsi_3"
8184   [(set (reg FLAGS_REG)
8185         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
8186                  (match_operand:SI 2 "general_operand" "ri,rm")))
8187    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8188         (minus:SI (match_dup 1) (match_dup 2)))]
8189   "ix86_match_ccmode (insn, CCmode)
8190    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8191   "sub{l}\t{%2, %0|%0, %2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "SI")])
8194
8195 (define_insn "*subsi_3_zext"
8196   [(set (reg FLAGS_REG)
8197         (compare (match_operand:SI 1 "register_operand" "0")
8198                  (match_operand:SI 2 "general_operand" "g")))
8199    (set (match_operand:DI 0 "register_operand" "=r")
8200         (zero_extend:DI
8201           (minus:SI (match_dup 1)
8202                     (match_dup 2))))]
8203   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8204    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8205   "sub{l}\t{%2, %1|%1, %2}"
8206   [(set_attr "type" "alu")
8207    (set_attr "mode" "DI")])
8208
8209 (define_expand "subhi3"
8210   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8211         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
8212                   (match_operand:HI 2 "general_operand" "")))]
8213   "TARGET_HIMODE_MATH"
8214   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
8215
8216 (define_insn "*subhi_1"
8217   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8218         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8219                   (match_operand:HI 2 "general_operand" "rn,rm")))
8220    (clobber (reg:CC FLAGS_REG))]
8221   "ix86_binary_operator_ok (MINUS, HImode, operands)"
8222   "sub{w}\t{%2, %0|%0, %2}"
8223   [(set_attr "type" "alu")
8224    (set_attr "mode" "HI")])
8225
8226 (define_insn "*subhi_2"
8227   [(set (reg FLAGS_REG)
8228         (compare
8229           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8230                     (match_operand:HI 2 "general_operand" "rn,rm"))
8231           (const_int 0)))
8232    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8233         (minus:HI (match_dup 1) (match_dup 2)))]
8234   "ix86_match_ccmode (insn, CCGOCmode)
8235    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8236   "sub{w}\t{%2, %0|%0, %2}"
8237   [(set_attr "type" "alu")
8238    (set_attr "mode" "HI")])
8239
8240 (define_insn "*subhi_3"
8241   [(set (reg FLAGS_REG)
8242         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
8243                  (match_operand:HI 2 "general_operand" "rn,rm")))
8244    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8245         (minus:HI (match_dup 1) (match_dup 2)))]
8246   "ix86_match_ccmode (insn, CCmode)
8247    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8248   "sub{w}\t{%2, %0|%0, %2}"
8249   [(set_attr "type" "alu")
8250    (set_attr "mode" "HI")])
8251
8252 (define_expand "subqi3"
8253   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8254         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
8255                   (match_operand:QI 2 "general_operand" "")))]
8256   "TARGET_QIMODE_MATH"
8257   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
8258
8259 (define_insn "*subqi_1"
8260   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8261         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8262                   (match_operand:QI 2 "general_operand" "qn,qm")))
8263    (clobber (reg:CC FLAGS_REG))]
8264   "ix86_binary_operator_ok (MINUS, QImode, operands)"
8265   "sub{b}\t{%2, %0|%0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "QI")])
8268
8269 (define_insn "*subqi_1_slp"
8270   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8271         (minus:QI (match_dup 0)
8272                   (match_operand:QI 1 "general_operand" "qn,qm")))
8273    (clobber (reg:CC FLAGS_REG))]
8274   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8275    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8276   "sub{b}\t{%1, %0|%0, %1}"
8277   [(set_attr "type" "alu1")
8278    (set_attr "mode" "QI")])
8279
8280 (define_insn "*subqi_2"
8281   [(set (reg FLAGS_REG)
8282         (compare
8283           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8284                     (match_operand:QI 2 "general_operand" "qn,qm"))
8285           (const_int 0)))
8286    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8287         (minus:QI (match_dup 1) (match_dup 2)))]
8288   "ix86_match_ccmode (insn, CCGOCmode)
8289    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8290   "sub{b}\t{%2, %0|%0, %2}"
8291   [(set_attr "type" "alu")
8292    (set_attr "mode" "QI")])
8293
8294 (define_insn "*subqi_3"
8295   [(set (reg FLAGS_REG)
8296         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
8297                  (match_operand:QI 2 "general_operand" "qn,qm")))
8298    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8299         (minus:QI (match_dup 1) (match_dup 2)))]
8300   "ix86_match_ccmode (insn, CCmode)
8301    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8302   "sub{b}\t{%2, %0|%0, %2}"
8303   [(set_attr "type" "alu")
8304    (set_attr "mode" "QI")])
8305
8306 ;; The patterns that match these are at the end of this file.
8307
8308 (define_expand "subxf3"
8309   [(set (match_operand:XF 0 "register_operand" "")
8310         (minus:XF (match_operand:XF 1 "register_operand" "")
8311                   (match_operand:XF 2 "register_operand" "")))]
8312   "TARGET_80387"
8313   "")
8314
8315 (define_expand "sub<mode>3"
8316   [(set (match_operand:MODEF 0 "register_operand" "")
8317         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
8318                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8319   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8320     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8321   "")
8322 \f
8323 ;; Multiply instructions
8324
8325 (define_expand "muldi3"
8326   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8327                    (mult:DI (match_operand:DI 1 "register_operand" "")
8328                             (match_operand:DI 2 "x86_64_general_operand" "")))
8329               (clobber (reg:CC FLAGS_REG))])]
8330   "TARGET_64BIT"
8331   "")
8332
8333 ;; On AMDFAM10
8334 ;; IMUL reg64, reg64, imm8      Direct
8335 ;; IMUL reg64, mem64, imm8      VectorPath
8336 ;; IMUL reg64, reg64, imm32     Direct
8337 ;; IMUL reg64, mem64, imm32     VectorPath
8338 ;; IMUL reg64, reg64            Direct
8339 ;; IMUL reg64, mem64            Direct
8340
8341 (define_insn "*muldi3_1_rex64"
8342   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8343         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
8344                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "TARGET_64BIT
8347    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8348   "@
8349    imul{q}\t{%2, %1, %0|%0, %1, %2}
8350    imul{q}\t{%2, %1, %0|%0, %1, %2}
8351    imul{q}\t{%2, %0|%0, %2}"
8352   [(set_attr "type" "imul")
8353    (set_attr "prefix_0f" "0,0,1")
8354    (set (attr "athlon_decode")
8355         (cond [(eq_attr "cpu" "athlon")
8356                   (const_string "vector")
8357                (eq_attr "alternative" "1")
8358                   (const_string "vector")
8359                (and (eq_attr "alternative" "2")
8360                     (match_operand 1 "memory_operand" ""))
8361                   (const_string "vector")]
8362               (const_string "direct")))
8363    (set (attr "amdfam10_decode")
8364         (cond [(and (eq_attr "alternative" "0,1")
8365                     (match_operand 1 "memory_operand" ""))
8366                   (const_string "vector")]
8367               (const_string "direct")))
8368    (set_attr "mode" "DI")])
8369
8370 (define_expand "mulsi3"
8371   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8372                    (mult:SI (match_operand:SI 1 "register_operand" "")
8373                             (match_operand:SI 2 "general_operand" "")))
8374               (clobber (reg:CC FLAGS_REG))])]
8375   ""
8376   "")
8377
8378 ;; On AMDFAM10
8379 ;; IMUL reg32, reg32, imm8      Direct
8380 ;; IMUL reg32, mem32, imm8      VectorPath
8381 ;; IMUL reg32, reg32, imm32     Direct
8382 ;; IMUL reg32, mem32, imm32     VectorPath
8383 ;; IMUL reg32, reg32            Direct
8384 ;; IMUL reg32, mem32            Direct
8385
8386 (define_insn "*mulsi3_1"
8387   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
8388         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8389                  (match_operand:SI 2 "general_operand" "K,i,mr")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8392   "@
8393    imul{l}\t{%2, %1, %0|%0, %1, %2}
8394    imul{l}\t{%2, %1, %0|%0, %1, %2}
8395    imul{l}\t{%2, %0|%0, %2}"
8396   [(set_attr "type" "imul")
8397    (set_attr "prefix_0f" "0,0,1")
8398    (set (attr "athlon_decode")
8399         (cond [(eq_attr "cpu" "athlon")
8400                   (const_string "vector")
8401                (eq_attr "alternative" "1")
8402                   (const_string "vector")
8403                (and (eq_attr "alternative" "2")
8404                     (match_operand 1 "memory_operand" ""))
8405                   (const_string "vector")]
8406               (const_string "direct")))
8407    (set (attr "amdfam10_decode")
8408         (cond [(and (eq_attr "alternative" "0,1")
8409                     (match_operand 1 "memory_operand" ""))
8410                   (const_string "vector")]
8411               (const_string "direct")))
8412    (set_attr "mode" "SI")])
8413
8414 (define_insn "*mulsi3_1_zext"
8415   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8416         (zero_extend:DI
8417           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8418                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
8419    (clobber (reg:CC FLAGS_REG))]
8420   "TARGET_64BIT
8421    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8422   "@
8423    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8424    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8425    imul{l}\t{%2, %k0|%k0, %2}"
8426   [(set_attr "type" "imul")
8427    (set_attr "prefix_0f" "0,0,1")
8428    (set (attr "athlon_decode")
8429         (cond [(eq_attr "cpu" "athlon")
8430                   (const_string "vector")
8431                (eq_attr "alternative" "1")
8432                   (const_string "vector")
8433                (and (eq_attr "alternative" "2")
8434                     (match_operand 1 "memory_operand" ""))
8435                   (const_string "vector")]
8436               (const_string "direct")))
8437    (set (attr "amdfam10_decode")
8438         (cond [(and (eq_attr "alternative" "0,1")
8439                     (match_operand 1 "memory_operand" ""))
8440                   (const_string "vector")]
8441               (const_string "direct")))
8442    (set_attr "mode" "SI")])
8443
8444 (define_expand "mulhi3"
8445   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8446                    (mult:HI (match_operand:HI 1 "register_operand" "")
8447                             (match_operand:HI 2 "general_operand" "")))
8448               (clobber (reg:CC FLAGS_REG))])]
8449   "TARGET_HIMODE_MATH"
8450   "")
8451
8452 ;; On AMDFAM10
8453 ;; IMUL reg16, reg16, imm8      VectorPath
8454 ;; IMUL reg16, mem16, imm8      VectorPath
8455 ;; IMUL reg16, reg16, imm16     VectorPath
8456 ;; IMUL reg16, mem16, imm16     VectorPath
8457 ;; IMUL reg16, reg16            Direct
8458 ;; IMUL reg16, mem16            Direct
8459 (define_insn "*mulhi3_1"
8460   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8461         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8462                  (match_operand:HI 2 "general_operand" "K,n,mr")))
8463    (clobber (reg:CC FLAGS_REG))]
8464   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8465   "@
8466    imul{w}\t{%2, %1, %0|%0, %1, %2}
8467    imul{w}\t{%2, %1, %0|%0, %1, %2}
8468    imul{w}\t{%2, %0|%0, %2}"
8469   [(set_attr "type" "imul")
8470    (set_attr "prefix_0f" "0,0,1")
8471    (set (attr "athlon_decode")
8472         (cond [(eq_attr "cpu" "athlon")
8473                   (const_string "vector")
8474                (eq_attr "alternative" "1,2")
8475                   (const_string "vector")]
8476               (const_string "direct")))
8477    (set (attr "amdfam10_decode")
8478         (cond [(eq_attr "alternative" "0,1")
8479                   (const_string "vector")]
8480               (const_string "direct")))
8481    (set_attr "mode" "HI")])
8482
8483 (define_expand "mulqi3"
8484   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8485                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8486                             (match_operand:QI 2 "register_operand" "")))
8487               (clobber (reg:CC FLAGS_REG))])]
8488   "TARGET_QIMODE_MATH"
8489   "")
8490
8491 ;;On AMDFAM10
8492 ;; MUL reg8     Direct
8493 ;; MUL mem8     Direct
8494
8495 (define_insn "*mulqi3_1"
8496   [(set (match_operand:QI 0 "register_operand" "=a")
8497         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8498                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8499    (clobber (reg:CC FLAGS_REG))]
8500   "TARGET_QIMODE_MATH
8501    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8502   "mul{b}\t%2"
8503   [(set_attr "type" "imul")
8504    (set_attr "length_immediate" "0")
8505    (set (attr "athlon_decode")
8506      (if_then_else (eq_attr "cpu" "athlon")
8507         (const_string "vector")
8508         (const_string "direct")))
8509    (set_attr "amdfam10_decode" "direct")
8510    (set_attr "mode" "QI")])
8511
8512 (define_expand "umulqihi3"
8513   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8514                    (mult:HI (zero_extend:HI
8515                               (match_operand:QI 1 "nonimmediate_operand" ""))
8516                             (zero_extend:HI
8517                               (match_operand:QI 2 "register_operand" ""))))
8518               (clobber (reg:CC FLAGS_REG))])]
8519   "TARGET_QIMODE_MATH"
8520   "")
8521
8522 (define_insn "*umulqihi3_1"
8523   [(set (match_operand:HI 0 "register_operand" "=a")
8524         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8525                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8526    (clobber (reg:CC FLAGS_REG))]
8527   "TARGET_QIMODE_MATH
8528    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8529   "mul{b}\t%2"
8530   [(set_attr "type" "imul")
8531    (set_attr "length_immediate" "0")
8532    (set (attr "athlon_decode")
8533      (if_then_else (eq_attr "cpu" "athlon")
8534         (const_string "vector")
8535         (const_string "direct")))
8536    (set_attr "amdfam10_decode" "direct")
8537    (set_attr "mode" "QI")])
8538
8539 (define_expand "mulqihi3"
8540   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8541                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8542                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8543               (clobber (reg:CC FLAGS_REG))])]
8544   "TARGET_QIMODE_MATH"
8545   "")
8546
8547 (define_insn "*mulqihi3_insn"
8548   [(set (match_operand:HI 0 "register_operand" "=a")
8549         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8550                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8551    (clobber (reg:CC FLAGS_REG))]
8552   "TARGET_QIMODE_MATH
8553    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8554   "imul{b}\t%2"
8555   [(set_attr "type" "imul")
8556    (set_attr "length_immediate" "0")
8557    (set (attr "athlon_decode")
8558      (if_then_else (eq_attr "cpu" "athlon")
8559         (const_string "vector")
8560         (const_string "direct")))
8561    (set_attr "amdfam10_decode" "direct")
8562    (set_attr "mode" "QI")])
8563
8564 (define_expand "umulditi3"
8565   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8566                    (mult:TI (zero_extend:TI
8567                               (match_operand:DI 1 "nonimmediate_operand" ""))
8568                             (zero_extend:TI
8569                               (match_operand:DI 2 "register_operand" ""))))
8570               (clobber (reg:CC FLAGS_REG))])]
8571   "TARGET_64BIT"
8572   "")
8573
8574 (define_insn "*umulditi3_insn"
8575   [(set (match_operand:TI 0 "register_operand" "=A")
8576         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8577                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8578    (clobber (reg:CC FLAGS_REG))]
8579   "TARGET_64BIT
8580    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8581   "mul{q}\t%2"
8582   [(set_attr "type" "imul")
8583    (set_attr "length_immediate" "0")
8584    (set (attr "athlon_decode")
8585      (if_then_else (eq_attr "cpu" "athlon")
8586         (const_string "vector")
8587         (const_string "double")))
8588    (set_attr "amdfam10_decode" "double")
8589    (set_attr "mode" "DI")])
8590
8591 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8592 (define_expand "umulsidi3"
8593   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8594                    (mult:DI (zero_extend:DI
8595                               (match_operand:SI 1 "nonimmediate_operand" ""))
8596                             (zero_extend:DI
8597                               (match_operand:SI 2 "register_operand" ""))))
8598               (clobber (reg:CC FLAGS_REG))])]
8599   "!TARGET_64BIT"
8600   "")
8601
8602 (define_insn "*umulsidi3_insn"
8603   [(set (match_operand:DI 0 "register_operand" "=A")
8604         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8605                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8606    (clobber (reg:CC FLAGS_REG))]
8607   "!TARGET_64BIT
8608    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8609   "mul{l}\t%2"
8610   [(set_attr "type" "imul")
8611    (set_attr "length_immediate" "0")
8612    (set (attr "athlon_decode")
8613      (if_then_else (eq_attr "cpu" "athlon")
8614         (const_string "vector")
8615         (const_string "double")))
8616    (set_attr "amdfam10_decode" "double")
8617    (set_attr "mode" "SI")])
8618
8619 (define_expand "mulditi3"
8620   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8621                    (mult:TI (sign_extend:TI
8622                               (match_operand:DI 1 "nonimmediate_operand" ""))
8623                             (sign_extend:TI
8624                               (match_operand:DI 2 "register_operand" ""))))
8625               (clobber (reg:CC FLAGS_REG))])]
8626   "TARGET_64BIT"
8627   "")
8628
8629 (define_insn "*mulditi3_insn"
8630   [(set (match_operand:TI 0 "register_operand" "=A")
8631         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8632                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "TARGET_64BIT
8635    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8636   "imul{q}\t%2"
8637   [(set_attr "type" "imul")
8638    (set_attr "length_immediate" "0")
8639    (set (attr "athlon_decode")
8640      (if_then_else (eq_attr "cpu" "athlon")
8641         (const_string "vector")
8642         (const_string "double")))
8643    (set_attr "amdfam10_decode" "double")
8644    (set_attr "mode" "DI")])
8645
8646 (define_expand "mulsidi3"
8647   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8648                    (mult:DI (sign_extend:DI
8649                               (match_operand:SI 1 "nonimmediate_operand" ""))
8650                             (sign_extend:DI
8651                               (match_operand:SI 2 "register_operand" ""))))
8652               (clobber (reg:CC FLAGS_REG))])]
8653   "!TARGET_64BIT"
8654   "")
8655
8656 (define_insn "*mulsidi3_insn"
8657   [(set (match_operand:DI 0 "register_operand" "=A")
8658         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8659                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8660    (clobber (reg:CC FLAGS_REG))]
8661   "!TARGET_64BIT
8662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8663   "imul{l}\t%2"
8664   [(set_attr "type" "imul")
8665    (set_attr "length_immediate" "0")
8666    (set (attr "athlon_decode")
8667      (if_then_else (eq_attr "cpu" "athlon")
8668         (const_string "vector")
8669         (const_string "double")))
8670    (set_attr "amdfam10_decode" "double")
8671    (set_attr "mode" "SI")])
8672
8673 (define_expand "umuldi3_highpart"
8674   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8675                    (truncate:DI
8676                      (lshiftrt:TI
8677                        (mult:TI (zero_extend:TI
8678                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8679                                 (zero_extend:TI
8680                                   (match_operand:DI 2 "register_operand" "")))
8681                        (const_int 64))))
8682               (clobber (match_scratch:DI 3 ""))
8683               (clobber (reg:CC FLAGS_REG))])]
8684   "TARGET_64BIT"
8685   "")
8686
8687 (define_insn "*umuldi3_highpart_rex64"
8688   [(set (match_operand:DI 0 "register_operand" "=d")
8689         (truncate:DI
8690           (lshiftrt:TI
8691             (mult:TI (zero_extend:TI
8692                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8693                      (zero_extend:TI
8694                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8695             (const_int 64))))
8696    (clobber (match_scratch:DI 3 "=1"))
8697    (clobber (reg:CC FLAGS_REG))]
8698   "TARGET_64BIT
8699    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8700   "mul{q}\t%2"
8701   [(set_attr "type" "imul")
8702    (set_attr "length_immediate" "0")
8703    (set (attr "athlon_decode")
8704      (if_then_else (eq_attr "cpu" "athlon")
8705         (const_string "vector")
8706         (const_string "double")))
8707    (set_attr "amdfam10_decode" "double")
8708    (set_attr "mode" "DI")])
8709
8710 (define_expand "umulsi3_highpart"
8711   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8712                    (truncate:SI
8713                      (lshiftrt:DI
8714                        (mult:DI (zero_extend:DI
8715                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8716                                 (zero_extend:DI
8717                                   (match_operand:SI 2 "register_operand" "")))
8718                        (const_int 32))))
8719               (clobber (match_scratch:SI 3 ""))
8720               (clobber (reg:CC FLAGS_REG))])]
8721   ""
8722   "")
8723
8724 (define_insn "*umulsi3_highpart_insn"
8725   [(set (match_operand:SI 0 "register_operand" "=d")
8726         (truncate:SI
8727           (lshiftrt:DI
8728             (mult:DI (zero_extend:DI
8729                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8730                      (zero_extend:DI
8731                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8732             (const_int 32))))
8733    (clobber (match_scratch:SI 3 "=1"))
8734    (clobber (reg:CC FLAGS_REG))]
8735   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8736   "mul{l}\t%2"
8737   [(set_attr "type" "imul")
8738    (set_attr "length_immediate" "0")
8739    (set (attr "athlon_decode")
8740      (if_then_else (eq_attr "cpu" "athlon")
8741         (const_string "vector")
8742         (const_string "double")))
8743    (set_attr "amdfam10_decode" "double")
8744    (set_attr "mode" "SI")])
8745
8746 (define_insn "*umulsi3_highpart_zext"
8747   [(set (match_operand:DI 0 "register_operand" "=d")
8748         (zero_extend:DI (truncate:SI
8749           (lshiftrt:DI
8750             (mult:DI (zero_extend:DI
8751                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8752                      (zero_extend:DI
8753                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8754             (const_int 32)))))
8755    (clobber (match_scratch:SI 3 "=1"))
8756    (clobber (reg:CC FLAGS_REG))]
8757   "TARGET_64BIT
8758    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8759   "mul{l}\t%2"
8760   [(set_attr "type" "imul")
8761    (set_attr "length_immediate" "0")
8762    (set (attr "athlon_decode")
8763      (if_then_else (eq_attr "cpu" "athlon")
8764         (const_string "vector")
8765         (const_string "double")))
8766    (set_attr "amdfam10_decode" "double")
8767    (set_attr "mode" "SI")])
8768
8769 (define_expand "smuldi3_highpart"
8770   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8771                    (truncate:DI
8772                      (lshiftrt:TI
8773                        (mult:TI (sign_extend:TI
8774                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8775                                 (sign_extend:TI
8776                                   (match_operand:DI 2 "register_operand" "")))
8777                        (const_int 64))))
8778               (clobber (match_scratch:DI 3 ""))
8779               (clobber (reg:CC FLAGS_REG))])]
8780   "TARGET_64BIT"
8781   "")
8782
8783 (define_insn "*smuldi3_highpart_rex64"
8784   [(set (match_operand:DI 0 "register_operand" "=d")
8785         (truncate:DI
8786           (lshiftrt:TI
8787             (mult:TI (sign_extend:TI
8788                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8789                      (sign_extend:TI
8790                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8791             (const_int 64))))
8792    (clobber (match_scratch:DI 3 "=1"))
8793    (clobber (reg:CC FLAGS_REG))]
8794   "TARGET_64BIT
8795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8796   "imul{q}\t%2"
8797   [(set_attr "type" "imul")
8798    (set (attr "athlon_decode")
8799      (if_then_else (eq_attr "cpu" "athlon")
8800         (const_string "vector")
8801         (const_string "double")))
8802    (set_attr "amdfam10_decode" "double")
8803    (set_attr "mode" "DI")])
8804
8805 (define_expand "smulsi3_highpart"
8806   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8807                    (truncate:SI
8808                      (lshiftrt:DI
8809                        (mult:DI (sign_extend:DI
8810                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8811                                 (sign_extend:DI
8812                                   (match_operand:SI 2 "register_operand" "")))
8813                        (const_int 32))))
8814               (clobber (match_scratch:SI 3 ""))
8815               (clobber (reg:CC FLAGS_REG))])]
8816   ""
8817   "")
8818
8819 (define_insn "*smulsi3_highpart_insn"
8820   [(set (match_operand:SI 0 "register_operand" "=d")
8821         (truncate:SI
8822           (lshiftrt:DI
8823             (mult:DI (sign_extend:DI
8824                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8825                      (sign_extend:DI
8826                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8827             (const_int 32))))
8828    (clobber (match_scratch:SI 3 "=1"))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8831   "imul{l}\t%2"
8832   [(set_attr "type" "imul")
8833    (set (attr "athlon_decode")
8834      (if_then_else (eq_attr "cpu" "athlon")
8835         (const_string "vector")
8836         (const_string "double")))
8837    (set_attr "amdfam10_decode" "double")
8838    (set_attr "mode" "SI")])
8839
8840 (define_insn "*smulsi3_highpart_zext"
8841   [(set (match_operand:DI 0 "register_operand" "=d")
8842         (zero_extend:DI (truncate:SI
8843           (lshiftrt:DI
8844             (mult:DI (sign_extend:DI
8845                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8846                      (sign_extend:DI
8847                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8848             (const_int 32)))))
8849    (clobber (match_scratch:SI 3 "=1"))
8850    (clobber (reg:CC FLAGS_REG))]
8851   "TARGET_64BIT
8852    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8853   "imul{l}\t%2"
8854   [(set_attr "type" "imul")
8855    (set (attr "athlon_decode")
8856      (if_then_else (eq_attr "cpu" "athlon")
8857         (const_string "vector")
8858         (const_string "double")))
8859    (set_attr "amdfam10_decode" "double")
8860    (set_attr "mode" "SI")])
8861
8862 ;; The patterns that match these are at the end of this file.
8863
8864 (define_expand "mulxf3"
8865   [(set (match_operand:XF 0 "register_operand" "")
8866         (mult:XF (match_operand:XF 1 "register_operand" "")
8867                  (match_operand:XF 2 "register_operand" "")))]
8868   "TARGET_80387"
8869   "")
8870
8871 (define_expand "mul<mode>3"
8872   [(set (match_operand:MODEF 0 "register_operand" "")
8873         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8874                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8875   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8876     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8877   "")
8878
8879 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8880
8881 \f
8882 ;; Divide instructions
8883
8884 (define_insn "divqi3"
8885   [(set (match_operand:QI 0 "register_operand" "=a")
8886         (div:QI (match_operand:HI 1 "register_operand" "0")
8887                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8888    (clobber (reg:CC FLAGS_REG))]
8889   "TARGET_QIMODE_MATH"
8890   "idiv{b}\t%2"
8891   [(set_attr "type" "idiv")
8892    (set_attr "mode" "QI")])
8893
8894 (define_insn "udivqi3"
8895   [(set (match_operand:QI 0 "register_operand" "=a")
8896         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8897                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8898    (clobber (reg:CC FLAGS_REG))]
8899   "TARGET_QIMODE_MATH"
8900   "div{b}\t%2"
8901   [(set_attr "type" "idiv")
8902    (set_attr "mode" "QI")])
8903
8904 ;; The patterns that match these are at the end of this file.
8905
8906 (define_expand "divxf3"
8907   [(set (match_operand:XF 0 "register_operand" "")
8908         (div:XF (match_operand:XF 1 "register_operand" "")
8909                 (match_operand:XF 2 "register_operand" "")))]
8910   "TARGET_80387"
8911   "")
8912
8913 (define_expand "divdf3"
8914   [(set (match_operand:DF 0 "register_operand" "")
8915         (div:DF (match_operand:DF 1 "register_operand" "")
8916                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8917    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8918     || (TARGET_SSE2 && TARGET_SSE_MATH)"
8919    "")
8920
8921 (define_expand "divsf3"
8922   [(set (match_operand:SF 0 "register_operand" "")
8923         (div:SF (match_operand:SF 1 "register_operand" "")
8924                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8925   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8926     || TARGET_SSE_MATH"
8927 {
8928   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8929       && flag_finite_math_only && !flag_trapping_math
8930       && flag_unsafe_math_optimizations)
8931     {
8932       ix86_emit_swdivsf (operands[0], operands[1],
8933                          operands[2], SFmode);
8934       DONE;
8935     }
8936 })
8937 \f
8938 ;; Remainder instructions.
8939
8940 (define_expand "divmoddi4"
8941   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8942                    (div:DI (match_operand:DI 1 "register_operand" "")
8943                            (match_operand:DI 2 "nonimmediate_operand" "")))
8944               (set (match_operand:DI 3 "register_operand" "")
8945                    (mod:DI (match_dup 1) (match_dup 2)))
8946               (clobber (reg:CC FLAGS_REG))])]
8947   "TARGET_64BIT"
8948   "")
8949
8950 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8951 ;; Penalize eax case slightly because it results in worse scheduling
8952 ;; of code.
8953 (define_insn "*divmoddi4_nocltd_rex64"
8954   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8955         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8956                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8957    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8958         (mod:DI (match_dup 2) (match_dup 3)))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8961   "#"
8962   [(set_attr "type" "multi")])
8963
8964 (define_insn "*divmoddi4_cltd_rex64"
8965   [(set (match_operand:DI 0 "register_operand" "=a")
8966         (div:DI (match_operand:DI 2 "register_operand" "a")
8967                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8968    (set (match_operand:DI 1 "register_operand" "=&d")
8969         (mod:DI (match_dup 2) (match_dup 3)))
8970    (clobber (reg:CC FLAGS_REG))]
8971   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8972   "#"
8973   [(set_attr "type" "multi")])
8974
8975 (define_insn "*divmoddi_noext_rex64"
8976   [(set (match_operand:DI 0 "register_operand" "=a")
8977         (div:DI (match_operand:DI 1 "register_operand" "0")
8978                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8979    (set (match_operand:DI 3 "register_operand" "=d")
8980         (mod:DI (match_dup 1) (match_dup 2)))
8981    (use (match_operand:DI 4 "register_operand" "3"))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "TARGET_64BIT"
8984   "idiv{q}\t%2"
8985   [(set_attr "type" "idiv")
8986    (set_attr "mode" "DI")])
8987
8988 (define_split
8989   [(set (match_operand:DI 0 "register_operand" "")
8990         (div:DI (match_operand:DI 1 "register_operand" "")
8991                 (match_operand:DI 2 "nonimmediate_operand" "")))
8992    (set (match_operand:DI 3 "register_operand" "")
8993         (mod:DI (match_dup 1) (match_dup 2)))
8994    (clobber (reg:CC FLAGS_REG))]
8995   "TARGET_64BIT && reload_completed"
8996   [(parallel [(set (match_dup 3)
8997                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8998               (clobber (reg:CC FLAGS_REG))])
8999    (parallel [(set (match_dup 0)
9000                    (div:DI (reg:DI 0) (match_dup 2)))
9001               (set (match_dup 3)
9002                    (mod:DI (reg:DI 0) (match_dup 2)))
9003               (use (match_dup 3))
9004               (clobber (reg:CC FLAGS_REG))])]
9005 {
9006   /* Avoid use of cltd in favor of a mov+shift.  */
9007   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9008     {
9009       if (true_regnum (operands[1]))
9010         emit_move_insn (operands[0], operands[1]);
9011       else
9012         emit_move_insn (operands[3], operands[1]);
9013       operands[4] = operands[3];
9014     }
9015   else
9016     {
9017       gcc_assert (!true_regnum (operands[1]));
9018       operands[4] = operands[1];
9019     }
9020 })
9021
9022
9023 (define_expand "divmodsi4"
9024   [(parallel [(set (match_operand:SI 0 "register_operand" "")
9025                    (div:SI (match_operand:SI 1 "register_operand" "")
9026                            (match_operand:SI 2 "nonimmediate_operand" "")))
9027               (set (match_operand:SI 3 "register_operand" "")
9028                    (mod:SI (match_dup 1) (match_dup 2)))
9029               (clobber (reg:CC FLAGS_REG))])]
9030   ""
9031   "")
9032
9033 ;; Allow to come the parameter in eax or edx to avoid extra moves.
9034 ;; Penalize eax case slightly because it results in worse scheduling
9035 ;; of code.
9036 (define_insn "*divmodsi4_nocltd"
9037   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
9038         (div:SI (match_operand:SI 2 "register_operand" "1,0")
9039                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
9040    (set (match_operand:SI 1 "register_operand" "=&d,&d")
9041         (mod:SI (match_dup 2) (match_dup 3)))
9042    (clobber (reg:CC FLAGS_REG))]
9043   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
9044   "#"
9045   [(set_attr "type" "multi")])
9046
9047 (define_insn "*divmodsi4_cltd"
9048   [(set (match_operand:SI 0 "register_operand" "=a")
9049         (div:SI (match_operand:SI 2 "register_operand" "a")
9050                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
9051    (set (match_operand:SI 1 "register_operand" "=&d")
9052         (mod:SI (match_dup 2) (match_dup 3)))
9053    (clobber (reg:CC FLAGS_REG))]
9054   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
9055   "#"
9056   [(set_attr "type" "multi")])
9057
9058 (define_insn "*divmodsi_noext"
9059   [(set (match_operand:SI 0 "register_operand" "=a")
9060         (div:SI (match_operand:SI 1 "register_operand" "0")
9061                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9062    (set (match_operand:SI 3 "register_operand" "=d")
9063         (mod:SI (match_dup 1) (match_dup 2)))
9064    (use (match_operand:SI 4 "register_operand" "3"))
9065    (clobber (reg:CC FLAGS_REG))]
9066   ""
9067   "idiv{l}\t%2"
9068   [(set_attr "type" "idiv")
9069    (set_attr "mode" "SI")])
9070
9071 (define_split
9072   [(set (match_operand:SI 0 "register_operand" "")
9073         (div:SI (match_operand:SI 1 "register_operand" "")
9074                 (match_operand:SI 2 "nonimmediate_operand" "")))
9075    (set (match_operand:SI 3 "register_operand" "")
9076         (mod:SI (match_dup 1) (match_dup 2)))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "reload_completed"
9079   [(parallel [(set (match_dup 3)
9080                    (ashiftrt:SI (match_dup 4) (const_int 31)))
9081               (clobber (reg:CC FLAGS_REG))])
9082    (parallel [(set (match_dup 0)
9083                    (div:SI (reg:SI 0) (match_dup 2)))
9084               (set (match_dup 3)
9085                    (mod:SI (reg:SI 0) (match_dup 2)))
9086               (use (match_dup 3))
9087               (clobber (reg:CC FLAGS_REG))])]
9088 {
9089   /* Avoid use of cltd in favor of a mov+shift.  */
9090   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9091     {
9092       if (true_regnum (operands[1]))
9093         emit_move_insn (operands[0], operands[1]);
9094       else
9095         emit_move_insn (operands[3], operands[1]);
9096       operands[4] = operands[3];
9097     }
9098   else
9099     {
9100       gcc_assert (!true_regnum (operands[1]));
9101       operands[4] = operands[1];
9102     }
9103 })
9104 ;; %%% Split me.
9105 (define_insn "divmodhi4"
9106   [(set (match_operand:HI 0 "register_operand" "=a")
9107         (div:HI (match_operand:HI 1 "register_operand" "0")
9108                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9109    (set (match_operand:HI 3 "register_operand" "=&d")
9110         (mod:HI (match_dup 1) (match_dup 2)))
9111    (clobber (reg:CC FLAGS_REG))]
9112   "TARGET_HIMODE_MATH"
9113   "cwtd\;idiv{w}\t%2"
9114   [(set_attr "type" "multi")
9115    (set_attr "length_immediate" "0")
9116    (set_attr "mode" "SI")])
9117
9118 (define_insn "udivmoddi4"
9119   [(set (match_operand:DI 0 "register_operand" "=a")
9120         (udiv:DI (match_operand:DI 1 "register_operand" "0")
9121                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
9122    (set (match_operand:DI 3 "register_operand" "=&d")
9123         (umod:DI (match_dup 1) (match_dup 2)))
9124    (clobber (reg:CC FLAGS_REG))]
9125   "TARGET_64BIT"
9126   "xor{q}\t%3, %3\;div{q}\t%2"
9127   [(set_attr "type" "multi")
9128    (set_attr "length_immediate" "0")
9129    (set_attr "mode" "DI")])
9130
9131 (define_insn "*udivmoddi4_noext"
9132   [(set (match_operand:DI 0 "register_operand" "=a")
9133         (udiv:DI (match_operand:DI 1 "register_operand" "0")
9134                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
9135    (set (match_operand:DI 3 "register_operand" "=d")
9136         (umod:DI (match_dup 1) (match_dup 2)))
9137    (use (match_dup 3))
9138    (clobber (reg:CC FLAGS_REG))]
9139   "TARGET_64BIT"
9140   "div{q}\t%2"
9141   [(set_attr "type" "idiv")
9142    (set_attr "mode" "DI")])
9143
9144 (define_split
9145   [(set (match_operand:DI 0 "register_operand" "")
9146         (udiv:DI (match_operand:DI 1 "register_operand" "")
9147                  (match_operand:DI 2 "nonimmediate_operand" "")))
9148    (set (match_operand:DI 3 "register_operand" "")
9149         (umod:DI (match_dup 1) (match_dup 2)))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "TARGET_64BIT && reload_completed"
9152   [(set (match_dup 3) (const_int 0))
9153    (parallel [(set (match_dup 0)
9154                    (udiv:DI (match_dup 1) (match_dup 2)))
9155               (set (match_dup 3)
9156                    (umod:DI (match_dup 1) (match_dup 2)))
9157               (use (match_dup 3))
9158               (clobber (reg:CC FLAGS_REG))])]
9159   "")
9160
9161 (define_insn "udivmodsi4"
9162   [(set (match_operand:SI 0 "register_operand" "=a")
9163         (udiv:SI (match_operand:SI 1 "register_operand" "0")
9164                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
9165    (set (match_operand:SI 3 "register_operand" "=&d")
9166         (umod:SI (match_dup 1) (match_dup 2)))
9167    (clobber (reg:CC FLAGS_REG))]
9168   ""
9169   "xor{l}\t%3, %3\;div{l}\t%2"
9170   [(set_attr "type" "multi")
9171    (set_attr "length_immediate" "0")
9172    (set_attr "mode" "SI")])
9173
9174 (define_insn "*udivmodsi4_noext"
9175   [(set (match_operand:SI 0 "register_operand" "=a")
9176         (udiv:SI (match_operand:SI 1 "register_operand" "0")
9177                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
9178    (set (match_operand:SI 3 "register_operand" "=d")
9179         (umod:SI (match_dup 1) (match_dup 2)))
9180    (use (match_dup 3))
9181    (clobber (reg:CC FLAGS_REG))]
9182   ""
9183   "div{l}\t%2"
9184   [(set_attr "type" "idiv")
9185    (set_attr "mode" "SI")])
9186
9187 (define_split
9188   [(set (match_operand:SI 0 "register_operand" "")
9189         (udiv:SI (match_operand:SI 1 "register_operand" "")
9190                  (match_operand:SI 2 "nonimmediate_operand" "")))
9191    (set (match_operand:SI 3 "register_operand" "")
9192         (umod:SI (match_dup 1) (match_dup 2)))
9193    (clobber (reg:CC FLAGS_REG))]
9194   "reload_completed"
9195   [(set (match_dup 3) (const_int 0))
9196    (parallel [(set (match_dup 0)
9197                    (udiv:SI (match_dup 1) (match_dup 2)))
9198               (set (match_dup 3)
9199                    (umod:SI (match_dup 1) (match_dup 2)))
9200               (use (match_dup 3))
9201               (clobber (reg:CC FLAGS_REG))])]
9202   "")
9203
9204 (define_expand "udivmodhi4"
9205   [(set (match_dup 4) (const_int 0))
9206    (parallel [(set (match_operand:HI 0 "register_operand" "")
9207                    (udiv:HI (match_operand:HI 1 "register_operand" "")
9208                             (match_operand:HI 2 "nonimmediate_operand" "")))
9209               (set (match_operand:HI 3 "register_operand" "")
9210                    (umod:HI (match_dup 1) (match_dup 2)))
9211               (use (match_dup 4))
9212               (clobber (reg:CC FLAGS_REG))])]
9213   "TARGET_HIMODE_MATH"
9214   "operands[4] = gen_reg_rtx (HImode);")
9215
9216 (define_insn "*udivmodhi_noext"
9217   [(set (match_operand:HI 0 "register_operand" "=a")
9218         (udiv:HI (match_operand:HI 1 "register_operand" "0")
9219                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
9220    (set (match_operand:HI 3 "register_operand" "=d")
9221         (umod:HI (match_dup 1) (match_dup 2)))
9222    (use (match_operand:HI 4 "register_operand" "3"))
9223    (clobber (reg:CC FLAGS_REG))]
9224   ""
9225   "div{w}\t%2"
9226   [(set_attr "type" "idiv")
9227    (set_attr "mode" "HI")])
9228
9229 ;; We cannot use div/idiv for double division, because it causes
9230 ;; "division by zero" on the overflow and that's not what we expect
9231 ;; from truncate.  Because true (non truncating) double division is
9232 ;; never generated, we can't create this insn anyway.
9233 ;
9234 ;(define_insn ""
9235 ;  [(set (match_operand:SI 0 "register_operand" "=a")
9236 ;       (truncate:SI
9237 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
9238 ;                  (zero_extend:DI
9239 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
9240 ;   (set (match_operand:SI 3 "register_operand" "=d")
9241 ;       (truncate:SI
9242 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
9243 ;   (clobber (reg:CC FLAGS_REG))]
9244 ;  ""
9245 ;  "div{l}\t{%2, %0|%0, %2}"
9246 ;  [(set_attr "type" "idiv")])
9247 \f
9248 ;;- Logical AND instructions
9249
9250 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
9251 ;; Note that this excludes ah.
9252
9253 (define_insn "*testdi_1_rex64"
9254   [(set (reg FLAGS_REG)
9255         (compare
9256           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
9257                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9258           (const_int 0)))]
9259   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9260    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9261   "@
9262    test{l}\t{%k1, %k0|%k0, %k1}
9263    test{l}\t{%k1, %k0|%k0, %k1}
9264    test{q}\t{%1, %0|%0, %1}
9265    test{q}\t{%1, %0|%0, %1}
9266    test{q}\t{%1, %0|%0, %1}"
9267   [(set_attr "type" "test")
9268    (set_attr "modrm" "0,1,0,1,1")
9269    (set_attr "mode" "SI,SI,DI,DI,DI")
9270    (set_attr "pent_pair" "uv,np,uv,np,uv")])
9271
9272 (define_insn "testsi_1"
9273   [(set (reg FLAGS_REG)
9274         (compare
9275           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
9276                   (match_operand:SI 1 "general_operand" "i,i,ri"))
9277           (const_int 0)))]
9278   "ix86_match_ccmode (insn, CCNOmode)
9279    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9280   "test{l}\t{%1, %0|%0, %1}"
9281   [(set_attr "type" "test")
9282    (set_attr "modrm" "0,1,1")
9283    (set_attr "mode" "SI")
9284    (set_attr "pent_pair" "uv,np,uv")])
9285
9286 (define_expand "testsi_ccno_1"
9287   [(set (reg:CCNO FLAGS_REG)
9288         (compare:CCNO
9289           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
9290                   (match_operand:SI 1 "nonmemory_operand" ""))
9291           (const_int 0)))]
9292   ""
9293   "")
9294
9295 (define_insn "*testhi_1"
9296   [(set (reg FLAGS_REG)
9297         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
9298                          (match_operand:HI 1 "general_operand" "n,n,rn"))
9299                  (const_int 0)))]
9300   "ix86_match_ccmode (insn, CCNOmode)
9301    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9302   "test{w}\t{%1, %0|%0, %1}"
9303   [(set_attr "type" "test")
9304    (set_attr "modrm" "0,1,1")
9305    (set_attr "mode" "HI")
9306    (set_attr "pent_pair" "uv,np,uv")])
9307
9308 (define_expand "testqi_ccz_1"
9309   [(set (reg:CCZ FLAGS_REG)
9310         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
9311                              (match_operand:QI 1 "nonmemory_operand" ""))
9312                  (const_int 0)))]
9313   ""
9314   "")
9315
9316 (define_insn "*testqi_1_maybe_si"
9317   [(set (reg FLAGS_REG)
9318         (compare
9319           (and:QI
9320             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
9321             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
9322           (const_int 0)))]
9323    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9324     && ix86_match_ccmode (insn,
9325                          CONST_INT_P (operands[1])
9326                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
9327 {
9328   if (which_alternative == 3)
9329     {
9330       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
9331         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
9332       return "test{l}\t{%1, %k0|%k0, %1}";
9333     }
9334   return "test{b}\t{%1, %0|%0, %1}";
9335 }
9336   [(set_attr "type" "test")
9337    (set_attr "modrm" "0,1,1,1")
9338    (set_attr "mode" "QI,QI,QI,SI")
9339    (set_attr "pent_pair" "uv,np,uv,np")])
9340
9341 (define_insn "*testqi_1"
9342   [(set (reg FLAGS_REG)
9343         (compare
9344           (and:QI
9345             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
9346             (match_operand:QI 1 "general_operand" "n,n,qn"))
9347           (const_int 0)))]
9348   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9349    && ix86_match_ccmode (insn, CCNOmode)"
9350   "test{b}\t{%1, %0|%0, %1}"
9351   [(set_attr "type" "test")
9352    (set_attr "modrm" "0,1,1")
9353    (set_attr "mode" "QI")
9354    (set_attr "pent_pair" "uv,np,uv")])
9355
9356 (define_expand "testqi_ext_ccno_0"
9357   [(set (reg:CCNO FLAGS_REG)
9358         (compare:CCNO
9359           (and:SI
9360             (zero_extract:SI
9361               (match_operand 0 "ext_register_operand" "")
9362               (const_int 8)
9363               (const_int 8))
9364             (match_operand 1 "const_int_operand" ""))
9365           (const_int 0)))]
9366   ""
9367   "")
9368
9369 (define_insn "*testqi_ext_0"
9370   [(set (reg FLAGS_REG)
9371         (compare
9372           (and:SI
9373             (zero_extract:SI
9374               (match_operand 0 "ext_register_operand" "Q")
9375               (const_int 8)
9376               (const_int 8))
9377             (match_operand 1 "const_int_operand" "n"))
9378           (const_int 0)))]
9379   "ix86_match_ccmode (insn, CCNOmode)"
9380   "test{b}\t{%1, %h0|%h0, %1}"
9381   [(set_attr "type" "test")
9382    (set_attr "mode" "QI")
9383    (set_attr "length_immediate" "1")
9384    (set_attr "modrm" "1")
9385    (set_attr "pent_pair" "np")])
9386
9387 (define_insn "*testqi_ext_1"
9388   [(set (reg FLAGS_REG)
9389         (compare
9390           (and:SI
9391             (zero_extract:SI
9392               (match_operand 0 "ext_register_operand" "Q")
9393               (const_int 8)
9394               (const_int 8))
9395             (zero_extend:SI
9396               (match_operand:QI 1 "general_operand" "Qm")))
9397           (const_int 0)))]
9398   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9399    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9400   "test{b}\t{%1, %h0|%h0, %1}"
9401   [(set_attr "type" "test")
9402    (set_attr "mode" "QI")])
9403
9404 (define_insn "*testqi_ext_1_rex64"
9405   [(set (reg FLAGS_REG)
9406         (compare
9407           (and:SI
9408             (zero_extract:SI
9409               (match_operand 0 "ext_register_operand" "Q")
9410               (const_int 8)
9411               (const_int 8))
9412             (zero_extend:SI
9413               (match_operand:QI 1 "register_operand" "Q")))
9414           (const_int 0)))]
9415   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9416   "test{b}\t{%1, %h0|%h0, %1}"
9417   [(set_attr "type" "test")
9418    (set_attr "mode" "QI")])
9419
9420 (define_insn "*testqi_ext_2"
9421   [(set (reg FLAGS_REG)
9422         (compare
9423           (and:SI
9424             (zero_extract:SI
9425               (match_operand 0 "ext_register_operand" "Q")
9426               (const_int 8)
9427               (const_int 8))
9428             (zero_extract:SI
9429               (match_operand 1 "ext_register_operand" "Q")
9430               (const_int 8)
9431               (const_int 8)))
9432           (const_int 0)))]
9433   "ix86_match_ccmode (insn, CCNOmode)"
9434   "test{b}\t{%h1, %h0|%h0, %h1}"
9435   [(set_attr "type" "test")
9436    (set_attr "mode" "QI")])
9437
9438 ;; Combine likes to form bit extractions for some tests.  Humor it.
9439 (define_insn "*testqi_ext_3"
9440   [(set (reg FLAGS_REG)
9441         (compare (zero_extract:SI
9442                    (match_operand 0 "nonimmediate_operand" "rm")
9443                    (match_operand:SI 1 "const_int_operand" "")
9444                    (match_operand:SI 2 "const_int_operand" ""))
9445                  (const_int 0)))]
9446   "ix86_match_ccmode (insn, CCNOmode)
9447    && INTVAL (operands[1]) > 0
9448    && INTVAL (operands[2]) >= 0
9449    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9450    && (GET_MODE (operands[0]) == SImode
9451        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9452        || GET_MODE (operands[0]) == HImode
9453        || GET_MODE (operands[0]) == QImode)"
9454   "#")
9455
9456 (define_insn "*testqi_ext_3_rex64"
9457   [(set (reg FLAGS_REG)
9458         (compare (zero_extract:DI
9459                    (match_operand 0 "nonimmediate_operand" "rm")
9460                    (match_operand:DI 1 "const_int_operand" "")
9461                    (match_operand:DI 2 "const_int_operand" ""))
9462                  (const_int 0)))]
9463   "TARGET_64BIT
9464    && ix86_match_ccmode (insn, CCNOmode)
9465    && INTVAL (operands[1]) > 0
9466    && INTVAL (operands[2]) >= 0
9467    /* Ensure that resulting mask is zero or sign extended operand.  */
9468    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9469        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9470            && INTVAL (operands[1]) > 32))
9471    && (GET_MODE (operands[0]) == SImode
9472        || GET_MODE (operands[0]) == DImode
9473        || GET_MODE (operands[0]) == HImode
9474        || GET_MODE (operands[0]) == QImode)"
9475   "#")
9476
9477 (define_split
9478   [(set (match_operand 0 "flags_reg_operand" "")
9479         (match_operator 1 "compare_operator"
9480           [(zero_extract
9481              (match_operand 2 "nonimmediate_operand" "")
9482              (match_operand 3 "const_int_operand" "")
9483              (match_operand 4 "const_int_operand" ""))
9484            (const_int 0)]))]
9485   "ix86_match_ccmode (insn, CCNOmode)"
9486   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9487 {
9488   rtx val = operands[2];
9489   HOST_WIDE_INT len = INTVAL (operands[3]);
9490   HOST_WIDE_INT pos = INTVAL (operands[4]);
9491   HOST_WIDE_INT mask;
9492   enum machine_mode mode, submode;
9493
9494   mode = GET_MODE (val);
9495   if (MEM_P (val))
9496     {
9497       /* ??? Combine likes to put non-volatile mem extractions in QImode
9498          no matter the size of the test.  So find a mode that works.  */
9499       if (! MEM_VOLATILE_P (val))
9500         {
9501           mode = smallest_mode_for_size (pos + len, MODE_INT);
9502           val = adjust_address (val, mode, 0);
9503         }
9504     }
9505   else if (GET_CODE (val) == SUBREG
9506            && (submode = GET_MODE (SUBREG_REG (val)),
9507                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9508            && pos + len <= GET_MODE_BITSIZE (submode))
9509     {
9510       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9511       mode = submode;
9512       val = SUBREG_REG (val);
9513     }
9514   else if (mode == HImode && pos + len <= 8)
9515     {
9516       /* Small HImode tests can be converted to QImode.  */
9517       mode = QImode;
9518       val = gen_lowpart (QImode, val);
9519     }
9520
9521   if (len == HOST_BITS_PER_WIDE_INT)
9522     mask = -1;
9523   else
9524     mask = ((HOST_WIDE_INT)1 << len) - 1;
9525   mask <<= pos;
9526
9527   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9528 })
9529
9530 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9531 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9532 ;; this is relatively important trick.
9533 ;; Do the conversion only post-reload to avoid limiting of the register class
9534 ;; to QI regs.
9535 (define_split
9536   [(set (match_operand 0 "flags_reg_operand" "")
9537         (match_operator 1 "compare_operator"
9538           [(and (match_operand 2 "register_operand" "")
9539                 (match_operand 3 "const_int_operand" ""))
9540            (const_int 0)]))]
9541    "reload_completed
9542     && QI_REG_P (operands[2])
9543     && GET_MODE (operands[2]) != QImode
9544     && ((ix86_match_ccmode (insn, CCZmode)
9545          && !(INTVAL (operands[3]) & ~(255 << 8)))
9546         || (ix86_match_ccmode (insn, CCNOmode)
9547             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9548   [(set (match_dup 0)
9549         (match_op_dup 1
9550           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9551                    (match_dup 3))
9552            (const_int 0)]))]
9553   "operands[2] = gen_lowpart (SImode, operands[2]);
9554    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9555
9556 (define_split
9557   [(set (match_operand 0 "flags_reg_operand" "")
9558         (match_operator 1 "compare_operator"
9559           [(and (match_operand 2 "nonimmediate_operand" "")
9560                 (match_operand 3 "const_int_operand" ""))
9561            (const_int 0)]))]
9562    "reload_completed
9563     && GET_MODE (operands[2]) != QImode
9564     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9565     && ((ix86_match_ccmode (insn, CCZmode)
9566          && !(INTVAL (operands[3]) & ~255))
9567         || (ix86_match_ccmode (insn, CCNOmode)
9568             && !(INTVAL (operands[3]) & ~127)))"
9569   [(set (match_dup 0)
9570         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9571                          (const_int 0)]))]
9572   "operands[2] = gen_lowpart (QImode, operands[2]);
9573    operands[3] = gen_lowpart (QImode, operands[3]);")
9574
9575
9576 ;; %%% This used to optimize known byte-wide and operations to memory,
9577 ;; and sometimes to QImode registers.  If this is considered useful,
9578 ;; it should be done with splitters.
9579
9580 (define_expand "anddi3"
9581   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9582         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9583                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9584   "TARGET_64BIT"
9585   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9586
9587 (define_insn "*anddi_1_rex64"
9588   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9589         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9590                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9591    (clobber (reg:CC FLAGS_REG))]
9592   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9593 {
9594   switch (get_attr_type (insn))
9595     {
9596     case TYPE_IMOVX:
9597       {
9598         enum machine_mode mode;
9599
9600         gcc_assert (CONST_INT_P (operands[2]));
9601         if (INTVAL (operands[2]) == 0xff)
9602           mode = QImode;
9603         else
9604           {
9605             gcc_assert (INTVAL (operands[2]) == 0xffff);
9606             mode = HImode;
9607           }
9608
9609         operands[1] = gen_lowpart (mode, operands[1]);
9610         if (mode == QImode)
9611           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
9612         else
9613           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
9614       }
9615
9616     default:
9617       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9618       if (get_attr_mode (insn) == MODE_SI)
9619         return "and{l}\t{%k2, %k0|%k0, %k2}";
9620       else
9621         return "and{q}\t{%2, %0|%0, %2}";
9622     }
9623 }
9624   [(set_attr "type" "alu,alu,alu,imovx")
9625    (set_attr "length_immediate" "*,*,*,0")
9626    (set (attr "prefix_rex")
9627      (if_then_else
9628        (and (eq_attr "type" "imovx")
9629             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9630                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
9631        (const_string "1")
9632        (const_string "*")))
9633    (set_attr "mode" "SI,DI,DI,SI")])
9634
9635 (define_insn "*anddi_2"
9636   [(set (reg FLAGS_REG)
9637         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9638                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9639                  (const_int 0)))
9640    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9641         (and:DI (match_dup 1) (match_dup 2)))]
9642   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9643    && ix86_binary_operator_ok (AND, DImode, operands)"
9644   "@
9645    and{l}\t{%k2, %k0|%k0, %k2}
9646    and{q}\t{%2, %0|%0, %2}
9647    and{q}\t{%2, %0|%0, %2}"
9648   [(set_attr "type" "alu")
9649    (set_attr "mode" "SI,DI,DI")])
9650
9651 (define_expand "andsi3"
9652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9653         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9654                 (match_operand:SI 2 "general_operand" "")))]
9655   ""
9656   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9657
9658 (define_insn "*andsi_1"
9659   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9660         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9661                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9662    (clobber (reg:CC FLAGS_REG))]
9663   "ix86_binary_operator_ok (AND, SImode, operands)"
9664 {
9665   switch (get_attr_type (insn))
9666     {
9667     case TYPE_IMOVX:
9668       {
9669         enum machine_mode mode;
9670
9671         gcc_assert (CONST_INT_P (operands[2]));
9672         if (INTVAL (operands[2]) == 0xff)
9673           mode = QImode;
9674         else
9675           {
9676             gcc_assert (INTVAL (operands[2]) == 0xffff);
9677             mode = HImode;
9678           }
9679
9680         operands[1] = gen_lowpart (mode, operands[1]);
9681         if (mode == QImode)
9682           return "movz{bl|x}\t{%1, %0|%0, %1}";
9683         else
9684           return "movz{wl|x}\t{%1, %0|%0, %1}";
9685       }
9686
9687     default:
9688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9689       return "and{l}\t{%2, %0|%0, %2}";
9690     }
9691 }
9692   [(set_attr "type" "alu,alu,imovx")
9693    (set (attr "prefix_rex")
9694      (if_then_else
9695        (and (eq_attr "type" "imovx")
9696             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9697                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
9698        (const_string "1")
9699        (const_string "*")))
9700    (set_attr "length_immediate" "*,*,0")
9701    (set_attr "mode" "SI")])
9702
9703 (define_split
9704   [(set (match_operand 0 "register_operand" "")
9705         (and (match_dup 0)
9706              (const_int -65536)))
9707    (clobber (reg:CC FLAGS_REG))]
9708   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9709   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9710   "operands[1] = gen_lowpart (HImode, operands[0]);")
9711
9712 (define_split
9713   [(set (match_operand 0 "ext_register_operand" "")
9714         (and (match_dup 0)
9715              (const_int -256)))
9716    (clobber (reg:CC FLAGS_REG))]
9717   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9718   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9719   "operands[1] = gen_lowpart (QImode, operands[0]);")
9720
9721 (define_split
9722   [(set (match_operand 0 "ext_register_operand" "")
9723         (and (match_dup 0)
9724              (const_int -65281)))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9727   [(parallel [(set (zero_extract:SI (match_dup 0)
9728                                     (const_int 8)
9729                                     (const_int 8))
9730                    (xor:SI
9731                      (zero_extract:SI (match_dup 0)
9732                                       (const_int 8)
9733                                       (const_int 8))
9734                      (zero_extract:SI (match_dup 0)
9735                                       (const_int 8)
9736                                       (const_int 8))))
9737               (clobber (reg:CC FLAGS_REG))])]
9738   "operands[0] = gen_lowpart (SImode, operands[0]);")
9739
9740 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9741 (define_insn "*andsi_1_zext"
9742   [(set (match_operand:DI 0 "register_operand" "=r")
9743         (zero_extend:DI
9744           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9745                   (match_operand:SI 2 "general_operand" "g"))))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9748   "and{l}\t{%2, %k0|%k0, %2}"
9749   [(set_attr "type" "alu")
9750    (set_attr "mode" "SI")])
9751
9752 (define_insn "*andsi_2"
9753   [(set (reg FLAGS_REG)
9754         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9755                          (match_operand:SI 2 "general_operand" "g,ri"))
9756                  (const_int 0)))
9757    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9758         (and:SI (match_dup 1) (match_dup 2)))]
9759   "ix86_match_ccmode (insn, CCNOmode)
9760    && ix86_binary_operator_ok (AND, SImode, operands)"
9761   "and{l}\t{%2, %0|%0, %2}"
9762   [(set_attr "type" "alu")
9763    (set_attr "mode" "SI")])
9764
9765 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9766 (define_insn "*andsi_2_zext"
9767   [(set (reg FLAGS_REG)
9768         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9769                          (match_operand:SI 2 "general_operand" "g"))
9770                  (const_int 0)))
9771    (set (match_operand:DI 0 "register_operand" "=r")
9772         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9773   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9774    && ix86_binary_operator_ok (AND, SImode, operands)"
9775   "and{l}\t{%2, %k0|%k0, %2}"
9776   [(set_attr "type" "alu")
9777    (set_attr "mode" "SI")])
9778
9779 (define_expand "andhi3"
9780   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9781         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9782                 (match_operand:HI 2 "general_operand" "")))]
9783   "TARGET_HIMODE_MATH"
9784   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9785
9786 (define_insn "*andhi_1"
9787   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9788         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9789                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9790    (clobber (reg:CC FLAGS_REG))]
9791   "ix86_binary_operator_ok (AND, HImode, operands)"
9792 {
9793   switch (get_attr_type (insn))
9794     {
9795     case TYPE_IMOVX:
9796       gcc_assert (CONST_INT_P (operands[2]));
9797       gcc_assert (INTVAL (operands[2]) == 0xff);
9798       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9799
9800     default:
9801       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9802
9803       return "and{w}\t{%2, %0|%0, %2}";
9804     }
9805 }
9806   [(set_attr "type" "alu,alu,imovx")
9807    (set_attr "length_immediate" "*,*,0")
9808    (set (attr "prefix_rex")
9809      (if_then_else
9810        (and (eq_attr "type" "imovx")
9811             (match_operand 1 "ext_QIreg_nomode_operand" ""))
9812        (const_string "1")
9813        (const_string "*")))
9814    (set_attr "mode" "HI,HI,SI")])
9815
9816 (define_insn "*andhi_2"
9817   [(set (reg FLAGS_REG)
9818         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9819                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9820                  (const_int 0)))
9821    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9822         (and:HI (match_dup 1) (match_dup 2)))]
9823   "ix86_match_ccmode (insn, CCNOmode)
9824    && ix86_binary_operator_ok (AND, HImode, operands)"
9825   "and{w}\t{%2, %0|%0, %2}"
9826   [(set_attr "type" "alu")
9827    (set_attr "mode" "HI")])
9828
9829 (define_expand "andqi3"
9830   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9831         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9832                 (match_operand:QI 2 "general_operand" "")))]
9833   "TARGET_QIMODE_MATH"
9834   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9835
9836 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9837 (define_insn "*andqi_1"
9838   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9839         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9840                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9841    (clobber (reg:CC FLAGS_REG))]
9842   "ix86_binary_operator_ok (AND, QImode, operands)"
9843   "@
9844    and{b}\t{%2, %0|%0, %2}
9845    and{b}\t{%2, %0|%0, %2}
9846    and{l}\t{%k2, %k0|%k0, %k2}"
9847   [(set_attr "type" "alu")
9848    (set_attr "mode" "QI,QI,SI")])
9849
9850 (define_insn "*andqi_1_slp"
9851   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9852         (and:QI (match_dup 0)
9853                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9854    (clobber (reg:CC FLAGS_REG))]
9855   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9856    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9857   "and{b}\t{%1, %0|%0, %1}"
9858   [(set_attr "type" "alu1")
9859    (set_attr "mode" "QI")])
9860
9861 (define_insn "*andqi_2_maybe_si"
9862   [(set (reg FLAGS_REG)
9863         (compare (and:QI
9864                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9865                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9866                  (const_int 0)))
9867    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9868         (and:QI (match_dup 1) (match_dup 2)))]
9869   "ix86_binary_operator_ok (AND, QImode, operands)
9870    && ix86_match_ccmode (insn,
9871                          CONST_INT_P (operands[2])
9872                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9873 {
9874   if (which_alternative == 2)
9875     {
9876       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9877         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9878       return "and{l}\t{%2, %k0|%k0, %2}";
9879     }
9880   return "and{b}\t{%2, %0|%0, %2}";
9881 }
9882   [(set_attr "type" "alu")
9883    (set_attr "mode" "QI,QI,SI")])
9884
9885 (define_insn "*andqi_2"
9886   [(set (reg FLAGS_REG)
9887         (compare (and:QI
9888                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9889                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9890                  (const_int 0)))
9891    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9892         (and:QI (match_dup 1) (match_dup 2)))]
9893   "ix86_match_ccmode (insn, CCNOmode)
9894    && ix86_binary_operator_ok (AND, QImode, operands)"
9895   "and{b}\t{%2, %0|%0, %2}"
9896   [(set_attr "type" "alu")
9897    (set_attr "mode" "QI")])
9898
9899 (define_insn "*andqi_2_slp"
9900   [(set (reg FLAGS_REG)
9901         (compare (and:QI
9902                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9903                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9904                  (const_int 0)))
9905    (set (strict_low_part (match_dup 0))
9906         (and:QI (match_dup 0) (match_dup 1)))]
9907   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9908    && ix86_match_ccmode (insn, CCNOmode)
9909    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9910   "and{b}\t{%1, %0|%0, %1}"
9911   [(set_attr "type" "alu1")
9912    (set_attr "mode" "QI")])
9913
9914 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9915 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9916 ;; for a QImode operand, which of course failed.
9917
9918 (define_insn "andqi_ext_0"
9919   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9920                          (const_int 8)
9921                          (const_int 8))
9922         (and:SI
9923           (zero_extract:SI
9924             (match_operand 1 "ext_register_operand" "0")
9925             (const_int 8)
9926             (const_int 8))
9927           (match_operand 2 "const_int_operand" "n")))
9928    (clobber (reg:CC FLAGS_REG))]
9929   ""
9930   "and{b}\t{%2, %h0|%h0, %2}"
9931   [(set_attr "type" "alu")
9932    (set_attr "length_immediate" "1")
9933    (set_attr "modrm" "1")
9934    (set_attr "mode" "QI")])
9935
9936 ;; Generated by peephole translating test to and.  This shows up
9937 ;; often in fp comparisons.
9938
9939 (define_insn "*andqi_ext_0_cc"
9940   [(set (reg FLAGS_REG)
9941         (compare
9942           (and:SI
9943             (zero_extract:SI
9944               (match_operand 1 "ext_register_operand" "0")
9945               (const_int 8)
9946               (const_int 8))
9947             (match_operand 2 "const_int_operand" "n"))
9948           (const_int 0)))
9949    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9950                          (const_int 8)
9951                          (const_int 8))
9952         (and:SI
9953           (zero_extract:SI
9954             (match_dup 1)
9955             (const_int 8)
9956             (const_int 8))
9957           (match_dup 2)))]
9958   "ix86_match_ccmode (insn, CCNOmode)"
9959   "and{b}\t{%2, %h0|%h0, %2}"
9960   [(set_attr "type" "alu")
9961    (set_attr "length_immediate" "1")
9962    (set_attr "modrm" "1")
9963    (set_attr "mode" "QI")])
9964
9965 (define_insn "*andqi_ext_1"
9966   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9967                          (const_int 8)
9968                          (const_int 8))
9969         (and:SI
9970           (zero_extract:SI
9971             (match_operand 1 "ext_register_operand" "0")
9972             (const_int 8)
9973             (const_int 8))
9974           (zero_extend:SI
9975             (match_operand:QI 2 "general_operand" "Qm"))))
9976    (clobber (reg:CC FLAGS_REG))]
9977   "!TARGET_64BIT"
9978   "and{b}\t{%2, %h0|%h0, %2}"
9979   [(set_attr "type" "alu")
9980    (set_attr "length_immediate" "0")
9981    (set_attr "mode" "QI")])
9982
9983 (define_insn "*andqi_ext_1_rex64"
9984   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9985                          (const_int 8)
9986                          (const_int 8))
9987         (and:SI
9988           (zero_extract:SI
9989             (match_operand 1 "ext_register_operand" "0")
9990             (const_int 8)
9991             (const_int 8))
9992           (zero_extend:SI
9993             (match_operand 2 "ext_register_operand" "Q"))))
9994    (clobber (reg:CC FLAGS_REG))]
9995   "TARGET_64BIT"
9996   "and{b}\t{%2, %h0|%h0, %2}"
9997   [(set_attr "type" "alu")
9998    (set_attr "length_immediate" "0")
9999    (set_attr "mode" "QI")])
10000
10001 (define_insn "*andqi_ext_2"
10002   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10003                          (const_int 8)
10004                          (const_int 8))
10005         (and:SI
10006           (zero_extract:SI
10007             (match_operand 1 "ext_register_operand" "%0")
10008             (const_int 8)
10009             (const_int 8))
10010           (zero_extract:SI
10011             (match_operand 2 "ext_register_operand" "Q")
10012             (const_int 8)
10013             (const_int 8))))
10014    (clobber (reg:CC FLAGS_REG))]
10015   ""
10016   "and{b}\t{%h2, %h0|%h0, %h2}"
10017   [(set_attr "type" "alu")
10018    (set_attr "length_immediate" "0")
10019    (set_attr "mode" "QI")])
10020
10021 ;; Convert wide AND instructions with immediate operand to shorter QImode
10022 ;; equivalents when possible.
10023 ;; Don't do the splitting with memory operands, since it introduces risk
10024 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
10025 ;; for size, but that can (should?) be handled by generic code instead.
10026 (define_split
10027   [(set (match_operand 0 "register_operand" "")
10028         (and (match_operand 1 "register_operand" "")
10029              (match_operand 2 "const_int_operand" "")))
10030    (clobber (reg:CC FLAGS_REG))]
10031    "reload_completed
10032     && QI_REG_P (operands[0])
10033     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10034     && !(~INTVAL (operands[2]) & ~(255 << 8))
10035     && GET_MODE (operands[0]) != QImode"
10036   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10037                    (and:SI (zero_extract:SI (match_dup 1)
10038                                             (const_int 8) (const_int 8))
10039                            (match_dup 2)))
10040               (clobber (reg:CC FLAGS_REG))])]
10041   "operands[0] = gen_lowpart (SImode, operands[0]);
10042    operands[1] = gen_lowpart (SImode, operands[1]);
10043    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10044
10045 ;; Since AND can be encoded with sign extended immediate, this is only
10046 ;; profitable when 7th bit is not set.
10047 (define_split
10048   [(set (match_operand 0 "register_operand" "")
10049         (and (match_operand 1 "general_operand" "")
10050              (match_operand 2 "const_int_operand" "")))
10051    (clobber (reg:CC FLAGS_REG))]
10052    "reload_completed
10053     && ANY_QI_REG_P (operands[0])
10054     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10055     && !(~INTVAL (operands[2]) & ~255)
10056     && !(INTVAL (operands[2]) & 128)
10057     && GET_MODE (operands[0]) != QImode"
10058   [(parallel [(set (strict_low_part (match_dup 0))
10059                    (and:QI (match_dup 1)
10060                            (match_dup 2)))
10061               (clobber (reg:CC FLAGS_REG))])]
10062   "operands[0] = gen_lowpart (QImode, operands[0]);
10063    operands[1] = gen_lowpart (QImode, operands[1]);
10064    operands[2] = gen_lowpart (QImode, operands[2]);")
10065 \f
10066 ;; Logical inclusive OR instructions
10067
10068 ;; %%% This used to optimize known byte-wide and operations to memory.
10069 ;; If this is considered useful, it should be done with splitters.
10070
10071 (define_expand "iordi3"
10072   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10073         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
10074                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10075   "TARGET_64BIT"
10076   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
10077
10078 (define_insn "*iordi_1_rex64"
10079   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10080         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10081                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
10082    (clobber (reg:CC FLAGS_REG))]
10083   "TARGET_64BIT
10084    && ix86_binary_operator_ok (IOR, DImode, operands)"
10085   "or{q}\t{%2, %0|%0, %2}"
10086   [(set_attr "type" "alu")
10087    (set_attr "mode" "DI")])
10088
10089 (define_insn "*iordi_2_rex64"
10090   [(set (reg FLAGS_REG)
10091         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10092                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10093                  (const_int 0)))
10094    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10095         (ior:DI (match_dup 1) (match_dup 2)))]
10096   "TARGET_64BIT
10097    && ix86_match_ccmode (insn, CCNOmode)
10098    && ix86_binary_operator_ok (IOR, DImode, operands)"
10099   "or{q}\t{%2, %0|%0, %2}"
10100   [(set_attr "type" "alu")
10101    (set_attr "mode" "DI")])
10102
10103 (define_insn "*iordi_3_rex64"
10104   [(set (reg FLAGS_REG)
10105         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10106                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10107                  (const_int 0)))
10108    (clobber (match_scratch:DI 0 "=r"))]
10109   "TARGET_64BIT
10110    && ix86_match_ccmode (insn, CCNOmode)
10111    && ix86_binary_operator_ok (IOR, DImode, operands)"
10112   "or{q}\t{%2, %0|%0, %2}"
10113   [(set_attr "type" "alu")
10114    (set_attr "mode" "DI")])
10115
10116
10117 (define_expand "iorsi3"
10118   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10119         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
10120                 (match_operand:SI 2 "general_operand" "")))]
10121   ""
10122   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
10123
10124 (define_insn "*iorsi_1"
10125   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10126         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10127                 (match_operand:SI 2 "general_operand" "ri,g")))
10128    (clobber (reg:CC FLAGS_REG))]
10129   "ix86_binary_operator_ok (IOR, SImode, operands)"
10130   "or{l}\t{%2, %0|%0, %2}"
10131   [(set_attr "type" "alu")
10132    (set_attr "mode" "SI")])
10133
10134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10135 (define_insn "*iorsi_1_zext"
10136   [(set (match_operand:DI 0 "register_operand" "=r")
10137         (zero_extend:DI
10138           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10139                   (match_operand:SI 2 "general_operand" "g"))))
10140    (clobber (reg:CC FLAGS_REG))]
10141   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
10142   "or{l}\t{%2, %k0|%k0, %2}"
10143   [(set_attr "type" "alu")
10144    (set_attr "mode" "SI")])
10145
10146 (define_insn "*iorsi_1_zext_imm"
10147   [(set (match_operand:DI 0 "register_operand" "=r")
10148         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10149                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10150    (clobber (reg:CC FLAGS_REG))]
10151   "TARGET_64BIT"
10152   "or{l}\t{%2, %k0|%k0, %2}"
10153   [(set_attr "type" "alu")
10154    (set_attr "mode" "SI")])
10155
10156 (define_insn "*iorsi_2"
10157   [(set (reg FLAGS_REG)
10158         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10159                          (match_operand:SI 2 "general_operand" "g,ri"))
10160                  (const_int 0)))
10161    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10162         (ior:SI (match_dup 1) (match_dup 2)))]
10163   "ix86_match_ccmode (insn, CCNOmode)
10164    && ix86_binary_operator_ok (IOR, SImode, operands)"
10165   "or{l}\t{%2, %0|%0, %2}"
10166   [(set_attr "type" "alu")
10167    (set_attr "mode" "SI")])
10168
10169 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10170 ;; ??? Special case for immediate operand is missing - it is tricky.
10171 (define_insn "*iorsi_2_zext"
10172   [(set (reg FLAGS_REG)
10173         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10174                          (match_operand:SI 2 "general_operand" "g"))
10175                  (const_int 0)))
10176    (set (match_operand:DI 0 "register_operand" "=r")
10177         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
10178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10179    && ix86_binary_operator_ok (IOR, SImode, operands)"
10180   "or{l}\t{%2, %k0|%k0, %2}"
10181   [(set_attr "type" "alu")
10182    (set_attr "mode" "SI")])
10183
10184 (define_insn "*iorsi_2_zext_imm"
10185   [(set (reg FLAGS_REG)
10186         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10187                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10188                  (const_int 0)))
10189    (set (match_operand:DI 0 "register_operand" "=r")
10190         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10191   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10192    && ix86_binary_operator_ok (IOR, SImode, operands)"
10193   "or{l}\t{%2, %k0|%k0, %2}"
10194   [(set_attr "type" "alu")
10195    (set_attr "mode" "SI")])
10196
10197 (define_insn "*iorsi_3"
10198   [(set (reg FLAGS_REG)
10199         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10200                          (match_operand:SI 2 "general_operand" "g"))
10201                  (const_int 0)))
10202    (clobber (match_scratch:SI 0 "=r"))]
10203   "ix86_match_ccmode (insn, CCNOmode)
10204    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10205   "or{l}\t{%2, %0|%0, %2}"
10206   [(set_attr "type" "alu")
10207    (set_attr "mode" "SI")])
10208
10209 (define_expand "iorhi3"
10210   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10211         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
10212                 (match_operand:HI 2 "general_operand" "")))]
10213   "TARGET_HIMODE_MATH"
10214   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
10215
10216 (define_insn "*iorhi_1"
10217   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10218         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10219                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10220    (clobber (reg:CC FLAGS_REG))]
10221   "ix86_binary_operator_ok (IOR, HImode, operands)"
10222   "or{w}\t{%2, %0|%0, %2}"
10223   [(set_attr "type" "alu")
10224    (set_attr "mode" "HI")])
10225
10226 (define_insn "*iorhi_2"
10227   [(set (reg FLAGS_REG)
10228         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10229                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10230                  (const_int 0)))
10231    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10232         (ior:HI (match_dup 1) (match_dup 2)))]
10233   "ix86_match_ccmode (insn, CCNOmode)
10234    && ix86_binary_operator_ok (IOR, HImode, operands)"
10235   "or{w}\t{%2, %0|%0, %2}"
10236   [(set_attr "type" "alu")
10237    (set_attr "mode" "HI")])
10238
10239 (define_insn "*iorhi_3"
10240   [(set (reg FLAGS_REG)
10241         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10242                          (match_operand:HI 2 "general_operand" "rmn"))
10243                  (const_int 0)))
10244    (clobber (match_scratch:HI 0 "=r"))]
10245   "ix86_match_ccmode (insn, CCNOmode)
10246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10247   "or{w}\t{%2, %0|%0, %2}"
10248   [(set_attr "type" "alu")
10249    (set_attr "mode" "HI")])
10250
10251 (define_expand "iorqi3"
10252   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10253         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
10254                 (match_operand:QI 2 "general_operand" "")))]
10255   "TARGET_QIMODE_MATH"
10256   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
10257
10258 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10259 (define_insn "*iorqi_1"
10260   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10261         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10262                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "ix86_binary_operator_ok (IOR, QImode, operands)"
10265   "@
10266    or{b}\t{%2, %0|%0, %2}
10267    or{b}\t{%2, %0|%0, %2}
10268    or{l}\t{%k2, %k0|%k0, %k2}"
10269   [(set_attr "type" "alu")
10270    (set_attr "mode" "QI,QI,SI")])
10271
10272 (define_insn "*iorqi_1_slp"
10273   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
10274         (ior:QI (match_dup 0)
10275                 (match_operand:QI 1 "general_operand" "qmn,qn")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10278    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10279   "or{b}\t{%1, %0|%0, %1}"
10280   [(set_attr "type" "alu1")
10281    (set_attr "mode" "QI")])
10282
10283 (define_insn "*iorqi_2"
10284   [(set (reg FLAGS_REG)
10285         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10286                          (match_operand:QI 2 "general_operand" "qmn,qn"))
10287                  (const_int 0)))
10288    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10289         (ior:QI (match_dup 1) (match_dup 2)))]
10290   "ix86_match_ccmode (insn, CCNOmode)
10291    && ix86_binary_operator_ok (IOR, QImode, operands)"
10292   "or{b}\t{%2, %0|%0, %2}"
10293   [(set_attr "type" "alu")
10294    (set_attr "mode" "QI")])
10295
10296 (define_insn "*iorqi_2_slp"
10297   [(set (reg FLAGS_REG)
10298         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10299                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10300                  (const_int 0)))
10301    (set (strict_low_part (match_dup 0))
10302         (ior:QI (match_dup 0) (match_dup 1)))]
10303   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10304    && ix86_match_ccmode (insn, CCNOmode)
10305    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10306   "or{b}\t{%1, %0|%0, %1}"
10307   [(set_attr "type" "alu1")
10308    (set_attr "mode" "QI")])
10309
10310 (define_insn "*iorqi_3"
10311   [(set (reg FLAGS_REG)
10312         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10313                          (match_operand:QI 2 "general_operand" "qmn"))
10314                  (const_int 0)))
10315    (clobber (match_scratch:QI 0 "=q"))]
10316   "ix86_match_ccmode (insn, CCNOmode)
10317    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10318   "or{b}\t{%2, %0|%0, %2}"
10319   [(set_attr "type" "alu")
10320    (set_attr "mode" "QI")])
10321
10322 (define_insn "*iorqi_ext_0"
10323   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10324                          (const_int 8)
10325                          (const_int 8))
10326         (ior:SI
10327           (zero_extract:SI
10328             (match_operand 1 "ext_register_operand" "0")
10329             (const_int 8)
10330             (const_int 8))
10331           (match_operand 2 "const_int_operand" "n")))
10332    (clobber (reg:CC FLAGS_REG))]
10333   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10334   "or{b}\t{%2, %h0|%h0, %2}"
10335   [(set_attr "type" "alu")
10336    (set_attr "length_immediate" "1")
10337    (set_attr "modrm" "1")
10338    (set_attr "mode" "QI")])
10339
10340 (define_insn "*iorqi_ext_1"
10341   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10342                          (const_int 8)
10343                          (const_int 8))
10344         (ior:SI
10345           (zero_extract:SI
10346             (match_operand 1 "ext_register_operand" "0")
10347             (const_int 8)
10348             (const_int 8))
10349           (zero_extend:SI
10350             (match_operand:QI 2 "general_operand" "Qm"))))
10351    (clobber (reg:CC FLAGS_REG))]
10352   "!TARGET_64BIT
10353    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10354   "or{b}\t{%2, %h0|%h0, %2}"
10355   [(set_attr "type" "alu")
10356    (set_attr "length_immediate" "0")
10357    (set_attr "mode" "QI")])
10358
10359 (define_insn "*iorqi_ext_1_rex64"
10360   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10361                          (const_int 8)
10362                          (const_int 8))
10363         (ior:SI
10364           (zero_extract:SI
10365             (match_operand 1 "ext_register_operand" "0")
10366             (const_int 8)
10367             (const_int 8))
10368           (zero_extend:SI
10369             (match_operand 2 "ext_register_operand" "Q"))))
10370    (clobber (reg:CC FLAGS_REG))]
10371   "TARGET_64BIT
10372    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10373   "or{b}\t{%2, %h0|%h0, %2}"
10374   [(set_attr "type" "alu")
10375    (set_attr "length_immediate" "0")
10376    (set_attr "mode" "QI")])
10377
10378 (define_insn "*iorqi_ext_2"
10379   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10380                          (const_int 8)
10381                          (const_int 8))
10382         (ior:SI
10383           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10384                            (const_int 8)
10385                            (const_int 8))
10386           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10387                            (const_int 8)
10388                            (const_int 8))))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10391   "ior{b}\t{%h2, %h0|%h0, %h2}"
10392   [(set_attr "type" "alu")
10393    (set_attr "length_immediate" "0")
10394    (set_attr "mode" "QI")])
10395
10396 (define_split
10397   [(set (match_operand 0 "register_operand" "")
10398         (ior (match_operand 1 "register_operand" "")
10399              (match_operand 2 "const_int_operand" "")))
10400    (clobber (reg:CC FLAGS_REG))]
10401    "reload_completed
10402     && QI_REG_P (operands[0])
10403     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10404     && !(INTVAL (operands[2]) & ~(255 << 8))
10405     && GET_MODE (operands[0]) != QImode"
10406   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10407                    (ior:SI (zero_extract:SI (match_dup 1)
10408                                             (const_int 8) (const_int 8))
10409                            (match_dup 2)))
10410               (clobber (reg:CC FLAGS_REG))])]
10411   "operands[0] = gen_lowpart (SImode, operands[0]);
10412    operands[1] = gen_lowpart (SImode, operands[1]);
10413    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10414
10415 ;; Since OR can be encoded with sign extended immediate, this is only
10416 ;; profitable when 7th bit is set.
10417 (define_split
10418   [(set (match_operand 0 "register_operand" "")
10419         (ior (match_operand 1 "general_operand" "")
10420              (match_operand 2 "const_int_operand" "")))
10421    (clobber (reg:CC FLAGS_REG))]
10422    "reload_completed
10423     && ANY_QI_REG_P (operands[0])
10424     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10425     && !(INTVAL (operands[2]) & ~255)
10426     && (INTVAL (operands[2]) & 128)
10427     && GET_MODE (operands[0]) != QImode"
10428   [(parallel [(set (strict_low_part (match_dup 0))
10429                    (ior:QI (match_dup 1)
10430                            (match_dup 2)))
10431               (clobber (reg:CC FLAGS_REG))])]
10432   "operands[0] = gen_lowpart (QImode, operands[0]);
10433    operands[1] = gen_lowpart (QImode, operands[1]);
10434    operands[2] = gen_lowpart (QImode, operands[2]);")
10435 \f
10436 ;; Logical XOR instructions
10437
10438 ;; %%% This used to optimize known byte-wide and operations to memory.
10439 ;; If this is considered useful, it should be done with splitters.
10440
10441 (define_expand "xordi3"
10442   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10443         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10444                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10445   "TARGET_64BIT"
10446   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10447
10448 (define_insn "*xordi_1_rex64"
10449   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10450         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10451                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10452    (clobber (reg:CC FLAGS_REG))]
10453   "TARGET_64BIT
10454    && ix86_binary_operator_ok (XOR, DImode, operands)"
10455   "xor{q}\t{%2, %0|%0, %2}"
10456   [(set_attr "type" "alu")
10457    (set_attr "mode" "DI")])
10458
10459 (define_insn "*xordi_2_rex64"
10460   [(set (reg FLAGS_REG)
10461         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10462                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10463                  (const_int 0)))
10464    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10465         (xor:DI (match_dup 1) (match_dup 2)))]
10466   "TARGET_64BIT
10467    && ix86_match_ccmode (insn, CCNOmode)
10468    && ix86_binary_operator_ok (XOR, DImode, operands)"
10469   "xor{q}\t{%2, %0|%0, %2}"
10470   [(set_attr "type" "alu")
10471    (set_attr "mode" "DI")])
10472
10473 (define_insn "*xordi_3_rex64"
10474   [(set (reg FLAGS_REG)
10475         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10476                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10477                  (const_int 0)))
10478    (clobber (match_scratch:DI 0 "=r"))]
10479   "TARGET_64BIT
10480    && ix86_match_ccmode (insn, CCNOmode)
10481    && ix86_binary_operator_ok (XOR, DImode, operands)"
10482   "xor{q}\t{%2, %0|%0, %2}"
10483   [(set_attr "type" "alu")
10484    (set_attr "mode" "DI")])
10485
10486 (define_expand "xorsi3"
10487   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10488         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10489                 (match_operand:SI 2 "general_operand" "")))]
10490   ""
10491   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10492
10493 (define_insn "*xorsi_1"
10494   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10495         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10496                 (match_operand:SI 2 "general_operand" "ri,rm")))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "ix86_binary_operator_ok (XOR, SImode, operands)"
10499   "xor{l}\t{%2, %0|%0, %2}"
10500   [(set_attr "type" "alu")
10501    (set_attr "mode" "SI")])
10502
10503 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10504 ;; Add speccase for immediates
10505 (define_insn "*xorsi_1_zext"
10506   [(set (match_operand:DI 0 "register_operand" "=r")
10507         (zero_extend:DI
10508           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10509                   (match_operand:SI 2 "general_operand" "g"))))
10510    (clobber (reg:CC FLAGS_REG))]
10511   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10512   "xor{l}\t{%2, %k0|%k0, %2}"
10513   [(set_attr "type" "alu")
10514    (set_attr "mode" "SI")])
10515
10516 (define_insn "*xorsi_1_zext_imm"
10517   [(set (match_operand:DI 0 "register_operand" "=r")
10518         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10519                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10520    (clobber (reg:CC FLAGS_REG))]
10521   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10522   "xor{l}\t{%2, %k0|%k0, %2}"
10523   [(set_attr "type" "alu")
10524    (set_attr "mode" "SI")])
10525
10526 (define_insn "*xorsi_2"
10527   [(set (reg FLAGS_REG)
10528         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10529                          (match_operand:SI 2 "general_operand" "g,ri"))
10530                  (const_int 0)))
10531    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10532         (xor:SI (match_dup 1) (match_dup 2)))]
10533   "ix86_match_ccmode (insn, CCNOmode)
10534    && ix86_binary_operator_ok (XOR, SImode, operands)"
10535   "xor{l}\t{%2, %0|%0, %2}"
10536   [(set_attr "type" "alu")
10537    (set_attr "mode" "SI")])
10538
10539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10540 ;; ??? Special case for immediate operand is missing - it is tricky.
10541 (define_insn "*xorsi_2_zext"
10542   [(set (reg FLAGS_REG)
10543         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10544                          (match_operand:SI 2 "general_operand" "g"))
10545                  (const_int 0)))
10546    (set (match_operand:DI 0 "register_operand" "=r")
10547         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10548   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10549    && ix86_binary_operator_ok (XOR, SImode, operands)"
10550   "xor{l}\t{%2, %k0|%k0, %2}"
10551   [(set_attr "type" "alu")
10552    (set_attr "mode" "SI")])
10553
10554 (define_insn "*xorsi_2_zext_imm"
10555   [(set (reg FLAGS_REG)
10556         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10557                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10558                  (const_int 0)))
10559    (set (match_operand:DI 0 "register_operand" "=r")
10560         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10561   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10562    && ix86_binary_operator_ok (XOR, SImode, operands)"
10563   "xor{l}\t{%2, %k0|%k0, %2}"
10564   [(set_attr "type" "alu")
10565    (set_attr "mode" "SI")])
10566
10567 (define_insn "*xorsi_3"
10568   [(set (reg FLAGS_REG)
10569         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10570                          (match_operand:SI 2 "general_operand" "g"))
10571                  (const_int 0)))
10572    (clobber (match_scratch:SI 0 "=r"))]
10573   "ix86_match_ccmode (insn, CCNOmode)
10574    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10575   "xor{l}\t{%2, %0|%0, %2}"
10576   [(set_attr "type" "alu")
10577    (set_attr "mode" "SI")])
10578
10579 (define_expand "xorhi3"
10580   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10581         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10582                 (match_operand:HI 2 "general_operand" "")))]
10583   "TARGET_HIMODE_MATH"
10584   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10585
10586 (define_insn "*xorhi_1"
10587   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10588         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10589                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10590    (clobber (reg:CC FLAGS_REG))]
10591   "ix86_binary_operator_ok (XOR, HImode, operands)"
10592   "xor{w}\t{%2, %0|%0, %2}"
10593   [(set_attr "type" "alu")
10594    (set_attr "mode" "HI")])
10595
10596 (define_insn "*xorhi_2"
10597   [(set (reg FLAGS_REG)
10598         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10599                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10600                  (const_int 0)))
10601    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10602         (xor:HI (match_dup 1) (match_dup 2)))]
10603   "ix86_match_ccmode (insn, CCNOmode)
10604    && ix86_binary_operator_ok (XOR, HImode, operands)"
10605   "xor{w}\t{%2, %0|%0, %2}"
10606   [(set_attr "type" "alu")
10607    (set_attr "mode" "HI")])
10608
10609 (define_insn "*xorhi_3"
10610   [(set (reg FLAGS_REG)
10611         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10612                          (match_operand:HI 2 "general_operand" "rmn"))
10613                  (const_int 0)))
10614    (clobber (match_scratch:HI 0 "=r"))]
10615   "ix86_match_ccmode (insn, CCNOmode)
10616    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10617   "xor{w}\t{%2, %0|%0, %2}"
10618   [(set_attr "type" "alu")
10619    (set_attr "mode" "HI")])
10620
10621 (define_expand "xorqi3"
10622   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10623         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10624                 (match_operand:QI 2 "general_operand" "")))]
10625   "TARGET_QIMODE_MATH"
10626   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10627
10628 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10629 (define_insn "*xorqi_1"
10630   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10631         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10632                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "ix86_binary_operator_ok (XOR, QImode, operands)"
10635   "@
10636    xor{b}\t{%2, %0|%0, %2}
10637    xor{b}\t{%2, %0|%0, %2}
10638    xor{l}\t{%k2, %k0|%k0, %k2}"
10639   [(set_attr "type" "alu")
10640    (set_attr "mode" "QI,QI,SI")])
10641
10642 (define_insn "*xorqi_1_slp"
10643   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10644         (xor:QI (match_dup 0)
10645                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10646    (clobber (reg:CC FLAGS_REG))]
10647   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10648    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10649   "xor{b}\t{%1, %0|%0, %1}"
10650   [(set_attr "type" "alu1")
10651    (set_attr "mode" "QI")])
10652
10653 (define_insn "*xorqi_ext_0"
10654   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10655                          (const_int 8)
10656                          (const_int 8))
10657         (xor:SI
10658           (zero_extract:SI
10659             (match_operand 1 "ext_register_operand" "0")
10660             (const_int 8)
10661             (const_int 8))
10662           (match_operand 2 "const_int_operand" "n")))
10663    (clobber (reg:CC FLAGS_REG))]
10664   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10665   "xor{b}\t{%2, %h0|%h0, %2}"
10666   [(set_attr "type" "alu")
10667    (set_attr "length_immediate" "1")
10668    (set_attr "modrm" "1")
10669    (set_attr "mode" "QI")])
10670
10671 (define_insn "*xorqi_ext_1"
10672   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10673                          (const_int 8)
10674                          (const_int 8))
10675         (xor:SI
10676           (zero_extract:SI
10677             (match_operand 1 "ext_register_operand" "0")
10678             (const_int 8)
10679             (const_int 8))
10680           (zero_extend:SI
10681             (match_operand:QI 2 "general_operand" "Qm"))))
10682    (clobber (reg:CC FLAGS_REG))]
10683   "!TARGET_64BIT
10684    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10685   "xor{b}\t{%2, %h0|%h0, %2}"
10686   [(set_attr "type" "alu")
10687    (set_attr "length_immediate" "0")
10688    (set_attr "mode" "QI")])
10689
10690 (define_insn "*xorqi_ext_1_rex64"
10691   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10692                          (const_int 8)
10693                          (const_int 8))
10694         (xor:SI
10695           (zero_extract:SI
10696             (match_operand 1 "ext_register_operand" "0")
10697             (const_int 8)
10698             (const_int 8))
10699           (zero_extend:SI
10700             (match_operand 2 "ext_register_operand" "Q"))))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "TARGET_64BIT
10703    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10704   "xor{b}\t{%2, %h0|%h0, %2}"
10705   [(set_attr "type" "alu")
10706    (set_attr "length_immediate" "0")
10707    (set_attr "mode" "QI")])
10708
10709 (define_insn "*xorqi_ext_2"
10710   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10711                          (const_int 8)
10712                          (const_int 8))
10713         (xor:SI
10714           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10715                            (const_int 8)
10716                            (const_int 8))
10717           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10718                            (const_int 8)
10719                            (const_int 8))))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10722   "xor{b}\t{%h2, %h0|%h0, %h2}"
10723   [(set_attr "type" "alu")
10724    (set_attr "length_immediate" "0")
10725    (set_attr "mode" "QI")])
10726
10727 (define_insn "*xorqi_cc_1"
10728   [(set (reg FLAGS_REG)
10729         (compare
10730           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10731                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10732           (const_int 0)))
10733    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10734         (xor:QI (match_dup 1) (match_dup 2)))]
10735   "ix86_match_ccmode (insn, CCNOmode)
10736    && ix86_binary_operator_ok (XOR, QImode, operands)"
10737   "xor{b}\t{%2, %0|%0, %2}"
10738   [(set_attr "type" "alu")
10739    (set_attr "mode" "QI")])
10740
10741 (define_insn "*xorqi_2_slp"
10742   [(set (reg FLAGS_REG)
10743         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10744                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10745                  (const_int 0)))
10746    (set (strict_low_part (match_dup 0))
10747         (xor:QI (match_dup 0) (match_dup 1)))]
10748   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10749    && ix86_match_ccmode (insn, CCNOmode)
10750    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10751   "xor{b}\t{%1, %0|%0, %1}"
10752   [(set_attr "type" "alu1")
10753    (set_attr "mode" "QI")])
10754
10755 (define_insn "*xorqi_cc_2"
10756   [(set (reg FLAGS_REG)
10757         (compare
10758           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10759                   (match_operand:QI 2 "general_operand" "qmn"))
10760           (const_int 0)))
10761    (clobber (match_scratch:QI 0 "=q"))]
10762   "ix86_match_ccmode (insn, CCNOmode)
10763    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10764   "xor{b}\t{%2, %0|%0, %2}"
10765   [(set_attr "type" "alu")
10766    (set_attr "mode" "QI")])
10767
10768 (define_insn "*xorqi_cc_ext_1"
10769   [(set (reg FLAGS_REG)
10770         (compare
10771           (xor:SI
10772             (zero_extract:SI
10773               (match_operand 1 "ext_register_operand" "0")
10774               (const_int 8)
10775               (const_int 8))
10776             (match_operand:QI 2 "general_operand" "qmn"))
10777           (const_int 0)))
10778    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10779                          (const_int 8)
10780                          (const_int 8))
10781         (xor:SI
10782           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10783           (match_dup 2)))]
10784   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10785   "xor{b}\t{%2, %h0|%h0, %2}"
10786   [(set_attr "type" "alu")
10787    (set_attr "modrm" "1")
10788    (set_attr "mode" "QI")])
10789
10790 (define_insn "*xorqi_cc_ext_1_rex64"
10791   [(set (reg FLAGS_REG)
10792         (compare
10793           (xor:SI
10794             (zero_extract:SI
10795               (match_operand 1 "ext_register_operand" "0")
10796               (const_int 8)
10797               (const_int 8))
10798             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10799           (const_int 0)))
10800    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10801                          (const_int 8)
10802                          (const_int 8))
10803         (xor:SI
10804           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10805           (match_dup 2)))]
10806   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10807   "xor{b}\t{%2, %h0|%h0, %2}"
10808   [(set_attr "type" "alu")
10809    (set_attr "modrm" "1")
10810    (set_attr "mode" "QI")])
10811
10812 (define_expand "xorqi_cc_ext_1"
10813   [(parallel [
10814      (set (reg:CCNO FLAGS_REG)
10815           (compare:CCNO
10816             (xor:SI
10817               (zero_extract:SI
10818                 (match_operand 1 "ext_register_operand" "")
10819                 (const_int 8)
10820                 (const_int 8))
10821               (match_operand:QI 2 "general_operand" ""))
10822             (const_int 0)))
10823      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10824                            (const_int 8)
10825                            (const_int 8))
10826           (xor:SI
10827             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10828             (match_dup 2)))])]
10829   ""
10830   "")
10831
10832 (define_split
10833   [(set (match_operand 0 "register_operand" "")
10834         (xor (match_operand 1 "register_operand" "")
10835              (match_operand 2 "const_int_operand" "")))
10836    (clobber (reg:CC FLAGS_REG))]
10837    "reload_completed
10838     && QI_REG_P (operands[0])
10839     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10840     && !(INTVAL (operands[2]) & ~(255 << 8))
10841     && GET_MODE (operands[0]) != QImode"
10842   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10843                    (xor:SI (zero_extract:SI (match_dup 1)
10844                                             (const_int 8) (const_int 8))
10845                            (match_dup 2)))
10846               (clobber (reg:CC FLAGS_REG))])]
10847   "operands[0] = gen_lowpart (SImode, operands[0]);
10848    operands[1] = gen_lowpart (SImode, operands[1]);
10849    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10850
10851 ;; Since XOR can be encoded with sign extended immediate, this is only
10852 ;; profitable when 7th bit is set.
10853 (define_split
10854   [(set (match_operand 0 "register_operand" "")
10855         (xor (match_operand 1 "general_operand" "")
10856              (match_operand 2 "const_int_operand" "")))
10857    (clobber (reg:CC FLAGS_REG))]
10858    "reload_completed
10859     && ANY_QI_REG_P (operands[0])
10860     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10861     && !(INTVAL (operands[2]) & ~255)
10862     && (INTVAL (operands[2]) & 128)
10863     && GET_MODE (operands[0]) != QImode"
10864   [(parallel [(set (strict_low_part (match_dup 0))
10865                    (xor:QI (match_dup 1)
10866                            (match_dup 2)))
10867               (clobber (reg:CC FLAGS_REG))])]
10868   "operands[0] = gen_lowpart (QImode, operands[0]);
10869    operands[1] = gen_lowpart (QImode, operands[1]);
10870    operands[2] = gen_lowpart (QImode, operands[2]);")
10871 \f
10872 ;; Negation instructions
10873
10874 (define_expand "negti2"
10875   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10876         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10877   "TARGET_64BIT"
10878   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10879
10880 (define_insn "*negti2_1"
10881   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10882         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10883    (clobber (reg:CC FLAGS_REG))]
10884   "TARGET_64BIT
10885    && ix86_unary_operator_ok (NEG, TImode, operands)"
10886   "#")
10887
10888 (define_split
10889   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10890         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10891    (clobber (reg:CC FLAGS_REG))]
10892   "TARGET_64BIT && reload_completed"
10893   [(parallel
10894     [(set (reg:CCZ FLAGS_REG)
10895           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10896      (set (match_dup 0) (neg:DI (match_dup 1)))])
10897    (parallel
10898     [(set (match_dup 2)
10899           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10900                             (match_dup 3))
10901                    (const_int 0)))
10902      (clobber (reg:CC FLAGS_REG))])
10903    (parallel
10904     [(set (match_dup 2)
10905           (neg:DI (match_dup 2)))
10906      (clobber (reg:CC FLAGS_REG))])]
10907   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10908
10909 (define_expand "negdi2"
10910   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10911         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10912   ""
10913   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10914
10915 (define_insn "*negdi2_1"
10916   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10917         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10918    (clobber (reg:CC FLAGS_REG))]
10919   "!TARGET_64BIT
10920    && ix86_unary_operator_ok (NEG, DImode, operands)"
10921   "#")
10922
10923 (define_split
10924   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10925         (neg:DI (match_operand:DI 1 "general_operand" "")))
10926    (clobber (reg:CC FLAGS_REG))]
10927   "!TARGET_64BIT && reload_completed"
10928   [(parallel
10929     [(set (reg:CCZ FLAGS_REG)
10930           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10931      (set (match_dup 0) (neg:SI (match_dup 1)))])
10932    (parallel
10933     [(set (match_dup 2)
10934           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10935                             (match_dup 3))
10936                    (const_int 0)))
10937      (clobber (reg:CC FLAGS_REG))])
10938    (parallel
10939     [(set (match_dup 2)
10940           (neg:SI (match_dup 2)))
10941      (clobber (reg:CC FLAGS_REG))])]
10942   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10943
10944 (define_insn "*negdi2_1_rex64"
10945   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10946         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10947    (clobber (reg:CC FLAGS_REG))]
10948   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10949   "neg{q}\t%0"
10950   [(set_attr "type" "negnot")
10951    (set_attr "mode" "DI")])
10952
10953 ;; The problem with neg is that it does not perform (compare x 0),
10954 ;; it really performs (compare 0 x), which leaves us with the zero
10955 ;; flag being the only useful item.
10956
10957 (define_insn "*negdi2_cmpz_rex64"
10958   [(set (reg:CCZ FLAGS_REG)
10959         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10960                      (const_int 0)))
10961    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10962         (neg:DI (match_dup 1)))]
10963   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10964   "neg{q}\t%0"
10965   [(set_attr "type" "negnot")
10966    (set_attr "mode" "DI")])
10967
10968
10969 (define_expand "negsi2"
10970   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10971         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10972   ""
10973   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10974
10975 (define_insn "*negsi2_1"
10976   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10977         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10978    (clobber (reg:CC FLAGS_REG))]
10979   "ix86_unary_operator_ok (NEG, SImode, operands)"
10980   "neg{l}\t%0"
10981   [(set_attr "type" "negnot")
10982    (set_attr "mode" "SI")])
10983
10984 ;; Combine is quite creative about this pattern.
10985 (define_insn "*negsi2_1_zext"
10986   [(set (match_operand:DI 0 "register_operand" "=r")
10987         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10988                                         (const_int 32)))
10989                      (const_int 32)))
10990    (clobber (reg:CC FLAGS_REG))]
10991   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10992   "neg{l}\t%k0"
10993   [(set_attr "type" "negnot")
10994    (set_attr "mode" "SI")])
10995
10996 ;; The problem with neg is that it does not perform (compare x 0),
10997 ;; it really performs (compare 0 x), which leaves us with the zero
10998 ;; flag being the only useful item.
10999
11000 (define_insn "*negsi2_cmpz"
11001   [(set (reg:CCZ FLAGS_REG)
11002         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11003                      (const_int 0)))
11004    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11005         (neg:SI (match_dup 1)))]
11006   "ix86_unary_operator_ok (NEG, SImode, operands)"
11007   "neg{l}\t%0"
11008   [(set_attr "type" "negnot")
11009    (set_attr "mode" "SI")])
11010
11011 (define_insn "*negsi2_cmpz_zext"
11012   [(set (reg:CCZ FLAGS_REG)
11013         (compare:CCZ (lshiftrt:DI
11014                        (neg:DI (ashift:DI
11015                                  (match_operand:DI 1 "register_operand" "0")
11016                                  (const_int 32)))
11017                        (const_int 32))
11018                      (const_int 0)))
11019    (set (match_operand:DI 0 "register_operand" "=r")
11020         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
11021                                         (const_int 32)))
11022                      (const_int 32)))]
11023   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
11024   "neg{l}\t%k0"
11025   [(set_attr "type" "negnot")
11026    (set_attr "mode" "SI")])
11027
11028 (define_expand "neghi2"
11029   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11030         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11031   "TARGET_HIMODE_MATH"
11032   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
11033
11034 (define_insn "*neghi2_1"
11035   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11036         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
11037    (clobber (reg:CC FLAGS_REG))]
11038   "ix86_unary_operator_ok (NEG, HImode, operands)"
11039   "neg{w}\t%0"
11040   [(set_attr "type" "negnot")
11041    (set_attr "mode" "HI")])
11042
11043 (define_insn "*neghi2_cmpz"
11044   [(set (reg:CCZ FLAGS_REG)
11045         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11046                      (const_int 0)))
11047    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11048         (neg:HI (match_dup 1)))]
11049   "ix86_unary_operator_ok (NEG, HImode, operands)"
11050   "neg{w}\t%0"
11051   [(set_attr "type" "negnot")
11052    (set_attr "mode" "HI")])
11053
11054 (define_expand "negqi2"
11055   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11056         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11057   "TARGET_QIMODE_MATH"
11058   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
11059
11060 (define_insn "*negqi2_1"
11061   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11062         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "ix86_unary_operator_ok (NEG, QImode, operands)"
11065   "neg{b}\t%0"
11066   [(set_attr "type" "negnot")
11067    (set_attr "mode" "QI")])
11068
11069 (define_insn "*negqi2_cmpz"
11070   [(set (reg:CCZ FLAGS_REG)
11071         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11072                      (const_int 0)))
11073    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11074         (neg:QI (match_dup 1)))]
11075   "ix86_unary_operator_ok (NEG, QImode, operands)"
11076   "neg{b}\t%0"
11077   [(set_attr "type" "negnot")
11078    (set_attr "mode" "QI")])
11079
11080 ;; Changing of sign for FP values is doable using integer unit too.
11081
11082 (define_expand "<code><mode>2"
11083   [(set (match_operand:X87MODEF 0 "register_operand" "")
11084         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
11085   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11086   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
11087
11088 (define_insn "*absneg<mode>2_mixed"
11089   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
11090         (match_operator:MODEF 3 "absneg_operator"
11091           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
11092    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
11093    (clobber (reg:CC FLAGS_REG))]
11094   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
11095   "#")
11096
11097 (define_insn "*absneg<mode>2_sse"
11098   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
11099         (match_operator:MODEF 3 "absneg_operator"
11100           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
11101    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
11102    (clobber (reg:CC FLAGS_REG))]
11103   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
11104   "#")
11105
11106 (define_insn "*absneg<mode>2_i387"
11107   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
11108         (match_operator:X87MODEF 3 "absneg_operator"
11109           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
11110    (use (match_operand 2 "" ""))
11111    (clobber (reg:CC FLAGS_REG))]
11112   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11113   "#")
11114
11115 (define_expand "<code>tf2"
11116   [(set (match_operand:TF 0 "register_operand" "")
11117         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
11118   "TARGET_SSE2"
11119   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
11120
11121 (define_insn "*absnegtf2_sse"
11122   [(set (match_operand:TF 0 "register_operand" "=x,x")
11123         (match_operator:TF 3 "absneg_operator"
11124           [(match_operand:TF 1 "register_operand" "0,x")]))
11125    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
11126    (clobber (reg:CC FLAGS_REG))]
11127   "TARGET_SSE2"
11128   "#")
11129
11130 ;; Splitters for fp abs and neg.
11131
11132 (define_split
11133   [(set (match_operand 0 "fp_register_operand" "")
11134         (match_operator 1 "absneg_operator" [(match_dup 0)]))
11135    (use (match_operand 2 "" ""))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "reload_completed"
11138   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
11139
11140 (define_split
11141   [(set (match_operand 0 "register_operand" "")
11142         (match_operator 3 "absneg_operator"
11143           [(match_operand 1 "register_operand" "")]))
11144    (use (match_operand 2 "nonimmediate_operand" ""))
11145    (clobber (reg:CC FLAGS_REG))]
11146   "reload_completed && SSE_REG_P (operands[0])"
11147   [(set (match_dup 0) (match_dup 3))]
11148 {
11149   enum machine_mode mode = GET_MODE (operands[0]);
11150   enum machine_mode vmode = GET_MODE (operands[2]);
11151   rtx tmp;
11152
11153   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
11154   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
11155   if (operands_match_p (operands[0], operands[2]))
11156     {
11157       tmp = operands[1];
11158       operands[1] = operands[2];
11159       operands[2] = tmp;
11160     }
11161   if (GET_CODE (operands[3]) == ABS)
11162     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
11163   else
11164     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
11165   operands[3] = tmp;
11166 })
11167
11168 (define_split
11169   [(set (match_operand:SF 0 "register_operand" "")
11170         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
11171    (use (match_operand:V4SF 2 "" ""))
11172    (clobber (reg:CC FLAGS_REG))]
11173   "reload_completed"
11174   [(parallel [(set (match_dup 0) (match_dup 1))
11175               (clobber (reg:CC FLAGS_REG))])]
11176 {
11177   rtx tmp;
11178   operands[0] = gen_lowpart (SImode, operands[0]);
11179   if (GET_CODE (operands[1]) == ABS)
11180     {
11181       tmp = gen_int_mode (0x7fffffff, SImode);
11182       tmp = gen_rtx_AND (SImode, operands[0], tmp);
11183     }
11184   else
11185     {
11186       tmp = gen_int_mode (0x80000000, SImode);
11187       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11188     }
11189   operands[1] = tmp;
11190 })
11191
11192 (define_split
11193   [(set (match_operand:DF 0 "register_operand" "")
11194         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
11195    (use (match_operand 2 "" ""))
11196    (clobber (reg:CC FLAGS_REG))]
11197   "reload_completed"
11198   [(parallel [(set (match_dup 0) (match_dup 1))
11199               (clobber (reg:CC FLAGS_REG))])]
11200 {
11201   rtx tmp;
11202   if (TARGET_64BIT)
11203     {
11204       tmp = gen_lowpart (DImode, operands[0]);
11205       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
11206       operands[0] = tmp;
11207
11208       if (GET_CODE (operands[1]) == ABS)
11209         tmp = const0_rtx;
11210       else
11211         tmp = gen_rtx_NOT (DImode, tmp);
11212     }
11213   else
11214     {
11215       operands[0] = gen_highpart (SImode, operands[0]);
11216       if (GET_CODE (operands[1]) == ABS)
11217         {
11218           tmp = gen_int_mode (0x7fffffff, SImode);
11219           tmp = gen_rtx_AND (SImode, operands[0], tmp);
11220         }
11221       else
11222         {
11223           tmp = gen_int_mode (0x80000000, SImode);
11224           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11225         }
11226     }
11227   operands[1] = tmp;
11228 })
11229
11230 (define_split
11231   [(set (match_operand:XF 0 "register_operand" "")
11232         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
11233    (use (match_operand 2 "" ""))
11234    (clobber (reg:CC FLAGS_REG))]
11235   "reload_completed"
11236   [(parallel [(set (match_dup 0) (match_dup 1))
11237               (clobber (reg:CC FLAGS_REG))])]
11238 {
11239   rtx tmp;
11240   operands[0] = gen_rtx_REG (SImode,
11241                              true_regnum (operands[0])
11242                              + (TARGET_64BIT ? 1 : 2));
11243   if (GET_CODE (operands[1]) == ABS)
11244     {
11245       tmp = GEN_INT (0x7fff);
11246       tmp = gen_rtx_AND (SImode, operands[0], tmp);
11247     }
11248   else
11249     {
11250       tmp = GEN_INT (0x8000);
11251       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11252     }
11253   operands[1] = tmp;
11254 })
11255
11256 ;; Conditionalize these after reload. If they match before reload, we
11257 ;; lose the clobber and ability to use integer instructions.
11258
11259 (define_insn "*<code><mode>2_1"
11260   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
11261         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
11262   "TARGET_80387
11263    && (reload_completed
11264        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
11265   "f<absnegprefix>"
11266   [(set_attr "type" "fsgn")
11267    (set_attr "mode" "<MODE>")])
11268
11269 (define_insn "*<code>extendsfdf2"
11270   [(set (match_operand:DF 0 "register_operand" "=f")
11271         (absneg:DF (float_extend:DF
11272                      (match_operand:SF 1 "register_operand" "0"))))]
11273   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
11274   "f<absnegprefix>"
11275   [(set_attr "type" "fsgn")
11276    (set_attr "mode" "DF")])
11277
11278 (define_insn "*<code>extendsfxf2"
11279   [(set (match_operand:XF 0 "register_operand" "=f")
11280         (absneg:XF (float_extend:XF
11281                      (match_operand:SF 1 "register_operand" "0"))))]
11282   "TARGET_80387"
11283   "f<absnegprefix>"
11284   [(set_attr "type" "fsgn")
11285    (set_attr "mode" "XF")])
11286
11287 (define_insn "*<code>extenddfxf2"
11288   [(set (match_operand:XF 0 "register_operand" "=f")
11289         (absneg:XF (float_extend:XF
11290                       (match_operand:DF 1 "register_operand" "0"))))]
11291   "TARGET_80387"
11292   "f<absnegprefix>"
11293   [(set_attr "type" "fsgn")
11294    (set_attr "mode" "XF")])
11295
11296 ;; Copysign instructions
11297
11298 (define_mode_iterator CSGNMODE [SF DF TF])
11299 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
11300
11301 (define_expand "copysign<mode>3"
11302   [(match_operand:CSGNMODE 0 "register_operand" "")
11303    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
11304    (match_operand:CSGNMODE 2 "register_operand" "")]
11305   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11306    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11307 {
11308   ix86_expand_copysign (operands);
11309   DONE;
11310 })
11311
11312 (define_insn_and_split "copysign<mode>3_const"
11313   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
11314         (unspec:CSGNMODE
11315           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
11316            (match_operand:CSGNMODE 2 "register_operand" "0")
11317            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
11318           UNSPEC_COPYSIGN))]
11319   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11320    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11321   "#"
11322   "&& reload_completed"
11323   [(const_int 0)]
11324 {
11325   ix86_split_copysign_const (operands);
11326   DONE;
11327 })
11328
11329 (define_insn "copysign<mode>3_var"
11330   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
11331         (unspec:CSGNMODE
11332           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
11333            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
11334            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
11335            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
11336           UNSPEC_COPYSIGN))
11337    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
11338   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11339    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11340   "#")
11341
11342 (define_split
11343   [(set (match_operand:CSGNMODE 0 "register_operand" "")
11344         (unspec:CSGNMODE
11345           [(match_operand:CSGNMODE 2 "register_operand" "")
11346            (match_operand:CSGNMODE 3 "register_operand" "")
11347            (match_operand:<CSGNVMODE> 4 "" "")
11348            (match_operand:<CSGNVMODE> 5 "" "")]
11349           UNSPEC_COPYSIGN))
11350    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
11351   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11352     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
11353    && reload_completed"
11354   [(const_int 0)]
11355 {
11356   ix86_split_copysign_var (operands);
11357   DONE;
11358 })
11359 \f
11360 ;; One complement instructions
11361
11362 (define_expand "one_cmpldi2"
11363   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11364         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
11365   "TARGET_64BIT"
11366   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
11367
11368 (define_insn "*one_cmpldi2_1_rex64"
11369   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11370         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
11371   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
11372   "not{q}\t%0"
11373   [(set_attr "type" "negnot")
11374    (set_attr "mode" "DI")])
11375
11376 (define_insn "*one_cmpldi2_2_rex64"
11377   [(set (reg FLAGS_REG)
11378         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
11379                  (const_int 0)))
11380    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11381         (not:DI (match_dup 1)))]
11382   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11383    && ix86_unary_operator_ok (NOT, DImode, operands)"
11384   "#"
11385   [(set_attr "type" "alu1")
11386    (set_attr "mode" "DI")])
11387
11388 (define_split
11389   [(set (match_operand 0 "flags_reg_operand" "")
11390         (match_operator 2 "compare_operator"
11391           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
11392            (const_int 0)]))
11393    (set (match_operand:DI 1 "nonimmediate_operand" "")
11394         (not:DI (match_dup 3)))]
11395   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
11396   [(parallel [(set (match_dup 0)
11397                    (match_op_dup 2
11398                      [(xor:DI (match_dup 3) (const_int -1))
11399                       (const_int 0)]))
11400               (set (match_dup 1)
11401                    (xor:DI (match_dup 3) (const_int -1)))])]
11402   "")
11403
11404 (define_expand "one_cmplsi2"
11405   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11406         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
11407   ""
11408   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
11409
11410 (define_insn "*one_cmplsi2_1"
11411   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11412         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
11413   "ix86_unary_operator_ok (NOT, SImode, operands)"
11414   "not{l}\t%0"
11415   [(set_attr "type" "negnot")
11416    (set_attr "mode" "SI")])
11417
11418 ;; ??? Currently never generated - xor is used instead.
11419 (define_insn "*one_cmplsi2_1_zext"
11420   [(set (match_operand:DI 0 "register_operand" "=r")
11421         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11422   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11423   "not{l}\t%k0"
11424   [(set_attr "type" "negnot")
11425    (set_attr "mode" "SI")])
11426
11427 (define_insn "*one_cmplsi2_2"
11428   [(set (reg FLAGS_REG)
11429         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11430                  (const_int 0)))
11431    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11432         (not:SI (match_dup 1)))]
11433   "ix86_match_ccmode (insn, CCNOmode)
11434    && ix86_unary_operator_ok (NOT, SImode, operands)"
11435   "#"
11436   [(set_attr "type" "alu1")
11437    (set_attr "mode" "SI")])
11438
11439 (define_split
11440   [(set (match_operand 0 "flags_reg_operand" "")
11441         (match_operator 2 "compare_operator"
11442           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11443            (const_int 0)]))
11444    (set (match_operand:SI 1 "nonimmediate_operand" "")
11445         (not:SI (match_dup 3)))]
11446   "ix86_match_ccmode (insn, CCNOmode)"
11447   [(parallel [(set (match_dup 0)
11448                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11449                                     (const_int 0)]))
11450               (set (match_dup 1)
11451                    (xor:SI (match_dup 3) (const_int -1)))])]
11452   "")
11453
11454 ;; ??? Currently never generated - xor is used instead.
11455 (define_insn "*one_cmplsi2_2_zext"
11456   [(set (reg FLAGS_REG)
11457         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11458                  (const_int 0)))
11459    (set (match_operand:DI 0 "register_operand" "=r")
11460         (zero_extend:DI (not:SI (match_dup 1))))]
11461   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11462    && ix86_unary_operator_ok (NOT, SImode, operands)"
11463   "#"
11464   [(set_attr "type" "alu1")
11465    (set_attr "mode" "SI")])
11466
11467 (define_split
11468   [(set (match_operand 0 "flags_reg_operand" "")
11469         (match_operator 2 "compare_operator"
11470           [(not:SI (match_operand:SI 3 "register_operand" ""))
11471            (const_int 0)]))
11472    (set (match_operand:DI 1 "register_operand" "")
11473         (zero_extend:DI (not:SI (match_dup 3))))]
11474   "ix86_match_ccmode (insn, CCNOmode)"
11475   [(parallel [(set (match_dup 0)
11476                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11477                                     (const_int 0)]))
11478               (set (match_dup 1)
11479                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11480   "")
11481
11482 (define_expand "one_cmplhi2"
11483   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11484         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11485   "TARGET_HIMODE_MATH"
11486   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11487
11488 (define_insn "*one_cmplhi2_1"
11489   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11490         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11491   "ix86_unary_operator_ok (NOT, HImode, operands)"
11492   "not{w}\t%0"
11493   [(set_attr "type" "negnot")
11494    (set_attr "mode" "HI")])
11495
11496 (define_insn "*one_cmplhi2_2"
11497   [(set (reg FLAGS_REG)
11498         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11499                  (const_int 0)))
11500    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11501         (not:HI (match_dup 1)))]
11502   "ix86_match_ccmode (insn, CCNOmode)
11503    && ix86_unary_operator_ok (NEG, HImode, operands)"
11504   "#"
11505   [(set_attr "type" "alu1")
11506    (set_attr "mode" "HI")])
11507
11508 (define_split
11509   [(set (match_operand 0 "flags_reg_operand" "")
11510         (match_operator 2 "compare_operator"
11511           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11512            (const_int 0)]))
11513    (set (match_operand:HI 1 "nonimmediate_operand" "")
11514         (not:HI (match_dup 3)))]
11515   "ix86_match_ccmode (insn, CCNOmode)"
11516   [(parallel [(set (match_dup 0)
11517                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11518                                     (const_int 0)]))
11519               (set (match_dup 1)
11520                    (xor:HI (match_dup 3) (const_int -1)))])]
11521   "")
11522
11523 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11524 (define_expand "one_cmplqi2"
11525   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11526         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11527   "TARGET_QIMODE_MATH"
11528   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11529
11530 (define_insn "*one_cmplqi2_1"
11531   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11532         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11533   "ix86_unary_operator_ok (NOT, QImode, operands)"
11534   "@
11535    not{b}\t%0
11536    not{l}\t%k0"
11537   [(set_attr "type" "negnot")
11538    (set_attr "mode" "QI,SI")])
11539
11540 (define_insn "*one_cmplqi2_2"
11541   [(set (reg FLAGS_REG)
11542         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11543                  (const_int 0)))
11544    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11545         (not:QI (match_dup 1)))]
11546   "ix86_match_ccmode (insn, CCNOmode)
11547    && ix86_unary_operator_ok (NOT, QImode, operands)"
11548   "#"
11549   [(set_attr "type" "alu1")
11550    (set_attr "mode" "QI")])
11551
11552 (define_split
11553   [(set (match_operand 0 "flags_reg_operand" "")
11554         (match_operator 2 "compare_operator"
11555           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11556            (const_int 0)]))
11557    (set (match_operand:QI 1 "nonimmediate_operand" "")
11558         (not:QI (match_dup 3)))]
11559   "ix86_match_ccmode (insn, CCNOmode)"
11560   [(parallel [(set (match_dup 0)
11561                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11562                                     (const_int 0)]))
11563               (set (match_dup 1)
11564                    (xor:QI (match_dup 3) (const_int -1)))])]
11565   "")
11566 \f
11567 ;; Arithmetic shift instructions
11568
11569 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11570 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11571 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11572 ;; from the assembler input.
11573 ;;
11574 ;; This instruction shifts the target reg/mem as usual, but instead of
11575 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11576 ;; is a left shift double, bits are taken from the high order bits of
11577 ;; reg, else if the insn is a shift right double, bits are taken from the
11578 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11579 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11580 ;;
11581 ;; Since sh[lr]d does not change the `reg' operand, that is done
11582 ;; separately, making all shifts emit pairs of shift double and normal
11583 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11584 ;; support a 63 bit shift, each shift where the count is in a reg expands
11585 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11586 ;;
11587 ;; If the shift count is a constant, we need never emit more than one
11588 ;; shift pair, instead using moves and sign extension for counts greater
11589 ;; than 31.
11590
11591 (define_expand "ashlti3"
11592   [(set (match_operand:TI 0 "register_operand" "")
11593         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11594                    (match_operand:QI 2 "nonmemory_operand" "")))]
11595   "TARGET_64BIT"
11596   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11597
11598 ;; This pattern must be defined before *ashlti3_1 to prevent
11599 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11600
11601 (define_insn "*avx_ashlti3"
11602   [(set (match_operand:TI 0 "register_operand" "=x")
11603         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11604                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11605   "TARGET_AVX"
11606 {
11607   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11608   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11609 }
11610   [(set_attr "type" "sseishft")
11611    (set_attr "prefix" "vex")
11612    (set_attr "length_immediate" "1")
11613    (set_attr "mode" "TI")])
11614
11615 (define_insn "sse2_ashlti3"
11616   [(set (match_operand:TI 0 "register_operand" "=x")
11617         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11618                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11619   "TARGET_SSE2"
11620 {
11621   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11622   return "pslldq\t{%2, %0|%0, %2}";
11623 }
11624   [(set_attr "type" "sseishft")
11625    (set_attr "prefix_data16" "1")
11626    (set_attr "length_immediate" "1")
11627    (set_attr "mode" "TI")])
11628
11629 (define_insn "*ashlti3_1"
11630   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11631         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11632                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11633    (clobber (reg:CC FLAGS_REG))]
11634   "TARGET_64BIT"
11635   "#"
11636   [(set_attr "type" "multi")])
11637
11638 (define_peephole2
11639   [(match_scratch:DI 3 "r")
11640    (parallel [(set (match_operand:TI 0 "register_operand" "")
11641                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11642                               (match_operand:QI 2 "nonmemory_operand" "")))
11643               (clobber (reg:CC FLAGS_REG))])
11644    (match_dup 3)]
11645   "TARGET_64BIT"
11646   [(const_int 0)]
11647   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11648
11649 (define_split
11650   [(set (match_operand:TI 0 "register_operand" "")
11651         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11652                    (match_operand:QI 2 "nonmemory_operand" "")))
11653    (clobber (reg:CC FLAGS_REG))]
11654   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11655                     ? epilogue_completed : reload_completed)"
11656   [(const_int 0)]
11657   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11658
11659 (define_insn "x86_64_shld"
11660   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11661         (ior:DI (ashift:DI (match_dup 0)
11662                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11663                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11664                   (minus:QI (const_int 64) (match_dup 2)))))
11665    (clobber (reg:CC FLAGS_REG))]
11666   "TARGET_64BIT"
11667   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11668   [(set_attr "type" "ishift")
11669    (set_attr "prefix_0f" "1")
11670    (set_attr "mode" "DI")
11671    (set_attr "athlon_decode" "vector")
11672    (set_attr "amdfam10_decode" "vector")])
11673
11674 (define_expand "x86_64_shift_adj_1"
11675   [(set (reg:CCZ FLAGS_REG)
11676         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11677                              (const_int 64))
11678                      (const_int 0)))
11679    (set (match_operand:DI 0 "register_operand" "")
11680         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11681                          (match_operand:DI 1 "register_operand" "")
11682                          (match_dup 0)))
11683    (set (match_dup 1)
11684         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11685                          (match_operand:DI 3 "register_operand" "r")
11686                          (match_dup 1)))]
11687   "TARGET_64BIT"
11688   "")
11689
11690 (define_expand "x86_64_shift_adj_2"
11691   [(use (match_operand:DI 0 "register_operand" ""))
11692    (use (match_operand:DI 1 "register_operand" ""))
11693    (use (match_operand:QI 2 "register_operand" ""))]
11694   "TARGET_64BIT"
11695 {
11696   rtx label = gen_label_rtx ();
11697   rtx tmp;
11698
11699   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11700
11701   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11702   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11703   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11704                               gen_rtx_LABEL_REF (VOIDmode, label),
11705                               pc_rtx);
11706   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11707   JUMP_LABEL (tmp) = label;
11708
11709   emit_move_insn (operands[0], operands[1]);
11710   ix86_expand_clear (operands[1]);
11711
11712   emit_label (label);
11713   LABEL_NUSES (label) = 1;
11714
11715   DONE;
11716 })
11717
11718 (define_expand "ashldi3"
11719   [(set (match_operand:DI 0 "shiftdi_operand" "")
11720         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11721                    (match_operand:QI 2 "nonmemory_operand" "")))]
11722   ""
11723   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11724
11725 (define_insn "*ashldi3_1_rex64"
11726   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11727         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11728                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11731 {
11732   switch (get_attr_type (insn))
11733     {
11734     case TYPE_ALU:
11735       gcc_assert (operands[2] == const1_rtx);
11736       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11737       return "add{q}\t%0, %0";
11738
11739     case TYPE_LEA:
11740       gcc_assert (CONST_INT_P (operands[2]));
11741       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11742       operands[1] = gen_rtx_MULT (DImode, operands[1],
11743                                   GEN_INT (1 << INTVAL (operands[2])));
11744       return "lea{q}\t{%a1, %0|%0, %a1}";
11745
11746     default:
11747       if (REG_P (operands[2]))
11748         return "sal{q}\t{%b2, %0|%0, %b2}";
11749       else if (operands[2] == const1_rtx
11750                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11751         return "sal{q}\t%0";
11752       else
11753         return "sal{q}\t{%2, %0|%0, %2}";
11754     }
11755 }
11756   [(set (attr "type")
11757      (cond [(eq_attr "alternative" "1")
11758               (const_string "lea")
11759             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11760                           (const_int 0))
11761                       (match_operand 0 "register_operand" ""))
11762                  (match_operand 2 "const1_operand" ""))
11763               (const_string "alu")
11764            ]
11765            (const_string "ishift")))
11766    (set (attr "length_immediate")
11767      (if_then_else
11768        (ior (eq_attr "type" "alu")
11769             (and (eq_attr "type" "ishift")
11770                  (and (match_operand 2 "const1_operand" "")
11771                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11772                           (const_int 0)))))
11773        (const_string "0")
11774        (const_string "*")))
11775    (set_attr "mode" "DI")])
11776
11777 ;; Convert lea to the lea pattern to avoid flags dependency.
11778 (define_split
11779   [(set (match_operand:DI 0 "register_operand" "")
11780         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11781                    (match_operand:QI 2 "immediate_operand" "")))
11782    (clobber (reg:CC FLAGS_REG))]
11783   "TARGET_64BIT && reload_completed
11784    && true_regnum (operands[0]) != true_regnum (operands[1])"
11785   [(set (match_dup 0)
11786         (mult:DI (match_dup 1)
11787                  (match_dup 2)))]
11788   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11789
11790 ;; This pattern can't accept a variable shift count, since shifts by
11791 ;; zero don't affect the flags.  We assume that shifts by constant
11792 ;; zero are optimized away.
11793 (define_insn "*ashldi3_cmp_rex64"
11794   [(set (reg FLAGS_REG)
11795         (compare
11796           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11797                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11798           (const_int 0)))
11799    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11800         (ashift:DI (match_dup 1) (match_dup 2)))]
11801   "TARGET_64BIT
11802    && (optimize_function_for_size_p (cfun)
11803        || !TARGET_PARTIAL_FLAG_REG_STALL
11804        || (operands[2] == const1_rtx
11805            && (TARGET_SHIFT1
11806                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11807    && ix86_match_ccmode (insn, CCGOCmode)
11808    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11809 {
11810   switch (get_attr_type (insn))
11811     {
11812     case TYPE_ALU:
11813       gcc_assert (operands[2] == const1_rtx);
11814       return "add{q}\t%0, %0";
11815
11816     default:
11817       if (REG_P (operands[2]))
11818         return "sal{q}\t{%b2, %0|%0, %b2}";
11819       else if (operands[2] == const1_rtx
11820                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11821         return "sal{q}\t%0";
11822       else
11823         return "sal{q}\t{%2, %0|%0, %2}";
11824     }
11825 }
11826   [(set (attr "type")
11827      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11828                           (const_int 0))
11829                       (match_operand 0 "register_operand" ""))
11830                  (match_operand 2 "const1_operand" ""))
11831               (const_string "alu")
11832            ]
11833            (const_string "ishift")))
11834    (set (attr "length_immediate")
11835      (if_then_else
11836        (ior (eq_attr "type" "alu")
11837             (and (eq_attr "type" "ishift")
11838                  (and (match_operand 2 "const1_operand" "")
11839                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11840                           (const_int 0)))))
11841        (const_string "0")
11842        (const_string "*")))
11843    (set_attr "mode" "DI")])
11844
11845 (define_insn "*ashldi3_cconly_rex64"
11846   [(set (reg FLAGS_REG)
11847         (compare
11848           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11849                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11850           (const_int 0)))
11851    (clobber (match_scratch:DI 0 "=r"))]
11852   "TARGET_64BIT
11853    && (optimize_function_for_size_p (cfun)
11854        || !TARGET_PARTIAL_FLAG_REG_STALL
11855        || (operands[2] == const1_rtx
11856            && (TARGET_SHIFT1
11857                || TARGET_DOUBLE_WITH_ADD)))
11858    && ix86_match_ccmode (insn, CCGOCmode)
11859    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11860 {
11861   switch (get_attr_type (insn))
11862     {
11863     case TYPE_ALU:
11864       gcc_assert (operands[2] == const1_rtx);
11865       return "add{q}\t%0, %0";
11866
11867     default:
11868       if (REG_P (operands[2]))
11869         return "sal{q}\t{%b2, %0|%0, %b2}";
11870       else if (operands[2] == const1_rtx
11871                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11872         return "sal{q}\t%0";
11873       else
11874         return "sal{q}\t{%2, %0|%0, %2}";
11875     }
11876 }
11877   [(set (attr "type")
11878      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11879                           (const_int 0))
11880                       (match_operand 0 "register_operand" ""))
11881                  (match_operand 2 "const1_operand" ""))
11882               (const_string "alu")
11883            ]
11884            (const_string "ishift")))
11885    (set (attr "length_immediate")
11886      (if_then_else
11887        (ior (eq_attr "type" "alu")
11888             (and (eq_attr "type" "ishift")
11889                  (and (match_operand 2 "const1_operand" "")
11890                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11891                           (const_int 0)))))
11892        (const_string "0")
11893        (const_string "*")))
11894    (set_attr "mode" "DI")])
11895
11896 (define_insn "*ashldi3_1"
11897   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11898         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11899                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "!TARGET_64BIT"
11902   "#"
11903   [(set_attr "type" "multi")])
11904
11905 ;; By default we don't ask for a scratch register, because when DImode
11906 ;; values are manipulated, registers are already at a premium.  But if
11907 ;; we have one handy, we won't turn it away.
11908 (define_peephole2
11909   [(match_scratch:SI 3 "r")
11910    (parallel [(set (match_operand:DI 0 "register_operand" "")
11911                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11912                               (match_operand:QI 2 "nonmemory_operand" "")))
11913               (clobber (reg:CC FLAGS_REG))])
11914    (match_dup 3)]
11915   "!TARGET_64BIT && TARGET_CMOVE"
11916   [(const_int 0)]
11917   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11918
11919 (define_split
11920   [(set (match_operand:DI 0 "register_operand" "")
11921         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11922                    (match_operand:QI 2 "nonmemory_operand" "")))
11923    (clobber (reg:CC FLAGS_REG))]
11924   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11925                      ? epilogue_completed : reload_completed)"
11926   [(const_int 0)]
11927   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11928
11929 (define_insn "x86_shld"
11930   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11931         (ior:SI (ashift:SI (match_dup 0)
11932                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11933                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11934                   (minus:QI (const_int 32) (match_dup 2)))))
11935    (clobber (reg:CC FLAGS_REG))]
11936   ""
11937   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11938   [(set_attr "type" "ishift")
11939    (set_attr "prefix_0f" "1")
11940    (set_attr "mode" "SI")
11941    (set_attr "pent_pair" "np")
11942    (set_attr "athlon_decode" "vector")
11943    (set_attr "amdfam10_decode" "vector")])
11944
11945 (define_expand "x86_shift_adj_1"
11946   [(set (reg:CCZ FLAGS_REG)
11947         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11948                              (const_int 32))
11949                      (const_int 0)))
11950    (set (match_operand:SI 0 "register_operand" "")
11951         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11952                          (match_operand:SI 1 "register_operand" "")
11953                          (match_dup 0)))
11954    (set (match_dup 1)
11955         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11956                          (match_operand:SI 3 "register_operand" "r")
11957                          (match_dup 1)))]
11958   "TARGET_CMOVE"
11959   "")
11960
11961 (define_expand "x86_shift_adj_2"
11962   [(use (match_operand:SI 0 "register_operand" ""))
11963    (use (match_operand:SI 1 "register_operand" ""))
11964    (use (match_operand:QI 2 "register_operand" ""))]
11965   ""
11966 {
11967   rtx label = gen_label_rtx ();
11968   rtx tmp;
11969
11970   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11971
11972   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11973   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11974   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11975                               gen_rtx_LABEL_REF (VOIDmode, label),
11976                               pc_rtx);
11977   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11978   JUMP_LABEL (tmp) = label;
11979
11980   emit_move_insn (operands[0], operands[1]);
11981   ix86_expand_clear (operands[1]);
11982
11983   emit_label (label);
11984   LABEL_NUSES (label) = 1;
11985
11986   DONE;
11987 })
11988
11989 (define_expand "ashlsi3"
11990   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11991         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11992                    (match_operand:QI 2 "nonmemory_operand" "")))]
11993   ""
11994   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11995
11996 (define_insn "*ashlsi3_1"
11997   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11998         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11999                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12000    (clobber (reg:CC FLAGS_REG))]
12001   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12002 {
12003   switch (get_attr_type (insn))
12004     {
12005     case TYPE_ALU:
12006       gcc_assert (operands[2] == const1_rtx);
12007       gcc_assert (rtx_equal_p (operands[0], operands[1]));
12008       return "add{l}\t%0, %0";
12009
12010     case TYPE_LEA:
12011       return "#";
12012
12013     default:
12014       if (REG_P (operands[2]))
12015         return "sal{l}\t{%b2, %0|%0, %b2}";
12016       else if (operands[2] == const1_rtx
12017                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12018         return "sal{l}\t%0";
12019       else
12020         return "sal{l}\t{%2, %0|%0, %2}";
12021     }
12022 }
12023   [(set (attr "type")
12024      (cond [(eq_attr "alternative" "1")
12025               (const_string "lea")
12026             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12027                           (const_int 0))
12028                       (match_operand 0 "register_operand" ""))
12029                  (match_operand 2 "const1_operand" ""))
12030               (const_string "alu")
12031            ]
12032            (const_string "ishift")))
12033    (set (attr "length_immediate")
12034      (if_then_else
12035        (ior (eq_attr "type" "alu")
12036             (and (eq_attr "type" "ishift")
12037                  (and (match_operand 2 "const1_operand" "")
12038                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12039                           (const_int 0)))))
12040        (const_string "0")
12041        (const_string "*")))
12042    (set_attr "mode" "SI")])
12043
12044 ;; Convert lea to the lea pattern to avoid flags dependency.
12045 (define_split
12046   [(set (match_operand 0 "register_operand" "")
12047         (ashift (match_operand 1 "index_register_operand" "")
12048                 (match_operand:QI 2 "const_int_operand" "")))
12049    (clobber (reg:CC FLAGS_REG))]
12050   "reload_completed
12051    && true_regnum (operands[0]) != true_regnum (operands[1])
12052    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
12053   [(const_int 0)]
12054 {
12055   rtx pat;
12056   enum machine_mode mode = GET_MODE (operands[0]);
12057
12058   if (GET_MODE_SIZE (mode) < 4)
12059     operands[0] = gen_lowpart (SImode, operands[0]);
12060   if (mode != Pmode)
12061     operands[1] = gen_lowpart (Pmode, operands[1]);
12062   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12063
12064   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
12065   if (Pmode != SImode)
12066     pat = gen_rtx_SUBREG (SImode, pat, 0);
12067   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
12068   DONE;
12069 })
12070
12071 ;; Rare case of shifting RSP is handled by generating move and shift
12072 (define_split
12073   [(set (match_operand 0 "register_operand" "")
12074         (ashift (match_operand 1 "register_operand" "")
12075                 (match_operand:QI 2 "const_int_operand" "")))
12076    (clobber (reg:CC FLAGS_REG))]
12077   "reload_completed
12078    && true_regnum (operands[0]) != true_regnum (operands[1])"
12079   [(const_int 0)]
12080 {
12081   rtx pat, clob;
12082   emit_move_insn (operands[0], operands[1]);
12083   pat = gen_rtx_SET (VOIDmode, operands[0],
12084                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
12085                                      operands[0], operands[2]));
12086   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
12087   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
12088   DONE;
12089 })
12090
12091 (define_insn "*ashlsi3_1_zext"
12092   [(set (match_operand:DI 0 "register_operand" "=r,r")
12093         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
12094                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
12095    (clobber (reg:CC FLAGS_REG))]
12096   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12097 {
12098   switch (get_attr_type (insn))
12099     {
12100     case TYPE_ALU:
12101       gcc_assert (operands[2] == const1_rtx);
12102       return "add{l}\t%k0, %k0";
12103
12104     case TYPE_LEA:
12105       return "#";
12106
12107     default:
12108       if (REG_P (operands[2]))
12109         return "sal{l}\t{%b2, %k0|%k0, %b2}";
12110       else if (operands[2] == const1_rtx
12111                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12112         return "sal{l}\t%k0";
12113       else
12114         return "sal{l}\t{%2, %k0|%k0, %2}";
12115     }
12116 }
12117   [(set (attr "type")
12118      (cond [(eq_attr "alternative" "1")
12119               (const_string "lea")
12120             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12121                      (const_int 0))
12122                  (match_operand 2 "const1_operand" ""))
12123               (const_string "alu")
12124            ]
12125            (const_string "ishift")))
12126    (set (attr "length_immediate")
12127      (if_then_else
12128        (ior (eq_attr "type" "alu")
12129             (and (eq_attr "type" "ishift")
12130                  (and (match_operand 2 "const1_operand" "")
12131                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12132                           (const_int 0)))))
12133        (const_string "0")
12134        (const_string "*")))
12135    (set_attr "mode" "SI")])
12136
12137 ;; Convert lea to the lea pattern to avoid flags dependency.
12138 (define_split
12139   [(set (match_operand:DI 0 "register_operand" "")
12140         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
12141                                 (match_operand:QI 2 "const_int_operand" ""))))
12142    (clobber (reg:CC FLAGS_REG))]
12143   "TARGET_64BIT && reload_completed
12144    && true_regnum (operands[0]) != true_regnum (operands[1])"
12145   [(set (match_dup 0) (zero_extend:DI
12146                         (subreg:SI (mult:SI (match_dup 1)
12147                                             (match_dup 2)) 0)))]
12148 {
12149   operands[1] = gen_lowpart (Pmode, operands[1]);
12150   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12151 })
12152
12153 ;; This pattern can't accept a variable shift count, since shifts by
12154 ;; zero don't affect the flags.  We assume that shifts by constant
12155 ;; zero are optimized away.
12156 (define_insn "*ashlsi3_cmp"
12157   [(set (reg FLAGS_REG)
12158         (compare
12159           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12160                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12161           (const_int 0)))
12162    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12163         (ashift:SI (match_dup 1) (match_dup 2)))]
12164    "(optimize_function_for_size_p (cfun)
12165      || !TARGET_PARTIAL_FLAG_REG_STALL
12166      || (operands[2] == const1_rtx
12167          && (TARGET_SHIFT1
12168              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12169    && ix86_match_ccmode (insn, CCGOCmode)
12170    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12171 {
12172   switch (get_attr_type (insn))
12173     {
12174     case TYPE_ALU:
12175       gcc_assert (operands[2] == const1_rtx);
12176       return "add{l}\t%0, %0";
12177
12178     default:
12179       if (REG_P (operands[2]))
12180         return "sal{l}\t{%b2, %0|%0, %b2}";
12181       else if (operands[2] == const1_rtx
12182                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12183         return "sal{l}\t%0";
12184       else
12185         return "sal{l}\t{%2, %0|%0, %2}";
12186     }
12187 }
12188   [(set (attr "type")
12189      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12190                           (const_int 0))
12191                       (match_operand 0 "register_operand" ""))
12192                  (match_operand 2 "const1_operand" ""))
12193               (const_string "alu")
12194            ]
12195            (const_string "ishift")))
12196    (set (attr "length_immediate")
12197      (if_then_else
12198        (ior (eq_attr "type" "alu")
12199             (and (eq_attr "type" "ishift")
12200                  (and (match_operand 2 "const1_operand" "")
12201                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12202                           (const_int 0)))))
12203        (const_string "0")
12204        (const_string "*")))
12205    (set_attr "mode" "SI")])
12206
12207 (define_insn "*ashlsi3_cconly"
12208   [(set (reg FLAGS_REG)
12209         (compare
12210           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12211                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12212           (const_int 0)))
12213    (clobber (match_scratch:SI 0 "=r"))]
12214   "(optimize_function_for_size_p (cfun)
12215     || !TARGET_PARTIAL_FLAG_REG_STALL
12216     || (operands[2] == const1_rtx
12217         && (TARGET_SHIFT1
12218             || TARGET_DOUBLE_WITH_ADD)))
12219    && ix86_match_ccmode (insn, CCGOCmode)
12220    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12221 {
12222   switch (get_attr_type (insn))
12223     {
12224     case TYPE_ALU:
12225       gcc_assert (operands[2] == const1_rtx);
12226       return "add{l}\t%0, %0";
12227
12228     default:
12229       if (REG_P (operands[2]))
12230         return "sal{l}\t{%b2, %0|%0, %b2}";
12231       else if (operands[2] == const1_rtx
12232                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12233         return "sal{l}\t%0";
12234       else
12235         return "sal{l}\t{%2, %0|%0, %2}";
12236     }
12237 }
12238   [(set (attr "type")
12239      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12240                           (const_int 0))
12241                       (match_operand 0 "register_operand" ""))
12242                  (match_operand 2 "const1_operand" ""))
12243               (const_string "alu")
12244            ]
12245            (const_string "ishift")))
12246    (set (attr "length_immediate")
12247      (if_then_else
12248        (ior (eq_attr "type" "alu")
12249             (and (eq_attr "type" "ishift")
12250                  (and (match_operand 2 "const1_operand" "")
12251                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12252                           (const_int 0)))))
12253        (const_string "0")
12254        (const_string "*")))
12255    (set_attr "mode" "SI")])
12256
12257 (define_insn "*ashlsi3_cmp_zext"
12258   [(set (reg FLAGS_REG)
12259         (compare
12260           (ashift:SI (match_operand:SI 1 "register_operand" "0")
12261                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12262           (const_int 0)))
12263    (set (match_operand:DI 0 "register_operand" "=r")
12264         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
12265   "TARGET_64BIT
12266    && (optimize_function_for_size_p (cfun)
12267        || !TARGET_PARTIAL_FLAG_REG_STALL
12268        || (operands[2] == const1_rtx
12269            && (TARGET_SHIFT1
12270                || TARGET_DOUBLE_WITH_ADD)))
12271    && ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12273 {
12274   switch (get_attr_type (insn))
12275     {
12276     case TYPE_ALU:
12277       gcc_assert (operands[2] == const1_rtx);
12278       return "add{l}\t%k0, %k0";
12279
12280     default:
12281       if (REG_P (operands[2]))
12282         return "sal{l}\t{%b2, %k0|%k0, %b2}";
12283       else if (operands[2] == const1_rtx
12284                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12285         return "sal{l}\t%k0";
12286       else
12287         return "sal{l}\t{%2, %k0|%k0, %2}";
12288     }
12289 }
12290   [(set (attr "type")
12291      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12292                      (const_int 0))
12293                  (match_operand 2 "const1_operand" ""))
12294               (const_string "alu")
12295            ]
12296            (const_string "ishift")))
12297    (set (attr "length_immediate")
12298      (if_then_else
12299        (ior (eq_attr "type" "alu")
12300             (and (eq_attr "type" "ishift")
12301                  (and (match_operand 2 "const1_operand" "")
12302                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12303                           (const_int 0)))))
12304        (const_string "0")
12305        (const_string "*")))
12306    (set_attr "mode" "SI")])
12307
12308 (define_expand "ashlhi3"
12309   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12310         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
12311                    (match_operand:QI 2 "nonmemory_operand" "")))]
12312   "TARGET_HIMODE_MATH"
12313   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
12314
12315 (define_insn "*ashlhi3_1_lea"
12316   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
12317         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
12318                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "!TARGET_PARTIAL_REG_STALL
12321    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12322 {
12323   switch (get_attr_type (insn))
12324     {
12325     case TYPE_LEA:
12326       return "#";
12327     case TYPE_ALU:
12328       gcc_assert (operands[2] == const1_rtx);
12329       return "add{w}\t%0, %0";
12330
12331     default:
12332       if (REG_P (operands[2]))
12333         return "sal{w}\t{%b2, %0|%0, %b2}";
12334       else if (operands[2] == const1_rtx
12335                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12336         return "sal{w}\t%0";
12337       else
12338         return "sal{w}\t{%2, %0|%0, %2}";
12339     }
12340 }
12341   [(set (attr "type")
12342      (cond [(eq_attr "alternative" "1")
12343               (const_string "lea")
12344             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12345                           (const_int 0))
12346                       (match_operand 0 "register_operand" ""))
12347                  (match_operand 2 "const1_operand" ""))
12348               (const_string "alu")
12349            ]
12350            (const_string "ishift")))
12351    (set (attr "length_immediate")
12352      (if_then_else
12353        (ior (eq_attr "type" "alu")
12354             (and (eq_attr "type" "ishift")
12355                  (and (match_operand 2 "const1_operand" "")
12356                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12357                           (const_int 0)))))
12358        (const_string "0")
12359        (const_string "*")))
12360    (set_attr "mode" "HI,SI")])
12361
12362 (define_insn "*ashlhi3_1"
12363   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12364         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12365                    (match_operand:QI 2 "nonmemory_operand" "cI")))
12366    (clobber (reg:CC FLAGS_REG))]
12367   "TARGET_PARTIAL_REG_STALL
12368    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12369 {
12370   switch (get_attr_type (insn))
12371     {
12372     case TYPE_ALU:
12373       gcc_assert (operands[2] == const1_rtx);
12374       return "add{w}\t%0, %0";
12375
12376     default:
12377       if (REG_P (operands[2]))
12378         return "sal{w}\t{%b2, %0|%0, %b2}";
12379       else if (operands[2] == const1_rtx
12380                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12381         return "sal{w}\t%0";
12382       else
12383         return "sal{w}\t{%2, %0|%0, %2}";
12384     }
12385 }
12386   [(set (attr "type")
12387      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12388                           (const_int 0))
12389                       (match_operand 0 "register_operand" ""))
12390                  (match_operand 2 "const1_operand" ""))
12391               (const_string "alu")
12392            ]
12393            (const_string "ishift")))
12394    (set (attr "length_immediate")
12395      (if_then_else
12396        (ior (eq_attr "type" "alu")
12397             (and (eq_attr "type" "ishift")
12398                  (and (match_operand 2 "const1_operand" "")
12399                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12400                           (const_int 0)))))
12401        (const_string "0")
12402        (const_string "*")))
12403    (set_attr "mode" "HI")])
12404
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags.  We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*ashlhi3_cmp"
12409   [(set (reg FLAGS_REG)
12410         (compare
12411           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12412                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12413           (const_int 0)))
12414    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12415         (ashift:HI (match_dup 1) (match_dup 2)))]
12416   "(optimize_function_for_size_p (cfun)
12417     || !TARGET_PARTIAL_FLAG_REG_STALL
12418     || (operands[2] == const1_rtx
12419         && (TARGET_SHIFT1
12420             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12421    && ix86_match_ccmode (insn, CCGOCmode)
12422    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12423 {
12424   switch (get_attr_type (insn))
12425     {
12426     case TYPE_ALU:
12427       gcc_assert (operands[2] == const1_rtx);
12428       return "add{w}\t%0, %0";
12429
12430     default:
12431       if (REG_P (operands[2]))
12432         return "sal{w}\t{%b2, %0|%0, %b2}";
12433       else if (operands[2] == const1_rtx
12434                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12435         return "sal{w}\t%0";
12436       else
12437         return "sal{w}\t{%2, %0|%0, %2}";
12438     }
12439 }
12440   [(set (attr "type")
12441      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12442                           (const_int 0))
12443                       (match_operand 0 "register_operand" ""))
12444                  (match_operand 2 "const1_operand" ""))
12445               (const_string "alu")
12446            ]
12447            (const_string "ishift")))
12448    (set (attr "length_immediate")
12449      (if_then_else
12450        (ior (eq_attr "type" "alu")
12451             (and (eq_attr "type" "ishift")
12452                  (and (match_operand 2 "const1_operand" "")
12453                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12454                           (const_int 0)))))
12455        (const_string "0")
12456        (const_string "*")))
12457    (set_attr "mode" "HI")])
12458
12459 (define_insn "*ashlhi3_cconly"
12460   [(set (reg FLAGS_REG)
12461         (compare
12462           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12463                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12464           (const_int 0)))
12465    (clobber (match_scratch:HI 0 "=r"))]
12466   "(optimize_function_for_size_p (cfun)
12467     || !TARGET_PARTIAL_FLAG_REG_STALL
12468     || (operands[2] == const1_rtx
12469         && (TARGET_SHIFT1
12470             || TARGET_DOUBLE_WITH_ADD)))
12471    && ix86_match_ccmode (insn, CCGOCmode)
12472    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12473 {
12474   switch (get_attr_type (insn))
12475     {
12476     case TYPE_ALU:
12477       gcc_assert (operands[2] == const1_rtx);
12478       return "add{w}\t%0, %0";
12479
12480     default:
12481       if (REG_P (operands[2]))
12482         return "sal{w}\t{%b2, %0|%0, %b2}";
12483       else if (operands[2] == const1_rtx
12484                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12485         return "sal{w}\t%0";
12486       else
12487         return "sal{w}\t{%2, %0|%0, %2}";
12488     }
12489 }
12490   [(set (attr "type")
12491      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12492                           (const_int 0))
12493                       (match_operand 0 "register_operand" ""))
12494                  (match_operand 2 "const1_operand" ""))
12495               (const_string "alu")
12496            ]
12497            (const_string "ishift")))
12498    (set (attr "length_immediate")
12499      (if_then_else
12500        (ior (eq_attr "type" "alu")
12501             (and (eq_attr "type" "ishift")
12502                  (and (match_operand 2 "const1_operand" "")
12503                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12504                           (const_int 0)))))
12505        (const_string "0")
12506        (const_string "*")))
12507    (set_attr "mode" "HI")])
12508
12509 (define_expand "ashlqi3"
12510   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12511         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
12512                    (match_operand:QI 2 "nonmemory_operand" "")))]
12513   "TARGET_QIMODE_MATH"
12514   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
12515
12516 ;; %%% Potential partial reg stall on alternative 2.  What to do?
12517
12518 (define_insn "*ashlqi3_1_lea"
12519   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
12520         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
12521                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
12522    (clobber (reg:CC FLAGS_REG))]
12523   "!TARGET_PARTIAL_REG_STALL
12524    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12525 {
12526   switch (get_attr_type (insn))
12527     {
12528     case TYPE_LEA:
12529       return "#";
12530     case TYPE_ALU:
12531       gcc_assert (operands[2] == const1_rtx);
12532       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12533         return "add{l}\t%k0, %k0";
12534       else
12535         return "add{b}\t%0, %0";
12536
12537     default:
12538       if (REG_P (operands[2]))
12539         {
12540           if (get_attr_mode (insn) == MODE_SI)
12541             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12542           else
12543             return "sal{b}\t{%b2, %0|%0, %b2}";
12544         }
12545       else if (operands[2] == const1_rtx
12546                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12547         {
12548           if (get_attr_mode (insn) == MODE_SI)
12549             return "sal{l}\t%0";
12550           else
12551             return "sal{b}\t%0";
12552         }
12553       else
12554         {
12555           if (get_attr_mode (insn) == MODE_SI)
12556             return "sal{l}\t{%2, %k0|%k0, %2}";
12557           else
12558             return "sal{b}\t{%2, %0|%0, %2}";
12559         }
12560     }
12561 }
12562   [(set (attr "type")
12563      (cond [(eq_attr "alternative" "2")
12564               (const_string "lea")
12565             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12566                           (const_int 0))
12567                       (match_operand 0 "register_operand" ""))
12568                  (match_operand 2 "const1_operand" ""))
12569               (const_string "alu")
12570            ]
12571            (const_string "ishift")))
12572    (set (attr "length_immediate")
12573      (if_then_else
12574        (ior (eq_attr "type" "alu")
12575             (and (eq_attr "type" "ishift")
12576                  (and (match_operand 2 "const1_operand" "")
12577                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12578                           (const_int 0)))))
12579        (const_string "0")
12580        (const_string "*")))
12581    (set_attr "mode" "QI,SI,SI")])
12582
12583 (define_insn "*ashlqi3_1"
12584   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12585         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12586                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "TARGET_PARTIAL_REG_STALL
12589    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12590 {
12591   switch (get_attr_type (insn))
12592     {
12593     case TYPE_ALU:
12594       gcc_assert (operands[2] == const1_rtx);
12595       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12596         return "add{l}\t%k0, %k0";
12597       else
12598         return "add{b}\t%0, %0";
12599
12600     default:
12601       if (REG_P (operands[2]))
12602         {
12603           if (get_attr_mode (insn) == MODE_SI)
12604             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12605           else
12606             return "sal{b}\t{%b2, %0|%0, %b2}";
12607         }
12608       else if (operands[2] == const1_rtx
12609                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12610         {
12611           if (get_attr_mode (insn) == MODE_SI)
12612             return "sal{l}\t%0";
12613           else
12614             return "sal{b}\t%0";
12615         }
12616       else
12617         {
12618           if (get_attr_mode (insn) == MODE_SI)
12619             return "sal{l}\t{%2, %k0|%k0, %2}";
12620           else
12621             return "sal{b}\t{%2, %0|%0, %2}";
12622         }
12623     }
12624 }
12625   [(set (attr "type")
12626      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12627                           (const_int 0))
12628                       (match_operand 0 "register_operand" ""))
12629                  (match_operand 2 "const1_operand" ""))
12630               (const_string "alu")
12631            ]
12632            (const_string "ishift")))
12633    (set (attr "length_immediate")
12634      (if_then_else
12635        (ior (eq_attr "type" "alu")
12636             (and (eq_attr "type" "ishift")
12637                  (and (match_operand 2 "const1_operand" "")
12638                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12639                           (const_int 0)))))
12640        (const_string "0")
12641        (const_string "*")))
12642    (set_attr "mode" "QI,SI")])
12643
12644 ;; This pattern can't accept a variable shift count, since shifts by
12645 ;; zero don't affect the flags.  We assume that shifts by constant
12646 ;; zero are optimized away.
12647 (define_insn "*ashlqi3_cmp"
12648   [(set (reg FLAGS_REG)
12649         (compare
12650           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12651                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12652           (const_int 0)))
12653    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12654         (ashift:QI (match_dup 1) (match_dup 2)))]
12655   "(optimize_function_for_size_p (cfun)
12656     || !TARGET_PARTIAL_FLAG_REG_STALL
12657     || (operands[2] == const1_rtx
12658         && (TARGET_SHIFT1
12659             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12660    && ix86_match_ccmode (insn, CCGOCmode)
12661    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12662 {
12663   switch (get_attr_type (insn))
12664     {
12665     case TYPE_ALU:
12666       gcc_assert (operands[2] == const1_rtx);
12667       return "add{b}\t%0, %0";
12668
12669     default:
12670       if (REG_P (operands[2]))
12671         return "sal{b}\t{%b2, %0|%0, %b2}";
12672       else if (operands[2] == const1_rtx
12673                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12674         return "sal{b}\t%0";
12675       else
12676         return "sal{b}\t{%2, %0|%0, %2}";
12677     }
12678 }
12679   [(set (attr "type")
12680      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12681                           (const_int 0))
12682                       (match_operand 0 "register_operand" ""))
12683                  (match_operand 2 "const1_operand" ""))
12684               (const_string "alu")
12685            ]
12686            (const_string "ishift")))
12687    (set (attr "length_immediate")
12688      (if_then_else
12689        (ior (eq_attr "type" "alu")
12690             (and (eq_attr "type" "ishift")
12691                  (and (match_operand 2 "const1_operand" "")
12692                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12693                           (const_int 0)))))
12694        (const_string "0")
12695        (const_string "*")))
12696    (set_attr "mode" "QI")])
12697
12698 (define_insn "*ashlqi3_cconly"
12699   [(set (reg FLAGS_REG)
12700         (compare
12701           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12702                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12703           (const_int 0)))
12704    (clobber (match_scratch:QI 0 "=q"))]
12705   "(optimize_function_for_size_p (cfun)
12706     || !TARGET_PARTIAL_FLAG_REG_STALL
12707     || (operands[2] == const1_rtx
12708         && (TARGET_SHIFT1
12709             || TARGET_DOUBLE_WITH_ADD)))
12710    && ix86_match_ccmode (insn, CCGOCmode)
12711    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12712 {
12713   switch (get_attr_type (insn))
12714     {
12715     case TYPE_ALU:
12716       gcc_assert (operands[2] == const1_rtx);
12717       return "add{b}\t%0, %0";
12718
12719     default:
12720       if (REG_P (operands[2]))
12721         return "sal{b}\t{%b2, %0|%0, %b2}";
12722       else if (operands[2] == const1_rtx
12723                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12724         return "sal{b}\t%0";
12725       else
12726         return "sal{b}\t{%2, %0|%0, %2}";
12727     }
12728 }
12729   [(set (attr "type")
12730      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12731                           (const_int 0))
12732                       (match_operand 0 "register_operand" ""))
12733                  (match_operand 2 "const1_operand" ""))
12734               (const_string "alu")
12735            ]
12736            (const_string "ishift")))
12737    (set (attr "length_immediate")
12738      (if_then_else
12739        (ior (eq_attr "type" "alu")
12740             (and (eq_attr "type" "ishift")
12741                  (and (match_operand 2 "const1_operand" "")
12742                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12743                           (const_int 0)))))
12744        (const_string "0")
12745        (const_string "*")))
12746    (set_attr "mode" "QI")])
12747
12748 ;; See comment above `ashldi3' about how this works.
12749
12750 (define_expand "ashrti3"
12751   [(set (match_operand:TI 0 "register_operand" "")
12752         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12753                      (match_operand:QI 2 "nonmemory_operand" "")))]
12754   "TARGET_64BIT"
12755   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12756
12757 (define_insn "*ashrti3_1"
12758   [(set (match_operand:TI 0 "register_operand" "=r")
12759         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12760                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12761    (clobber (reg:CC FLAGS_REG))]
12762   "TARGET_64BIT"
12763   "#"
12764   [(set_attr "type" "multi")])
12765
12766 (define_peephole2
12767   [(match_scratch:DI 3 "r")
12768    (parallel [(set (match_operand:TI 0 "register_operand" "")
12769                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12770                                 (match_operand:QI 2 "nonmemory_operand" "")))
12771               (clobber (reg:CC FLAGS_REG))])
12772    (match_dup 3)]
12773   "TARGET_64BIT"
12774   [(const_int 0)]
12775   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12776
12777 (define_split
12778   [(set (match_operand:TI 0 "register_operand" "")
12779         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12780                      (match_operand:QI 2 "nonmemory_operand" "")))
12781    (clobber (reg:CC FLAGS_REG))]
12782   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12783                     ? epilogue_completed : reload_completed)"
12784   [(const_int 0)]
12785   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12786
12787 (define_insn "x86_64_shrd"
12788   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12789         (ior:DI (ashiftrt:DI (match_dup 0)
12790                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12791                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12792                   (minus:QI (const_int 64) (match_dup 2)))))
12793    (clobber (reg:CC FLAGS_REG))]
12794   "TARGET_64BIT"
12795   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12796   [(set_attr "type" "ishift")
12797    (set_attr "prefix_0f" "1")
12798    (set_attr "mode" "DI")
12799    (set_attr "athlon_decode" "vector")
12800    (set_attr "amdfam10_decode" "vector")])
12801
12802 (define_expand "ashrdi3"
12803   [(set (match_operand:DI 0 "shiftdi_operand" "")
12804         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12805                      (match_operand:QI 2 "nonmemory_operand" "")))]
12806   ""
12807   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12808
12809 (define_expand "x86_64_shift_adj_3"
12810   [(use (match_operand:DI 0 "register_operand" ""))
12811    (use (match_operand:DI 1 "register_operand" ""))
12812    (use (match_operand:QI 2 "register_operand" ""))]
12813   ""
12814 {
12815   rtx label = gen_label_rtx ();
12816   rtx tmp;
12817
12818   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12819
12820   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12821   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12822   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12823                               gen_rtx_LABEL_REF (VOIDmode, label),
12824                               pc_rtx);
12825   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12826   JUMP_LABEL (tmp) = label;
12827
12828   emit_move_insn (operands[0], operands[1]);
12829   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12830
12831   emit_label (label);
12832   LABEL_NUSES (label) = 1;
12833
12834   DONE;
12835 })
12836
12837 (define_insn "ashrdi3_63_rex64"
12838   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12839         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12840                      (match_operand:DI 2 "const_int_operand" "i,i")))
12841    (clobber (reg:CC FLAGS_REG))]
12842   "TARGET_64BIT && INTVAL (operands[2]) == 63
12843    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12844    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12845   "@
12846    {cqto|cqo}
12847    sar{q}\t{%2, %0|%0, %2}"
12848   [(set_attr "type" "imovx,ishift")
12849    (set_attr "prefix_0f" "0,*")
12850    (set_attr "length_immediate" "0,*")
12851    (set_attr "modrm" "0,1")
12852    (set_attr "mode" "DI")])
12853
12854 (define_insn "*ashrdi3_1_one_bit_rex64"
12855   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12856         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12857                      (match_operand:QI 2 "const1_operand" "")))
12858    (clobber (reg:CC FLAGS_REG))]
12859   "TARGET_64BIT
12860    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12861    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12862   "sar{q}\t%0"
12863   [(set_attr "type" "ishift")
12864    (set_attr "length_immediate" "0")
12865    (set_attr "mode" "DI")])
12866
12867 (define_insn "*ashrdi3_1_rex64"
12868   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12869         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12870                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12871    (clobber (reg:CC FLAGS_REG))]
12872   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12873   "@
12874    sar{q}\t{%2, %0|%0, %2}
12875    sar{q}\t{%b2, %0|%0, %b2}"
12876   [(set_attr "type" "ishift")
12877    (set_attr "mode" "DI")])
12878
12879 ;; This pattern can't accept a variable shift count, since shifts by
12880 ;; zero don't affect the flags.  We assume that shifts by constant
12881 ;; zero are optimized away.
12882 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12883   [(set (reg FLAGS_REG)
12884         (compare
12885           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12886                        (match_operand:QI 2 "const1_operand" ""))
12887           (const_int 0)))
12888    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12889         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12890   "TARGET_64BIT
12891    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12892    && ix86_match_ccmode (insn, CCGOCmode)
12893    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12894   "sar{q}\t%0"
12895   [(set_attr "type" "ishift")
12896    (set_attr "length_immediate" "0")
12897    (set_attr "mode" "DI")])
12898
12899 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12900   [(set (reg FLAGS_REG)
12901         (compare
12902           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12903                        (match_operand:QI 2 "const1_operand" ""))
12904           (const_int 0)))
12905    (clobber (match_scratch:DI 0 "=r"))]
12906   "TARGET_64BIT
12907    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12908    && ix86_match_ccmode (insn, CCGOCmode)
12909    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12910   "sar{q}\t%0"
12911   [(set_attr "type" "ishift")
12912    (set_attr "length_immediate" "0")
12913    (set_attr "mode" "DI")])
12914
12915 ;; This pattern can't accept a variable shift count, since shifts by
12916 ;; zero don't affect the flags.  We assume that shifts by constant
12917 ;; zero are optimized away.
12918 (define_insn "*ashrdi3_cmp_rex64"
12919   [(set (reg FLAGS_REG)
12920         (compare
12921           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12922                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12923           (const_int 0)))
12924    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12925         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12926   "TARGET_64BIT
12927    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12928    && ix86_match_ccmode (insn, CCGOCmode)
12929    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12930   "sar{q}\t{%2, %0|%0, %2}"
12931   [(set_attr "type" "ishift")
12932    (set_attr "mode" "DI")])
12933
12934 (define_insn "*ashrdi3_cconly_rex64"
12935   [(set (reg FLAGS_REG)
12936         (compare
12937           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12938                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12939           (const_int 0)))
12940    (clobber (match_scratch:DI 0 "=r"))]
12941   "TARGET_64BIT
12942    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12943    && ix86_match_ccmode (insn, CCGOCmode)
12944    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12945   "sar{q}\t{%2, %0|%0, %2}"
12946   [(set_attr "type" "ishift")
12947    (set_attr "mode" "DI")])
12948
12949 (define_insn "*ashrdi3_1"
12950   [(set (match_operand:DI 0 "register_operand" "=r")
12951         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12952                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12953    (clobber (reg:CC FLAGS_REG))]
12954   "!TARGET_64BIT"
12955   "#"
12956   [(set_attr "type" "multi")])
12957
12958 ;; By default we don't ask for a scratch register, because when DImode
12959 ;; values are manipulated, registers are already at a premium.  But if
12960 ;; we have one handy, we won't turn it away.
12961 (define_peephole2
12962   [(match_scratch:SI 3 "r")
12963    (parallel [(set (match_operand:DI 0 "register_operand" "")
12964                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12965                                 (match_operand:QI 2 "nonmemory_operand" "")))
12966               (clobber (reg:CC FLAGS_REG))])
12967    (match_dup 3)]
12968   "!TARGET_64BIT && TARGET_CMOVE"
12969   [(const_int 0)]
12970   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12971
12972 (define_split
12973   [(set (match_operand:DI 0 "register_operand" "")
12974         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12975                      (match_operand:QI 2 "nonmemory_operand" "")))
12976    (clobber (reg:CC FLAGS_REG))]
12977   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12978                      ? epilogue_completed : reload_completed)"
12979   [(const_int 0)]
12980   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12981
12982 (define_insn "x86_shrd"
12983   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12984         (ior:SI (ashiftrt:SI (match_dup 0)
12985                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12986                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12987                   (minus:QI (const_int 32) (match_dup 2)))))
12988    (clobber (reg:CC FLAGS_REG))]
12989   ""
12990   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12991   [(set_attr "type" "ishift")
12992    (set_attr "prefix_0f" "1")
12993    (set_attr "pent_pair" "np")
12994    (set_attr "mode" "SI")])
12995
12996 (define_expand "x86_shift_adj_3"
12997   [(use (match_operand:SI 0 "register_operand" ""))
12998    (use (match_operand:SI 1 "register_operand" ""))
12999    (use (match_operand:QI 2 "register_operand" ""))]
13000   ""
13001 {
13002   rtx label = gen_label_rtx ();
13003   rtx tmp;
13004
13005   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
13006
13007   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13008   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13009   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13010                               gen_rtx_LABEL_REF (VOIDmode, label),
13011                               pc_rtx);
13012   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
13013   JUMP_LABEL (tmp) = label;
13014
13015   emit_move_insn (operands[0], operands[1]);
13016   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
13017
13018   emit_label (label);
13019   LABEL_NUSES (label) = 1;
13020
13021   DONE;
13022 })
13023
13024 (define_expand "ashrsi3_31"
13025   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13026                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13027                                 (match_operand:SI 2 "const_int_operand" "i,i")))
13028               (clobber (reg:CC FLAGS_REG))])]
13029   "")
13030
13031 (define_insn "*ashrsi3_31"
13032   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13033         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13034                      (match_operand:SI 2 "const_int_operand" "i,i")))
13035    (clobber (reg:CC FLAGS_REG))]
13036   "INTVAL (operands[2]) == 31
13037    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13038    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13039   "@
13040    {cltd|cdq}
13041    sar{l}\t{%2, %0|%0, %2}"
13042   [(set_attr "type" "imovx,ishift")
13043    (set_attr "prefix_0f" "0,*")
13044    (set_attr "length_immediate" "0,*")
13045    (set_attr "modrm" "0,1")
13046    (set_attr "mode" "SI")])
13047
13048 (define_insn "*ashrsi3_31_zext"
13049   [(set (match_operand:DI 0 "register_operand" "=*d,r")
13050         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
13051                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
13052    (clobber (reg:CC FLAGS_REG))]
13053   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13054    && INTVAL (operands[2]) == 31
13055    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13056   "@
13057    {cltd|cdq}
13058    sar{l}\t{%2, %k0|%k0, %2}"
13059   [(set_attr "type" "imovx,ishift")
13060    (set_attr "prefix_0f" "0,*")
13061    (set_attr "length_immediate" "0,*")
13062    (set_attr "modrm" "0,1")
13063    (set_attr "mode" "SI")])
13064
13065 (define_expand "ashrsi3"
13066   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13067         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13068                      (match_operand:QI 2 "nonmemory_operand" "")))]
13069   ""
13070   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
13071
13072 (define_insn "*ashrsi3_1_one_bit"
13073   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13074         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13075                      (match_operand:QI 2 "const1_operand" "")))
13076    (clobber (reg:CC FLAGS_REG))]
13077   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13078    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13079   "sar{l}\t%0"
13080   [(set_attr "type" "ishift")
13081    (set_attr "length_immediate" "0")
13082    (set_attr "mode" "SI")])
13083
13084 (define_insn "*ashrsi3_1_one_bit_zext"
13085   [(set (match_operand:DI 0 "register_operand" "=r")
13086         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13087                                      (match_operand:QI 2 "const1_operand" ""))))
13088    (clobber (reg:CC FLAGS_REG))]
13089   "TARGET_64BIT
13090    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13092   "sar{l}\t%k0"
13093   [(set_attr "type" "ishift")
13094    (set_attr "length_immediate" "0")
13095    (set_attr "mode" "SI")])
13096
13097 (define_insn "*ashrsi3_1"
13098   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13099         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13100                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13101    (clobber (reg:CC FLAGS_REG))]
13102   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13103   "@
13104    sar{l}\t{%2, %0|%0, %2}
13105    sar{l}\t{%b2, %0|%0, %b2}"
13106   [(set_attr "type" "ishift")
13107    (set_attr "mode" "SI")])
13108
13109 (define_insn "*ashrsi3_1_zext"
13110   [(set (match_operand:DI 0 "register_operand" "=r,r")
13111         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
13112                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13113    (clobber (reg:CC FLAGS_REG))]
13114   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13115   "@
13116    sar{l}\t{%2, %k0|%k0, %2}
13117    sar{l}\t{%b2, %k0|%k0, %b2}"
13118   [(set_attr "type" "ishift")
13119    (set_attr "mode" "SI")])
13120
13121 ;; This pattern can't accept a variable shift count, since shifts by
13122 ;; zero don't affect the flags.  We assume that shifts by constant
13123 ;; zero are optimized away.
13124 (define_insn "*ashrsi3_one_bit_cmp"
13125   [(set (reg FLAGS_REG)
13126         (compare
13127           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13128                        (match_operand:QI 2 "const1_operand" ""))
13129           (const_int 0)))
13130    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13131         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13132   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13133    && ix86_match_ccmode (insn, CCGOCmode)
13134    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13135   "sar{l}\t%0"
13136   [(set_attr "type" "ishift")
13137    (set_attr "length_immediate" "0")
13138    (set_attr "mode" "SI")])
13139
13140 (define_insn "*ashrsi3_one_bit_cconly"
13141   [(set (reg FLAGS_REG)
13142         (compare
13143           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13144                        (match_operand:QI 2 "const1_operand" ""))
13145           (const_int 0)))
13146    (clobber (match_scratch:SI 0 "=r"))]
13147   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13148    && ix86_match_ccmode (insn, CCGOCmode)
13149    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13150   "sar{l}\t%0"
13151   [(set_attr "type" "ishift")
13152    (set_attr "length_immediate" "0")
13153    (set_attr "mode" "SI")])
13154
13155 (define_insn "*ashrsi3_one_bit_cmp_zext"
13156   [(set (reg FLAGS_REG)
13157         (compare
13158           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13159                        (match_operand:QI 2 "const1_operand" ""))
13160           (const_int 0)))
13161    (set (match_operand:DI 0 "register_operand" "=r")
13162         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13163   "TARGET_64BIT
13164    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13165    && ix86_match_ccmode (insn, CCmode)
13166    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13167   "sar{l}\t%k0"
13168   [(set_attr "type" "ishift")
13169    (set_attr "length_immediate" "0")
13170    (set_attr "mode" "SI")])
13171
13172 ;; This pattern can't accept a variable shift count, since shifts by
13173 ;; zero don't affect the flags.  We assume that shifts by constant
13174 ;; zero are optimized away.
13175 (define_insn "*ashrsi3_cmp"
13176   [(set (reg FLAGS_REG)
13177         (compare
13178           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13179                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13180           (const_int 0)))
13181    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13182         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13183   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13184    && ix86_match_ccmode (insn, CCGOCmode)
13185    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13186   "sar{l}\t{%2, %0|%0, %2}"
13187   [(set_attr "type" "ishift")
13188    (set_attr "mode" "SI")])
13189
13190 (define_insn "*ashrsi3_cconly"
13191   [(set (reg FLAGS_REG)
13192         (compare
13193           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13194                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13195           (const_int 0)))
13196    (clobber (match_scratch:SI 0 "=r"))]
13197   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13198    && ix86_match_ccmode (insn, CCGOCmode)
13199    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13200   "sar{l}\t{%2, %0|%0, %2}"
13201   [(set_attr "type" "ishift")
13202    (set_attr "mode" "SI")])
13203
13204 (define_insn "*ashrsi3_cmp_zext"
13205   [(set (reg FLAGS_REG)
13206         (compare
13207           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13208                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13209           (const_int 0)))
13210    (set (match_operand:DI 0 "register_operand" "=r")
13211         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13212   "TARGET_64BIT
13213    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13214    && ix86_match_ccmode (insn, CCGOCmode)
13215    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13216   "sar{l}\t{%2, %k0|%k0, %2}"
13217   [(set_attr "type" "ishift")
13218    (set_attr "mode" "SI")])
13219
13220 (define_expand "ashrhi3"
13221   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13222         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13223                      (match_operand:QI 2 "nonmemory_operand" "")))]
13224   "TARGET_HIMODE_MATH"
13225   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
13226
13227 (define_insn "*ashrhi3_1_one_bit"
13228   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13229         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13230                      (match_operand:QI 2 "const1_operand" "")))
13231    (clobber (reg:CC FLAGS_REG))]
13232   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13233    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13234   "sar{w}\t%0"
13235   [(set_attr "type" "ishift")
13236    (set_attr "length_immediate" "0")
13237    (set_attr "mode" "HI")])
13238
13239 (define_insn "*ashrhi3_1"
13240   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13241         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13242                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13243    (clobber (reg:CC FLAGS_REG))]
13244   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13245   "@
13246    sar{w}\t{%2, %0|%0, %2}
13247    sar{w}\t{%b2, %0|%0, %b2}"
13248   [(set_attr "type" "ishift")
13249    (set_attr "mode" "HI")])
13250
13251 ;; This pattern can't accept a variable shift count, since shifts by
13252 ;; zero don't affect the flags.  We assume that shifts by constant
13253 ;; zero are optimized away.
13254 (define_insn "*ashrhi3_one_bit_cmp"
13255   [(set (reg FLAGS_REG)
13256         (compare
13257           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13258                        (match_operand:QI 2 "const1_operand" ""))
13259           (const_int 0)))
13260    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13261         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13262   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13263    && ix86_match_ccmode (insn, CCGOCmode)
13264    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13265   "sar{w}\t%0"
13266   [(set_attr "type" "ishift")
13267    (set_attr "length_immediate" "0")
13268    (set_attr "mode" "HI")])
13269
13270 (define_insn "*ashrhi3_one_bit_cconly"
13271   [(set (reg FLAGS_REG)
13272         (compare
13273           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13274                        (match_operand:QI 2 "const1_operand" ""))
13275           (const_int 0)))
13276    (clobber (match_scratch:HI 0 "=r"))]
13277   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13278    && ix86_match_ccmode (insn, CCGOCmode)
13279    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13280   "sar{w}\t%0"
13281   [(set_attr "type" "ishift")
13282    (set_attr "length_immediate" "0")
13283    (set_attr "mode" "HI")])
13284
13285 ;; This pattern can't accept a variable shift count, since shifts by
13286 ;; zero don't affect the flags.  We assume that shifts by constant
13287 ;; zero are optimized away.
13288 (define_insn "*ashrhi3_cmp"
13289   [(set (reg FLAGS_REG)
13290         (compare
13291           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13292                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13293           (const_int 0)))
13294    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13295         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13296   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13297    && ix86_match_ccmode (insn, CCGOCmode)
13298    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13299   "sar{w}\t{%2, %0|%0, %2}"
13300   [(set_attr "type" "ishift")
13301    (set_attr "mode" "HI")])
13302
13303 (define_insn "*ashrhi3_cconly"
13304   [(set (reg FLAGS_REG)
13305         (compare
13306           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13307                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13308           (const_int 0)))
13309    (clobber (match_scratch:HI 0 "=r"))]
13310   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13311    && ix86_match_ccmode (insn, CCGOCmode)
13312    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13313   "sar{w}\t{%2, %0|%0, %2}"
13314   [(set_attr "type" "ishift")
13315    (set_attr "mode" "HI")])
13316
13317 (define_expand "ashrqi3"
13318   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13319         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13320                      (match_operand:QI 2 "nonmemory_operand" "")))]
13321   "TARGET_QIMODE_MATH"
13322   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
13323
13324 (define_insn "*ashrqi3_1_one_bit"
13325   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13326         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13327                      (match_operand:QI 2 "const1_operand" "")))
13328    (clobber (reg:CC FLAGS_REG))]
13329   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13330    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13331   "sar{b}\t%0"
13332   [(set_attr "type" "ishift")
13333    (set_attr "length_immediate" "0")
13334    (set_attr "mode" "QI")])
13335
13336 (define_insn "*ashrqi3_1_one_bit_slp"
13337   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13338         (ashiftrt:QI (match_dup 0)
13339                      (match_operand:QI 1 "const1_operand" "")))
13340    (clobber (reg:CC FLAGS_REG))]
13341   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13342    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13343    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13344   "sar{b}\t%0"
13345   [(set_attr "type" "ishift1")
13346    (set_attr "length_immediate" "0")
13347    (set_attr "mode" "QI")])
13348
13349 (define_insn "*ashrqi3_1"
13350   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13351         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13352                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13353    (clobber (reg:CC FLAGS_REG))]
13354   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13355   "@
13356    sar{b}\t{%2, %0|%0, %2}
13357    sar{b}\t{%b2, %0|%0, %b2}"
13358   [(set_attr "type" "ishift")
13359    (set_attr "mode" "QI")])
13360
13361 (define_insn "*ashrqi3_1_slp"
13362   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13363         (ashiftrt:QI (match_dup 0)
13364                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13365    (clobber (reg:CC FLAGS_REG))]
13366   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13367    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13368   "@
13369    sar{b}\t{%1, %0|%0, %1}
13370    sar{b}\t{%b1, %0|%0, %b1}"
13371   [(set_attr "type" "ishift1")
13372    (set_attr "mode" "QI")])
13373
13374 ;; This pattern can't accept a variable shift count, since shifts by
13375 ;; zero don't affect the flags.  We assume that shifts by constant
13376 ;; zero are optimized away.
13377 (define_insn "*ashrqi3_one_bit_cmp"
13378   [(set (reg FLAGS_REG)
13379         (compare
13380           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13381                        (match_operand:QI 2 "const1_operand" "I"))
13382           (const_int 0)))
13383    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13384         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13385   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13386    && ix86_match_ccmode (insn, CCGOCmode)
13387    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13388   "sar{b}\t%0"
13389   [(set_attr "type" "ishift")
13390    (set_attr "length_immediate" "0")
13391    (set_attr "mode" "QI")])
13392
13393 (define_insn "*ashrqi3_one_bit_cconly"
13394   [(set (reg FLAGS_REG)
13395         (compare
13396           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13397                        (match_operand:QI 2 "const1_operand" ""))
13398           (const_int 0)))
13399    (clobber (match_scratch:QI 0 "=q"))]
13400   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13401    && ix86_match_ccmode (insn, CCGOCmode)
13402    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13403   "sar{b}\t%0"
13404   [(set_attr "type" "ishift")
13405    (set_attr "length_immediate" "0")
13406    (set_attr "mode" "QI")])
13407
13408 ;; This pattern can't accept a variable shift count, since shifts by
13409 ;; zero don't affect the flags.  We assume that shifts by constant
13410 ;; zero are optimized away.
13411 (define_insn "*ashrqi3_cmp"
13412   [(set (reg FLAGS_REG)
13413         (compare
13414           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13415                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13416           (const_int 0)))
13417    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13418         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13419   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13420    && ix86_match_ccmode (insn, CCGOCmode)
13421    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13422   "sar{b}\t{%2, %0|%0, %2}"
13423   [(set_attr "type" "ishift")
13424    (set_attr "mode" "QI")])
13425
13426 (define_insn "*ashrqi3_cconly"
13427   [(set (reg FLAGS_REG)
13428         (compare
13429           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13430                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13431           (const_int 0)))
13432    (clobber (match_scratch:QI 0 "=q"))]
13433   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13434    && ix86_match_ccmode (insn, CCGOCmode)
13435    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13436   "sar{b}\t{%2, %0|%0, %2}"
13437   [(set_attr "type" "ishift")
13438    (set_attr "mode" "QI")])
13439
13440 \f
13441 ;; Logical shift instructions
13442
13443 ;; See comment above `ashldi3' about how this works.
13444
13445 (define_expand "lshrti3"
13446   [(set (match_operand:TI 0 "register_operand" "")
13447         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13448                      (match_operand:QI 2 "nonmemory_operand" "")))]
13449   "TARGET_64BIT"
13450   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
13451
13452 ;; This pattern must be defined before *lshrti3_1 to prevent
13453 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
13454
13455 (define_insn "*avx_lshrti3"
13456   [(set (match_operand:TI 0 "register_operand" "=x")
13457         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
13458                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13459   "TARGET_AVX"
13460 {
13461   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13462   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
13463 }
13464   [(set_attr "type" "sseishft")
13465    (set_attr "prefix" "vex")
13466    (set_attr "length_immediate" "1")
13467    (set_attr "mode" "TI")])
13468
13469 (define_insn "sse2_lshrti3"
13470   [(set (match_operand:TI 0 "register_operand" "=x")
13471         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13472                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13473   "TARGET_SSE2"
13474 {
13475   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13476   return "psrldq\t{%2, %0|%0, %2}";
13477 }
13478   [(set_attr "type" "sseishft")
13479    (set_attr "prefix_data16" "1")
13480    (set_attr "length_immediate" "1")
13481    (set_attr "mode" "TI")])
13482
13483 (define_insn "*lshrti3_1"
13484   [(set (match_operand:TI 0 "register_operand" "=r")
13485         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13486                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
13487    (clobber (reg:CC FLAGS_REG))]
13488   "TARGET_64BIT"
13489   "#"
13490   [(set_attr "type" "multi")])
13491
13492 (define_peephole2
13493   [(match_scratch:DI 3 "r")
13494    (parallel [(set (match_operand:TI 0 "register_operand" "")
13495                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13496                                 (match_operand:QI 2 "nonmemory_operand" "")))
13497               (clobber (reg:CC FLAGS_REG))])
13498    (match_dup 3)]
13499   "TARGET_64BIT"
13500   [(const_int 0)]
13501   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
13502
13503 (define_split
13504   [(set (match_operand:TI 0 "register_operand" "")
13505         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13506                      (match_operand:QI 2 "nonmemory_operand" "")))
13507    (clobber (reg:CC FLAGS_REG))]
13508   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13509                     ? epilogue_completed : reload_completed)"
13510   [(const_int 0)]
13511   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
13512
13513 (define_expand "lshrdi3"
13514   [(set (match_operand:DI 0 "shiftdi_operand" "")
13515         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
13516                      (match_operand:QI 2 "nonmemory_operand" "")))]
13517   ""
13518   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
13519
13520 (define_insn "*lshrdi3_1_one_bit_rex64"
13521   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13522         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13523                      (match_operand:QI 2 "const1_operand" "")))
13524    (clobber (reg:CC FLAGS_REG))]
13525   "TARGET_64BIT
13526    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13527    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13528   "shr{q}\t%0"
13529   [(set_attr "type" "ishift")
13530    (set_attr "length_immediate" "0")
13531    (set_attr "mode" "DI")])
13532
13533 (define_insn "*lshrdi3_1_rex64"
13534   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13535         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13536                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13537    (clobber (reg:CC FLAGS_REG))]
13538   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13539   "@
13540    shr{q}\t{%2, %0|%0, %2}
13541    shr{q}\t{%b2, %0|%0, %b2}"
13542   [(set_attr "type" "ishift")
13543    (set_attr "mode" "DI")])
13544
13545 ;; This pattern can't accept a variable shift count, since shifts by
13546 ;; zero don't affect the flags.  We assume that shifts by constant
13547 ;; zero are optimized away.
13548 (define_insn "*lshrdi3_cmp_one_bit_rex64"
13549   [(set (reg FLAGS_REG)
13550         (compare
13551           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13552                        (match_operand:QI 2 "const1_operand" ""))
13553           (const_int 0)))
13554    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13555         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13556   "TARGET_64BIT
13557    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13558    && ix86_match_ccmode (insn, CCGOCmode)
13559    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13560   "shr{q}\t%0"
13561   [(set_attr "type" "ishift")
13562    (set_attr "length_immediate" "0")
13563    (set_attr "mode" "DI")])
13564
13565 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13566   [(set (reg FLAGS_REG)
13567         (compare
13568           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13569                        (match_operand:QI 2 "const1_operand" ""))
13570           (const_int 0)))
13571    (clobber (match_scratch:DI 0 "=r"))]
13572   "TARGET_64BIT
13573    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13574    && ix86_match_ccmode (insn, CCGOCmode)
13575    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13576   "shr{q}\t%0"
13577   [(set_attr "type" "ishift")
13578    (set_attr "length_immediate" "0")
13579    (set_attr "mode" "DI")])
13580
13581 ;; This pattern can't accept a variable shift count, since shifts by
13582 ;; zero don't affect the flags.  We assume that shifts by constant
13583 ;; zero are optimized away.
13584 (define_insn "*lshrdi3_cmp_rex64"
13585   [(set (reg FLAGS_REG)
13586         (compare
13587           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13588                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13589           (const_int 0)))
13590    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13591         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13592   "TARGET_64BIT
13593    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13594    && ix86_match_ccmode (insn, CCGOCmode)
13595    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13596   "shr{q}\t{%2, %0|%0, %2}"
13597   [(set_attr "type" "ishift")
13598    (set_attr "mode" "DI")])
13599
13600 (define_insn "*lshrdi3_cconly_rex64"
13601   [(set (reg FLAGS_REG)
13602         (compare
13603           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13604                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13605           (const_int 0)))
13606    (clobber (match_scratch:DI 0 "=r"))]
13607   "TARGET_64BIT
13608    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13609    && ix86_match_ccmode (insn, CCGOCmode)
13610    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13611   "shr{q}\t{%2, %0|%0, %2}"
13612   [(set_attr "type" "ishift")
13613    (set_attr "mode" "DI")])
13614
13615 (define_insn "*lshrdi3_1"
13616   [(set (match_operand:DI 0 "register_operand" "=r")
13617         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13618                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
13619    (clobber (reg:CC FLAGS_REG))]
13620   "!TARGET_64BIT"
13621   "#"
13622   [(set_attr "type" "multi")])
13623
13624 ;; By default we don't ask for a scratch register, because when DImode
13625 ;; values are manipulated, registers are already at a premium.  But if
13626 ;; we have one handy, we won't turn it away.
13627 (define_peephole2
13628   [(match_scratch:SI 3 "r")
13629    (parallel [(set (match_operand:DI 0 "register_operand" "")
13630                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13631                                 (match_operand:QI 2 "nonmemory_operand" "")))
13632               (clobber (reg:CC FLAGS_REG))])
13633    (match_dup 3)]
13634   "!TARGET_64BIT && TARGET_CMOVE"
13635   [(const_int 0)]
13636   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13637
13638 (define_split
13639   [(set (match_operand:DI 0 "register_operand" "")
13640         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13641                      (match_operand:QI 2 "nonmemory_operand" "")))
13642    (clobber (reg:CC FLAGS_REG))]
13643   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13644                      ? epilogue_completed : reload_completed)"
13645   [(const_int 0)]
13646   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13647
13648 (define_expand "lshrsi3"
13649   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13650         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13651                      (match_operand:QI 2 "nonmemory_operand" "")))]
13652   ""
13653   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13654
13655 (define_insn "*lshrsi3_1_one_bit"
13656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13657         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13658                      (match_operand:QI 2 "const1_operand" "")))
13659    (clobber (reg:CC FLAGS_REG))]
13660   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13661    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13662   "shr{l}\t%0"
13663   [(set_attr "type" "ishift")
13664    (set_attr "length_immediate" "0")
13665    (set_attr "mode" "SI")])
13666
13667 (define_insn "*lshrsi3_1_one_bit_zext"
13668   [(set (match_operand:DI 0 "register_operand" "=r")
13669         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13670                      (match_operand:QI 2 "const1_operand" "")))
13671    (clobber (reg:CC FLAGS_REG))]
13672   "TARGET_64BIT
13673    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13674    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13675   "shr{l}\t%k0"
13676   [(set_attr "type" "ishift")
13677    (set_attr "length_immediate" "0")
13678    (set_attr "mode" "SI")])
13679
13680 (define_insn "*lshrsi3_1"
13681   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13682         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13683                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13684    (clobber (reg:CC FLAGS_REG))]
13685   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13686   "@
13687    shr{l}\t{%2, %0|%0, %2}
13688    shr{l}\t{%b2, %0|%0, %b2}"
13689   [(set_attr "type" "ishift")
13690    (set_attr "mode" "SI")])
13691
13692 (define_insn "*lshrsi3_1_zext"
13693   [(set (match_operand:DI 0 "register_operand" "=r,r")
13694         (zero_extend:DI
13695           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13696                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13697    (clobber (reg:CC FLAGS_REG))]
13698   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13699   "@
13700    shr{l}\t{%2, %k0|%k0, %2}
13701    shr{l}\t{%b2, %k0|%k0, %b2}"
13702   [(set_attr "type" "ishift")
13703    (set_attr "mode" "SI")])
13704
13705 ;; This pattern can't accept a variable shift count, since shifts by
13706 ;; zero don't affect the flags.  We assume that shifts by constant
13707 ;; zero are optimized away.
13708 (define_insn "*lshrsi3_one_bit_cmp"
13709   [(set (reg FLAGS_REG)
13710         (compare
13711           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13712                        (match_operand:QI 2 "const1_operand" ""))
13713           (const_int 0)))
13714    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13715         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13716   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13717    && ix86_match_ccmode (insn, CCGOCmode)
13718    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13719   "shr{l}\t%0"
13720   [(set_attr "type" "ishift")
13721    (set_attr "length_immediate" "0")
13722    (set_attr "mode" "SI")])
13723
13724 (define_insn "*lshrsi3_one_bit_cconly"
13725   [(set (reg FLAGS_REG)
13726         (compare
13727           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13728                        (match_operand:QI 2 "const1_operand" ""))
13729           (const_int 0)))
13730    (clobber (match_scratch:SI 0 "=r"))]
13731   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13732    && ix86_match_ccmode (insn, CCGOCmode)
13733    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13734   "shr{l}\t%0"
13735   [(set_attr "type" "ishift")
13736    (set_attr "length_immediate" "0")
13737    (set_attr "mode" "SI")])
13738
13739 (define_insn "*lshrsi3_cmp_one_bit_zext"
13740   [(set (reg FLAGS_REG)
13741         (compare
13742           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13743                        (match_operand:QI 2 "const1_operand" ""))
13744           (const_int 0)))
13745    (set (match_operand:DI 0 "register_operand" "=r")
13746         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13747   "TARGET_64BIT
13748    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13749    && ix86_match_ccmode (insn, CCGOCmode)
13750    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13751   "shr{l}\t%k0"
13752   [(set_attr "type" "ishift")
13753    (set_attr "length_immediate" "0")
13754    (set_attr "mode" "SI")])
13755
13756 ;; This pattern can't accept a variable shift count, since shifts by
13757 ;; zero don't affect the flags.  We assume that shifts by constant
13758 ;; zero are optimized away.
13759 (define_insn "*lshrsi3_cmp"
13760   [(set (reg FLAGS_REG)
13761         (compare
13762           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13763                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13764           (const_int 0)))
13765    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13766         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13767   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13768    && ix86_match_ccmode (insn, CCGOCmode)
13769    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13770   "shr{l}\t{%2, %0|%0, %2}"
13771   [(set_attr "type" "ishift")
13772    (set_attr "mode" "SI")])
13773
13774 (define_insn "*lshrsi3_cconly"
13775   [(set (reg FLAGS_REG)
13776       (compare
13777         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13778                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13779         (const_int 0)))
13780    (clobber (match_scratch:SI 0 "=r"))]
13781   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13782    && ix86_match_ccmode (insn, CCGOCmode)
13783    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13784   "shr{l}\t{%2, %0|%0, %2}"
13785   [(set_attr "type" "ishift")
13786    (set_attr "mode" "SI")])
13787
13788 (define_insn "*lshrsi3_cmp_zext"
13789   [(set (reg FLAGS_REG)
13790         (compare
13791           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13792                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13793           (const_int 0)))
13794    (set (match_operand:DI 0 "register_operand" "=r")
13795         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13796   "TARGET_64BIT
13797    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13798    && ix86_match_ccmode (insn, CCGOCmode)
13799    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13800   "shr{l}\t{%2, %k0|%k0, %2}"
13801   [(set_attr "type" "ishift")
13802    (set_attr "mode" "SI")])
13803
13804 (define_expand "lshrhi3"
13805   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13806         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13807                      (match_operand:QI 2 "nonmemory_operand" "")))]
13808   "TARGET_HIMODE_MATH"
13809   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13810
13811 (define_insn "*lshrhi3_1_one_bit"
13812   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13813         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13814                      (match_operand:QI 2 "const1_operand" "")))
13815    (clobber (reg:CC FLAGS_REG))]
13816   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13817    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13818   "shr{w}\t%0"
13819   [(set_attr "type" "ishift")
13820    (set_attr "length_immediate" "0")
13821    (set_attr "mode" "HI")])
13822
13823 (define_insn "*lshrhi3_1"
13824   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13825         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13826                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13827    (clobber (reg:CC FLAGS_REG))]
13828   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13829   "@
13830    shr{w}\t{%2, %0|%0, %2}
13831    shr{w}\t{%b2, %0|%0, %b2}"
13832   [(set_attr "type" "ishift")
13833    (set_attr "mode" "HI")])
13834
13835 ;; This pattern can't accept a variable shift count, since shifts by
13836 ;; zero don't affect the flags.  We assume that shifts by constant
13837 ;; zero are optimized away.
13838 (define_insn "*lshrhi3_one_bit_cmp"
13839   [(set (reg FLAGS_REG)
13840         (compare
13841           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13842                        (match_operand:QI 2 "const1_operand" ""))
13843           (const_int 0)))
13844    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13845         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13846   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13847    && ix86_match_ccmode (insn, CCGOCmode)
13848    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13849   "shr{w}\t%0"
13850   [(set_attr "type" "ishift")
13851    (set_attr "length_immediate" "0")
13852    (set_attr "mode" "HI")])
13853
13854 (define_insn "*lshrhi3_one_bit_cconly"
13855   [(set (reg FLAGS_REG)
13856         (compare
13857           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13858                        (match_operand:QI 2 "const1_operand" ""))
13859           (const_int 0)))
13860    (clobber (match_scratch:HI 0 "=r"))]
13861   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13862    && ix86_match_ccmode (insn, CCGOCmode)
13863    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13864   "shr{w}\t%0"
13865   [(set_attr "type" "ishift")
13866    (set_attr "length_immediate" "0")
13867    (set_attr "mode" "HI")])
13868
13869 ;; This pattern can't accept a variable shift count, since shifts by
13870 ;; zero don't affect the flags.  We assume that shifts by constant
13871 ;; zero are optimized away.
13872 (define_insn "*lshrhi3_cmp"
13873   [(set (reg FLAGS_REG)
13874         (compare
13875           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13876                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13877           (const_int 0)))
13878    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13879         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13880   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13881    && ix86_match_ccmode (insn, CCGOCmode)
13882    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13883   "shr{w}\t{%2, %0|%0, %2}"
13884   [(set_attr "type" "ishift")
13885    (set_attr "mode" "HI")])
13886
13887 (define_insn "*lshrhi3_cconly"
13888   [(set (reg FLAGS_REG)
13889         (compare
13890           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13891                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13892           (const_int 0)))
13893    (clobber (match_scratch:HI 0 "=r"))]
13894   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13895    && ix86_match_ccmode (insn, CCGOCmode)
13896    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13897   "shr{w}\t{%2, %0|%0, %2}"
13898   [(set_attr "type" "ishift")
13899    (set_attr "mode" "HI")])
13900
13901 (define_expand "lshrqi3"
13902   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13903         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13904                      (match_operand:QI 2 "nonmemory_operand" "")))]
13905   "TARGET_QIMODE_MATH"
13906   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13907
13908 (define_insn "*lshrqi3_1_one_bit"
13909   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13910         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13911                      (match_operand:QI 2 "const1_operand" "")))
13912    (clobber (reg:CC FLAGS_REG))]
13913   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13914    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13915   "shr{b}\t%0"
13916   [(set_attr "type" "ishift")
13917    (set_attr "length_immediate" "0")
13918    (set_attr "mode" "QI")])
13919
13920 (define_insn "*lshrqi3_1_one_bit_slp"
13921   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13922         (lshiftrt:QI (match_dup 0)
13923                      (match_operand:QI 1 "const1_operand" "")))
13924    (clobber (reg:CC FLAGS_REG))]
13925   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13926    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13927   "shr{b}\t%0"
13928   [(set_attr "type" "ishift1")
13929    (set_attr "length_immediate" "0")
13930    (set_attr "mode" "QI")])
13931
13932 (define_insn "*lshrqi3_1"
13933   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13934         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13935                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13936    (clobber (reg:CC FLAGS_REG))]
13937   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13938   "@
13939    shr{b}\t{%2, %0|%0, %2}
13940    shr{b}\t{%b2, %0|%0, %b2}"
13941   [(set_attr "type" "ishift")
13942    (set_attr "mode" "QI")])
13943
13944 (define_insn "*lshrqi3_1_slp"
13945   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13946         (lshiftrt:QI (match_dup 0)
13947                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13948    (clobber (reg:CC FLAGS_REG))]
13949   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13950    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13951   "@
13952    shr{b}\t{%1, %0|%0, %1}
13953    shr{b}\t{%b1, %0|%0, %b1}"
13954   [(set_attr "type" "ishift1")
13955    (set_attr "mode" "QI")])
13956
13957 ;; This pattern can't accept a variable shift count, since shifts by
13958 ;; zero don't affect the flags.  We assume that shifts by constant
13959 ;; zero are optimized away.
13960 (define_insn "*lshrqi2_one_bit_cmp"
13961   [(set (reg FLAGS_REG)
13962         (compare
13963           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13964                        (match_operand:QI 2 "const1_operand" ""))
13965           (const_int 0)))
13966    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13967         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13968   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13969    && ix86_match_ccmode (insn, CCGOCmode)
13970    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13971   "shr{b}\t%0"
13972   [(set_attr "type" "ishift")
13973    (set_attr "length_immediate" "0")
13974    (set_attr "mode" "QI")])
13975
13976 (define_insn "*lshrqi2_one_bit_cconly"
13977   [(set (reg FLAGS_REG)
13978         (compare
13979           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13980                        (match_operand:QI 2 "const1_operand" ""))
13981           (const_int 0)))
13982    (clobber (match_scratch:QI 0 "=q"))]
13983   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13984    && ix86_match_ccmode (insn, CCGOCmode)
13985    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13986   "shr{b}\t%0"
13987   [(set_attr "type" "ishift")
13988    (set_attr "length_immediate" "0")
13989    (set_attr "mode" "QI")])
13990
13991 ;; This pattern can't accept a variable shift count, since shifts by
13992 ;; zero don't affect the flags.  We assume that shifts by constant
13993 ;; zero are optimized away.
13994 (define_insn "*lshrqi2_cmp"
13995   [(set (reg FLAGS_REG)
13996         (compare
13997           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13998                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13999           (const_int 0)))
14000    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14001         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
14002   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14003    && ix86_match_ccmode (insn, CCGOCmode)
14004    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14005   "shr{b}\t{%2, %0|%0, %2}"
14006   [(set_attr "type" "ishift")
14007    (set_attr "mode" "QI")])
14008
14009 (define_insn "*lshrqi2_cconly"
14010   [(set (reg FLAGS_REG)
14011         (compare
14012           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14013                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
14014           (const_int 0)))
14015    (clobber (match_scratch:QI 0 "=q"))]
14016   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14017    && ix86_match_ccmode (insn, CCGOCmode)
14018    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14019   "shr{b}\t{%2, %0|%0, %2}"
14020   [(set_attr "type" "ishift")
14021    (set_attr "mode" "QI")])
14022 \f
14023 ;; Rotate instructions
14024
14025 (define_expand "rotldi3"
14026   [(set (match_operand:DI 0 "shiftdi_operand" "")
14027         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14028                    (match_operand:QI 2 "nonmemory_operand" "")))]
14029  ""
14030 {
14031   if (TARGET_64BIT)
14032     {
14033       ix86_expand_binary_operator (ROTATE, DImode, operands);
14034       DONE;
14035     }
14036   if (!const_1_to_31_operand (operands[2], VOIDmode))
14037     FAIL;
14038   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
14039   DONE;
14040 })
14041
14042 ;; Implement rotation using two double-precision shift instructions
14043 ;; and a scratch register.
14044 (define_insn_and_split "ix86_rotldi3"
14045  [(set (match_operand:DI 0 "register_operand" "=r")
14046        (rotate:DI (match_operand:DI 1 "register_operand" "0")
14047                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
14048   (clobber (reg:CC FLAGS_REG))
14049   (clobber (match_scratch:SI 3 "=&r"))]
14050  "!TARGET_64BIT"
14051  ""
14052  "&& reload_completed"
14053  [(set (match_dup 3) (match_dup 4))
14054   (parallel
14055    [(set (match_dup 4)
14056          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
14057                  (lshiftrt:SI (match_dup 5)
14058                               (minus:QI (const_int 32) (match_dup 2)))))
14059     (clobber (reg:CC FLAGS_REG))])
14060   (parallel
14061    [(set (match_dup 5)
14062          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
14063                  (lshiftrt:SI (match_dup 3)
14064                               (minus:QI (const_int 32) (match_dup 2)))))
14065     (clobber (reg:CC FLAGS_REG))])]
14066  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14067
14068 (define_insn "*rotlsi3_1_one_bit_rex64"
14069   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14070         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14071                    (match_operand:QI 2 "const1_operand" "")))
14072    (clobber (reg:CC FLAGS_REG))]
14073   "TARGET_64BIT
14074    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14075    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14076   "rol{q}\t%0"
14077   [(set_attr "type" "rotate")
14078    (set_attr "length_immediate" "0")
14079    (set_attr "mode" "DI")])
14080
14081 (define_insn "*rotldi3_1_rex64"
14082   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14083         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14084                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
14085    (clobber (reg:CC FLAGS_REG))]
14086   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14087   "@
14088    rol{q}\t{%2, %0|%0, %2}
14089    rol{q}\t{%b2, %0|%0, %b2}"
14090   [(set_attr "type" "rotate")
14091    (set_attr "mode" "DI")])
14092
14093 (define_expand "rotlsi3"
14094   [(set (match_operand:SI 0 "nonimmediate_operand" "")
14095         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
14096                    (match_operand:QI 2 "nonmemory_operand" "")))]
14097   ""
14098   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
14099
14100 (define_insn "*rotlsi3_1_one_bit"
14101   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14102         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14103                    (match_operand:QI 2 "const1_operand" "")))
14104    (clobber (reg:CC FLAGS_REG))]
14105   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14106    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14107   "rol{l}\t%0"
14108   [(set_attr "type" "rotate")
14109    (set_attr "length_immediate" "0")
14110    (set_attr "mode" "SI")])
14111
14112 (define_insn "*rotlsi3_1_one_bit_zext"
14113   [(set (match_operand:DI 0 "register_operand" "=r")
14114         (zero_extend:DI
14115           (rotate:SI (match_operand:SI 1 "register_operand" "0")
14116                      (match_operand:QI 2 "const1_operand" ""))))
14117    (clobber (reg:CC FLAGS_REG))]
14118   "TARGET_64BIT
14119    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14120    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14121   "rol{l}\t%k0"
14122   [(set_attr "type" "rotate")
14123    (set_attr "length_immediate" "0")
14124    (set_attr "mode" "SI")])
14125
14126 (define_insn "*rotlsi3_1"
14127   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14128         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14129                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14130    (clobber (reg:CC FLAGS_REG))]
14131   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
14132   "@
14133    rol{l}\t{%2, %0|%0, %2}
14134    rol{l}\t{%b2, %0|%0, %b2}"
14135   [(set_attr "type" "rotate")
14136    (set_attr "mode" "SI")])
14137
14138 (define_insn "*rotlsi3_1_zext"
14139   [(set (match_operand:DI 0 "register_operand" "=r,r")
14140         (zero_extend:DI
14141           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
14142                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14143    (clobber (reg:CC FLAGS_REG))]
14144   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14145   "@
14146    rol{l}\t{%2, %k0|%k0, %2}
14147    rol{l}\t{%b2, %k0|%k0, %b2}"
14148   [(set_attr "type" "rotate")
14149    (set_attr "mode" "SI")])
14150
14151 (define_expand "rotlhi3"
14152   [(set (match_operand:HI 0 "nonimmediate_operand" "")
14153         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
14154                    (match_operand:QI 2 "nonmemory_operand" "")))]
14155   "TARGET_HIMODE_MATH"
14156   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
14157
14158 (define_insn "*rotlhi3_1_one_bit"
14159   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14160         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14161                    (match_operand:QI 2 "const1_operand" "")))
14162    (clobber (reg:CC FLAGS_REG))]
14163   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14164    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
14165   "rol{w}\t%0"
14166   [(set_attr "type" "rotate")
14167    (set_attr "length_immediate" "0")
14168    (set_attr "mode" "HI")])
14169
14170 (define_insn "*rotlhi3_1"
14171   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14172         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14173                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14174    (clobber (reg:CC FLAGS_REG))]
14175   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
14176   "@
14177    rol{w}\t{%2, %0|%0, %2}
14178    rol{w}\t{%b2, %0|%0, %b2}"
14179   [(set_attr "type" "rotate")
14180    (set_attr "mode" "HI")])
14181
14182 (define_split
14183  [(set (match_operand:HI 0 "register_operand" "")
14184        (rotate:HI (match_dup 0) (const_int 8)))
14185   (clobber (reg:CC FLAGS_REG))]
14186  "reload_completed"
14187  [(parallel [(set (strict_low_part (match_dup 0))
14188                   (bswap:HI (match_dup 0)))
14189              (clobber (reg:CC FLAGS_REG))])]
14190  "")
14191
14192 (define_expand "rotlqi3"
14193   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14194         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
14195                    (match_operand:QI 2 "nonmemory_operand" "")))]
14196   "TARGET_QIMODE_MATH"
14197   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
14198
14199 (define_insn "*rotlqi3_1_one_bit_slp"
14200   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14201         (rotate:QI (match_dup 0)
14202                    (match_operand:QI 1 "const1_operand" "")))
14203    (clobber (reg:CC FLAGS_REG))]
14204   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14205    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14206   "rol{b}\t%0"
14207   [(set_attr "type" "rotate1")
14208    (set_attr "length_immediate" "0")
14209    (set_attr "mode" "QI")])
14210
14211 (define_insn "*rotlqi3_1_one_bit"
14212   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14213         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14214                    (match_operand:QI 2 "const1_operand" "")))
14215    (clobber (reg:CC FLAGS_REG))]
14216   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14217    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
14218   "rol{b}\t%0"
14219   [(set_attr "type" "rotate")
14220    (set_attr "length_immediate" "0")
14221    (set_attr "mode" "QI")])
14222
14223 (define_insn "*rotlqi3_1_slp"
14224   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14225         (rotate:QI (match_dup 0)
14226                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
14227    (clobber (reg:CC FLAGS_REG))]
14228   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14229    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14230   "@
14231    rol{b}\t{%1, %0|%0, %1}
14232    rol{b}\t{%b1, %0|%0, %b1}"
14233   [(set_attr "type" "rotate1")
14234    (set_attr "mode" "QI")])
14235
14236 (define_insn "*rotlqi3_1"
14237   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14238         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14239                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14240    (clobber (reg:CC FLAGS_REG))]
14241   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
14242   "@
14243    rol{b}\t{%2, %0|%0, %2}
14244    rol{b}\t{%b2, %0|%0, %b2}"
14245   [(set_attr "type" "rotate")
14246    (set_attr "mode" "QI")])
14247
14248 (define_expand "rotrdi3"
14249   [(set (match_operand:DI 0 "shiftdi_operand" "")
14250         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14251                    (match_operand:QI 2 "nonmemory_operand" "")))]
14252  ""
14253 {
14254   if (TARGET_64BIT)
14255     {
14256       ix86_expand_binary_operator (ROTATERT, DImode, operands);
14257       DONE;
14258     }
14259   if (!const_1_to_31_operand (operands[2], VOIDmode))
14260     FAIL;
14261   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
14262   DONE;
14263 })
14264
14265 ;; Implement rotation using two double-precision shift instructions
14266 ;; and a scratch register.
14267 (define_insn_and_split "ix86_rotrdi3"
14268  [(set (match_operand:DI 0 "register_operand" "=r")
14269        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
14270                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
14271   (clobber (reg:CC FLAGS_REG))
14272   (clobber (match_scratch:SI 3 "=&r"))]
14273  "!TARGET_64BIT"
14274  ""
14275  "&& reload_completed"
14276  [(set (match_dup 3) (match_dup 4))
14277   (parallel
14278    [(set (match_dup 4)
14279          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
14280                  (ashift:SI (match_dup 5)
14281                             (minus:QI (const_int 32) (match_dup 2)))))
14282     (clobber (reg:CC FLAGS_REG))])
14283   (parallel
14284    [(set (match_dup 5)
14285          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
14286                  (ashift:SI (match_dup 3)
14287                             (minus:QI (const_int 32) (match_dup 2)))))
14288     (clobber (reg:CC FLAGS_REG))])]
14289  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14290
14291 (define_insn "*rotrdi3_1_one_bit_rex64"
14292   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14293         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14294                      (match_operand:QI 2 "const1_operand" "")))
14295    (clobber (reg:CC FLAGS_REG))]
14296   "TARGET_64BIT
14297    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14298    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14299   "ror{q}\t%0"
14300   [(set_attr "type" "rotate")
14301    (set_attr "length_immediate" "0")
14302    (set_attr "mode" "DI")])
14303
14304 (define_insn "*rotrdi3_1_rex64"
14305   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14306         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14307                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
14308    (clobber (reg:CC FLAGS_REG))]
14309   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14310   "@
14311    ror{q}\t{%2, %0|%0, %2}
14312    ror{q}\t{%b2, %0|%0, %b2}"
14313   [(set_attr "type" "rotate")
14314    (set_attr "mode" "DI")])
14315
14316 (define_expand "rotrsi3"
14317   [(set (match_operand:SI 0 "nonimmediate_operand" "")
14318         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
14319                      (match_operand:QI 2 "nonmemory_operand" "")))]
14320   ""
14321   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
14322
14323 (define_insn "*rotrsi3_1_one_bit"
14324   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14325         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14326                      (match_operand:QI 2 "const1_operand" "")))
14327    (clobber (reg:CC FLAGS_REG))]
14328   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14329    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14330   "ror{l}\t%0"
14331   [(set_attr "type" "rotate")
14332    (set_attr "length_immediate" "0")
14333    (set_attr "mode" "SI")])
14334
14335 (define_insn "*rotrsi3_1_one_bit_zext"
14336   [(set (match_operand:DI 0 "register_operand" "=r")
14337         (zero_extend:DI
14338           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
14339                        (match_operand:QI 2 "const1_operand" ""))))
14340    (clobber (reg:CC FLAGS_REG))]
14341   "TARGET_64BIT
14342    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14343    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14344   "ror{l}\t%k0"
14345   [(set_attr "type" "rotate")
14346    (set_attr "length_immediate" "0")
14347    (set_attr "mode" "SI")])
14348
14349 (define_insn "*rotrsi3_1"
14350   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14351         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14352                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14353    (clobber (reg:CC FLAGS_REG))]
14354   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14355   "@
14356    ror{l}\t{%2, %0|%0, %2}
14357    ror{l}\t{%b2, %0|%0, %b2}"
14358   [(set_attr "type" "rotate")
14359    (set_attr "mode" "SI")])
14360
14361 (define_insn "*rotrsi3_1_zext"
14362   [(set (match_operand:DI 0 "register_operand" "=r,r")
14363         (zero_extend:DI
14364           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
14365                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14366    (clobber (reg:CC FLAGS_REG))]
14367   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14368   "@
14369    ror{l}\t{%2, %k0|%k0, %2}
14370    ror{l}\t{%b2, %k0|%k0, %b2}"
14371   [(set_attr "type" "rotate")
14372    (set_attr "mode" "SI")])
14373
14374 (define_expand "rotrhi3"
14375   [(set (match_operand:HI 0 "nonimmediate_operand" "")
14376         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
14377                      (match_operand:QI 2 "nonmemory_operand" "")))]
14378   "TARGET_HIMODE_MATH"
14379   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
14380
14381 (define_insn "*rotrhi3_one_bit"
14382   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14383         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14384                      (match_operand:QI 2 "const1_operand" "")))
14385    (clobber (reg:CC FLAGS_REG))]
14386   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14387    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14388   "ror{w}\t%0"
14389   [(set_attr "type" "rotate")
14390    (set_attr "length_immediate" "0")
14391    (set_attr "mode" "HI")])
14392
14393 (define_insn "*rotrhi3_1"
14394   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14395         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14396                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14397    (clobber (reg:CC FLAGS_REG))]
14398   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14399   "@
14400    ror{w}\t{%2, %0|%0, %2}
14401    ror{w}\t{%b2, %0|%0, %b2}"
14402   [(set_attr "type" "rotate")
14403    (set_attr "mode" "HI")])
14404
14405 (define_split
14406  [(set (match_operand:HI 0 "register_operand" "")
14407        (rotatert:HI (match_dup 0) (const_int 8)))
14408   (clobber (reg:CC FLAGS_REG))]
14409  "reload_completed"
14410  [(parallel [(set (strict_low_part (match_dup 0))
14411                   (bswap:HI (match_dup 0)))
14412              (clobber (reg:CC FLAGS_REG))])]
14413  "")
14414
14415 (define_expand "rotrqi3"
14416   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14417         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
14418                      (match_operand:QI 2 "nonmemory_operand" "")))]
14419   "TARGET_QIMODE_MATH"
14420   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
14421
14422 (define_insn "*rotrqi3_1_one_bit"
14423   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14424         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14425                      (match_operand:QI 2 "const1_operand" "")))
14426    (clobber (reg:CC FLAGS_REG))]
14427   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14428    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14429   "ror{b}\t%0"
14430   [(set_attr "type" "rotate")
14431    (set_attr "length_immediate" "0")
14432    (set_attr "mode" "QI")])
14433
14434 (define_insn "*rotrqi3_1_one_bit_slp"
14435   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14436         (rotatert:QI (match_dup 0)
14437                      (match_operand:QI 1 "const1_operand" "")))
14438    (clobber (reg:CC FLAGS_REG))]
14439   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14440    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14441   "ror{b}\t%0"
14442   [(set_attr "type" "rotate1")
14443    (set_attr "length_immediate" "0")
14444    (set_attr "mode" "QI")])
14445
14446 (define_insn "*rotrqi3_1"
14447   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14448         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14449                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14450    (clobber (reg:CC FLAGS_REG))]
14451   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14452   "@
14453    ror{b}\t{%2, %0|%0, %2}
14454    ror{b}\t{%b2, %0|%0, %b2}"
14455   [(set_attr "type" "rotate")
14456    (set_attr "mode" "QI")])
14457
14458 (define_insn "*rotrqi3_1_slp"
14459   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14460         (rotatert:QI (match_dup 0)
14461                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
14462    (clobber (reg:CC FLAGS_REG))]
14463   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14464    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14465   "@
14466    ror{b}\t{%1, %0|%0, %1}
14467    ror{b}\t{%b1, %0|%0, %b1}"
14468   [(set_attr "type" "rotate1")
14469    (set_attr "mode" "QI")])
14470 \f
14471 ;; Bit set / bit test instructions
14472
14473 (define_expand "extv"
14474   [(set (match_operand:SI 0 "register_operand" "")
14475         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
14476                          (match_operand:SI 2 "const8_operand" "")
14477                          (match_operand:SI 3 "const8_operand" "")))]
14478   ""
14479 {
14480   /* Handle extractions from %ah et al.  */
14481   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14482     FAIL;
14483
14484   /* From mips.md: extract_bit_field doesn't verify that our source
14485      matches the predicate, so check it again here.  */
14486   if (! ext_register_operand (operands[1], VOIDmode))
14487     FAIL;
14488 })
14489
14490 (define_expand "extzv"
14491   [(set (match_operand:SI 0 "register_operand" "")
14492         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
14493                          (match_operand:SI 2 "const8_operand" "")
14494                          (match_operand:SI 3 "const8_operand" "")))]
14495   ""
14496 {
14497   /* Handle extractions from %ah et al.  */
14498   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14499     FAIL;
14500
14501   /* From mips.md: extract_bit_field doesn't verify that our source
14502      matches the predicate, so check it again here.  */
14503   if (! ext_register_operand (operands[1], VOIDmode))
14504     FAIL;
14505 })
14506
14507 (define_expand "insv"
14508   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
14509                       (match_operand 1 "const8_operand" "")
14510                       (match_operand 2 "const8_operand" ""))
14511         (match_operand 3 "register_operand" ""))]
14512   ""
14513 {
14514   /* Handle insertions to %ah et al.  */
14515   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
14516     FAIL;
14517
14518   /* From mips.md: insert_bit_field doesn't verify that our source
14519      matches the predicate, so check it again here.  */
14520   if (! ext_register_operand (operands[0], VOIDmode))
14521     FAIL;
14522
14523   if (TARGET_64BIT)
14524     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14525   else
14526     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14527
14528   DONE;
14529 })
14530
14531 ;; %%% bts, btr, btc, bt.
14532 ;; In general these instructions are *slow* when applied to memory,
14533 ;; since they enforce atomic operation.  When applied to registers,
14534 ;; it depends on the cpu implementation.  They're never faster than
14535 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14536 ;; no point.  But in 64-bit, we can't hold the relevant immediates
14537 ;; within the instruction itself, so operating on bits in the high
14538 ;; 32-bits of a register becomes easier.
14539 ;;
14540 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
14541 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14542 ;; negdf respectively, so they can never be disabled entirely.
14543
14544 (define_insn "*btsq"
14545   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14546                          (const_int 1)
14547                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14548         (const_int 1))
14549    (clobber (reg:CC FLAGS_REG))]
14550   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14551   "bts{q}\t{%1, %0|%0, %1}"
14552   [(set_attr "type" "alu1")
14553    (set_attr "prefix_0f" "1")
14554    (set_attr "mode" "DI")])
14555
14556 (define_insn "*btrq"
14557   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14558                          (const_int 1)
14559                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14560         (const_int 0))
14561    (clobber (reg:CC FLAGS_REG))]
14562   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14563   "btr{q}\t{%1, %0|%0, %1}"
14564   [(set_attr "type" "alu1")
14565    (set_attr "prefix_0f" "1")
14566    (set_attr "mode" "DI")])
14567
14568 (define_insn "*btcq"
14569   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14570                          (const_int 1)
14571                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14572         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14573    (clobber (reg:CC FLAGS_REG))]
14574   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14575   "btc{q}\t{%1, %0|%0, %1}"
14576   [(set_attr "type" "alu1")
14577    (set_attr "prefix_0f" "1")
14578    (set_attr "mode" "DI")])
14579
14580 ;; Allow Nocona to avoid these instructions if a register is available.
14581
14582 (define_peephole2
14583   [(match_scratch:DI 2 "r")
14584    (parallel [(set (zero_extract:DI
14585                      (match_operand:DI 0 "register_operand" "")
14586                      (const_int 1)
14587                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14588                    (const_int 1))
14589               (clobber (reg:CC FLAGS_REG))])]
14590   "TARGET_64BIT && !TARGET_USE_BT"
14591   [(const_int 0)]
14592 {
14593   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14594   rtx op1;
14595
14596   if (HOST_BITS_PER_WIDE_INT >= 64)
14597     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14598   else if (i < HOST_BITS_PER_WIDE_INT)
14599     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14600   else
14601     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14602
14603   op1 = immed_double_const (lo, hi, DImode);
14604   if (i >= 31)
14605     {
14606       emit_move_insn (operands[2], op1);
14607       op1 = operands[2];
14608     }
14609
14610   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14611   DONE;
14612 })
14613
14614 (define_peephole2
14615   [(match_scratch:DI 2 "r")
14616    (parallel [(set (zero_extract:DI
14617                      (match_operand:DI 0 "register_operand" "")
14618                      (const_int 1)
14619                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14620                    (const_int 0))
14621               (clobber (reg:CC FLAGS_REG))])]
14622   "TARGET_64BIT && !TARGET_USE_BT"
14623   [(const_int 0)]
14624 {
14625   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14626   rtx op1;
14627
14628   if (HOST_BITS_PER_WIDE_INT >= 64)
14629     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14630   else if (i < HOST_BITS_PER_WIDE_INT)
14631     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14632   else
14633     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14634
14635   op1 = immed_double_const (~lo, ~hi, DImode);
14636   if (i >= 32)
14637     {
14638       emit_move_insn (operands[2], op1);
14639       op1 = operands[2];
14640     }
14641
14642   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14643   DONE;
14644 })
14645
14646 (define_peephole2
14647   [(match_scratch:DI 2 "r")
14648    (parallel [(set (zero_extract:DI
14649                      (match_operand:DI 0 "register_operand" "")
14650                      (const_int 1)
14651                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14652               (not:DI (zero_extract:DI
14653                         (match_dup 0) (const_int 1) (match_dup 1))))
14654               (clobber (reg:CC FLAGS_REG))])]
14655   "TARGET_64BIT && !TARGET_USE_BT"
14656   [(const_int 0)]
14657 {
14658   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14659   rtx op1;
14660
14661   if (HOST_BITS_PER_WIDE_INT >= 64)
14662     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14663   else if (i < HOST_BITS_PER_WIDE_INT)
14664     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14665   else
14666     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14667
14668   op1 = immed_double_const (lo, hi, DImode);
14669   if (i >= 31)
14670     {
14671       emit_move_insn (operands[2], op1);
14672       op1 = operands[2];
14673     }
14674
14675   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14676   DONE;
14677 })
14678
14679 (define_insn "*btdi_rex64"
14680   [(set (reg:CCC FLAGS_REG)
14681         (compare:CCC
14682           (zero_extract:DI
14683             (match_operand:DI 0 "register_operand" "r")
14684             (const_int 1)
14685             (match_operand:DI 1 "nonmemory_operand" "rN"))
14686           (const_int 0)))]
14687   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14688   "bt{q}\t{%1, %0|%0, %1}"
14689   [(set_attr "type" "alu1")
14690    (set_attr "prefix_0f" "1")
14691    (set_attr "mode" "DI")])
14692
14693 (define_insn "*btsi"
14694   [(set (reg:CCC FLAGS_REG)
14695         (compare:CCC
14696           (zero_extract:SI
14697             (match_operand:SI 0 "register_operand" "r")
14698             (const_int 1)
14699             (match_operand:SI 1 "nonmemory_operand" "rN"))
14700           (const_int 0)))]
14701   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14702   "bt{l}\t{%1, %0|%0, %1}"
14703   [(set_attr "type" "alu1")
14704    (set_attr "prefix_0f" "1")
14705    (set_attr "mode" "SI")])
14706 \f
14707 ;; Store-flag instructions.
14708
14709 ;; For all sCOND expanders, also expand the compare or test insn that
14710 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14711
14712 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14713 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14714 ;; way, which can later delete the movzx if only QImode is needed.
14715
14716 (define_insn "*setcc_1"
14717   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14718         (match_operator:QI 1 "ix86_comparison_operator"
14719           [(reg FLAGS_REG) (const_int 0)]))]
14720   ""
14721   "set%C1\t%0"
14722   [(set_attr "type" "setcc")
14723    (set_attr "mode" "QI")])
14724
14725 (define_insn "*setcc_2"
14726   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14727         (match_operator:QI 1 "ix86_comparison_operator"
14728           [(reg FLAGS_REG) (const_int 0)]))]
14729   ""
14730   "set%C1\t%0"
14731   [(set_attr "type" "setcc")
14732    (set_attr "mode" "QI")])
14733
14734 ;; In general it is not safe to assume too much about CCmode registers,
14735 ;; so simplify-rtx stops when it sees a second one.  Under certain
14736 ;; conditions this is safe on x86, so help combine not create
14737 ;;
14738 ;;      seta    %al
14739 ;;      testb   %al, %al
14740 ;;      sete    %al
14741
14742 (define_split
14743   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14744         (ne:QI (match_operator 1 "ix86_comparison_operator"
14745                  [(reg FLAGS_REG) (const_int 0)])
14746             (const_int 0)))]
14747   ""
14748   [(set (match_dup 0) (match_dup 1))]
14749 {
14750   PUT_MODE (operands[1], QImode);
14751 })
14752
14753 (define_split
14754   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14755         (ne:QI (match_operator 1 "ix86_comparison_operator"
14756                  [(reg FLAGS_REG) (const_int 0)])
14757             (const_int 0)))]
14758   ""
14759   [(set (match_dup 0) (match_dup 1))]
14760 {
14761   PUT_MODE (operands[1], QImode);
14762 })
14763
14764 (define_split
14765   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14766         (eq:QI (match_operator 1 "ix86_comparison_operator"
14767                  [(reg FLAGS_REG) (const_int 0)])
14768             (const_int 0)))]
14769   ""
14770   [(set (match_dup 0) (match_dup 1))]
14771 {
14772   rtx new_op1 = copy_rtx (operands[1]);
14773   operands[1] = new_op1;
14774   PUT_MODE (new_op1, QImode);
14775   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14776                                              GET_MODE (XEXP (new_op1, 0))));
14777
14778   /* Make sure that (a) the CCmode we have for the flags is strong
14779      enough for the reversed compare or (b) we have a valid FP compare.  */
14780   if (! ix86_comparison_operator (new_op1, VOIDmode))
14781     FAIL;
14782 })
14783
14784 (define_split
14785   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14786         (eq:QI (match_operator 1 "ix86_comparison_operator"
14787                  [(reg FLAGS_REG) (const_int 0)])
14788             (const_int 0)))]
14789   ""
14790   [(set (match_dup 0) (match_dup 1))]
14791 {
14792   rtx new_op1 = copy_rtx (operands[1]);
14793   operands[1] = new_op1;
14794   PUT_MODE (new_op1, QImode);
14795   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14796                                              GET_MODE (XEXP (new_op1, 0))));
14797
14798   /* Make sure that (a) the CCmode we have for the flags is strong
14799      enough for the reversed compare or (b) we have a valid FP compare.  */
14800   if (! ix86_comparison_operator (new_op1, VOIDmode))
14801     FAIL;
14802 })
14803
14804 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14805 ;; subsequent logical operations are used to imitate conditional moves.
14806 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14807 ;; it directly.
14808
14809 (define_insn "*avx_setcc<mode>"
14810   [(set (match_operand:MODEF 0 "register_operand" "=x")
14811         (match_operator:MODEF 1 "avx_comparison_float_operator"
14812           [(match_operand:MODEF 2 "register_operand" "x")
14813            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14814   "TARGET_AVX"
14815   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14816   [(set_attr "type" "ssecmp")
14817    (set_attr "prefix" "vex")
14818    (set_attr "length_immediate" "1")
14819    (set_attr "mode" "<MODE>")])
14820
14821 (define_insn "*sse_setcc<mode>"
14822   [(set (match_operand:MODEF 0 "register_operand" "=x")
14823         (match_operator:MODEF 1 "sse_comparison_operator"
14824           [(match_operand:MODEF 2 "register_operand" "0")
14825            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14826   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14827   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14828   [(set_attr "type" "ssecmp")
14829    (set_attr "length_immediate" "1")
14830    (set_attr "mode" "<MODE>")])
14831
14832 (define_insn "*sse5_setcc<mode>"
14833   [(set (match_operand:MODEF 0 "register_operand" "=x")
14834         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14835           [(match_operand:MODEF 2 "register_operand" "x")
14836            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14837   "TARGET_SSE5"
14838   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14839   [(set_attr "type" "sse4arg")
14840    (set_attr "length_immediate" "1")
14841    (set_attr "mode" "<MODE>")])
14842
14843 \f
14844 ;; Basic conditional jump instructions.
14845 ;; We ignore the overflow flag for signed branch instructions.
14846
14847 (define_insn "*jcc_1"
14848   [(set (pc)
14849         (if_then_else (match_operator 1 "ix86_comparison_operator"
14850                                       [(reg FLAGS_REG) (const_int 0)])
14851                       (label_ref (match_operand 0 "" ""))
14852                       (pc)))]
14853   ""
14854   "%+j%C1\t%l0"
14855   [(set_attr "type" "ibr")
14856    (set_attr "modrm" "0")
14857    (set (attr "length")
14858            (if_then_else (and (ge (minus (match_dup 0) (pc))
14859                                   (const_int -126))
14860                               (lt (minus (match_dup 0) (pc))
14861                                   (const_int 128)))
14862              (const_int 2)
14863              (const_int 6)))])
14864
14865 (define_insn "*jcc_2"
14866   [(set (pc)
14867         (if_then_else (match_operator 1 "ix86_comparison_operator"
14868                                       [(reg FLAGS_REG) (const_int 0)])
14869                       (pc)
14870                       (label_ref (match_operand 0 "" ""))))]
14871   ""
14872   "%+j%c1\t%l0"
14873   [(set_attr "type" "ibr")
14874    (set_attr "modrm" "0")
14875    (set (attr "length")
14876            (if_then_else (and (ge (minus (match_dup 0) (pc))
14877                                   (const_int -126))
14878                               (lt (minus (match_dup 0) (pc))
14879                                   (const_int 128)))
14880              (const_int 2)
14881              (const_int 6)))])
14882
14883 ;; In general it is not safe to assume too much about CCmode registers,
14884 ;; so simplify-rtx stops when it sees a second one.  Under certain
14885 ;; conditions this is safe on x86, so help combine not create
14886 ;;
14887 ;;      seta    %al
14888 ;;      testb   %al, %al
14889 ;;      je      Lfoo
14890
14891 (define_split
14892   [(set (pc)
14893         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14894                                       [(reg FLAGS_REG) (const_int 0)])
14895                           (const_int 0))
14896                       (label_ref (match_operand 1 "" ""))
14897                       (pc)))]
14898   ""
14899   [(set (pc)
14900         (if_then_else (match_dup 0)
14901                       (label_ref (match_dup 1))
14902                       (pc)))]
14903 {
14904   PUT_MODE (operands[0], VOIDmode);
14905 })
14906
14907 (define_split
14908   [(set (pc)
14909         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14910                                       [(reg FLAGS_REG) (const_int 0)])
14911                           (const_int 0))
14912                       (label_ref (match_operand 1 "" ""))
14913                       (pc)))]
14914   ""
14915   [(set (pc)
14916         (if_then_else (match_dup 0)
14917                       (label_ref (match_dup 1))
14918                       (pc)))]
14919 {
14920   rtx new_op0 = copy_rtx (operands[0]);
14921   operands[0] = new_op0;
14922   PUT_MODE (new_op0, VOIDmode);
14923   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14924                                              GET_MODE (XEXP (new_op0, 0))));
14925
14926   /* Make sure that (a) the CCmode we have for the flags is strong
14927      enough for the reversed compare or (b) we have a valid FP compare.  */
14928   if (! ix86_comparison_operator (new_op0, VOIDmode))
14929     FAIL;
14930 })
14931
14932 ;; zero_extend in SImode is correct, since this is what combine pass
14933 ;; generates from shift insn with QImode operand.  Actually, the mode of
14934 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14935 ;; appropriate modulo of the bit offset value.
14936
14937 (define_insn_and_split "*jcc_btdi_rex64"
14938   [(set (pc)
14939         (if_then_else (match_operator 0 "bt_comparison_operator"
14940                         [(zero_extract:DI
14941                            (match_operand:DI 1 "register_operand" "r")
14942                            (const_int 1)
14943                            (zero_extend:SI
14944                              (match_operand:QI 2 "register_operand" "r")))
14945                          (const_int 0)])
14946                       (label_ref (match_operand 3 "" ""))
14947                       (pc)))
14948    (clobber (reg:CC FLAGS_REG))]
14949   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14950   "#"
14951   "&& 1"
14952   [(set (reg:CCC FLAGS_REG)
14953         (compare:CCC
14954           (zero_extract:DI
14955             (match_dup 1)
14956             (const_int 1)
14957             (match_dup 2))
14958           (const_int 0)))
14959    (set (pc)
14960         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14961                       (label_ref (match_dup 3))
14962                       (pc)))]
14963 {
14964   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14965
14966   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14967 })
14968
14969 ;; avoid useless masking of bit offset operand
14970 (define_insn_and_split "*jcc_btdi_mask_rex64"
14971   [(set (pc)
14972         (if_then_else (match_operator 0 "bt_comparison_operator"
14973                         [(zero_extract:DI
14974                            (match_operand:DI 1 "register_operand" "r")
14975                            (const_int 1)
14976                            (and:SI
14977                              (match_operand:SI 2 "register_operand" "r")
14978                              (match_operand:SI 3 "const_int_operand" "n")))])
14979                       (label_ref (match_operand 4 "" ""))
14980                       (pc)))
14981    (clobber (reg:CC FLAGS_REG))]
14982   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14983    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14984   "#"
14985   "&& 1"
14986   [(set (reg:CCC FLAGS_REG)
14987         (compare:CCC
14988           (zero_extract:DI
14989             (match_dup 1)
14990             (const_int 1)
14991             (match_dup 2))
14992           (const_int 0)))
14993    (set (pc)
14994         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14995                       (label_ref (match_dup 4))
14996                       (pc)))]
14997 {
14998   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14999
15000   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15001 })
15002
15003 (define_insn_and_split "*jcc_btsi"
15004   [(set (pc)
15005         (if_then_else (match_operator 0 "bt_comparison_operator"
15006                         [(zero_extract:SI
15007                            (match_operand:SI 1 "register_operand" "r")
15008                            (const_int 1)
15009                            (zero_extend:SI
15010                              (match_operand:QI 2 "register_operand" "r")))
15011                          (const_int 0)])
15012                       (label_ref (match_operand 3 "" ""))
15013                       (pc)))
15014    (clobber (reg:CC FLAGS_REG))]
15015   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15016   "#"
15017   "&& 1"
15018   [(set (reg:CCC FLAGS_REG)
15019         (compare:CCC
15020           (zero_extract:SI
15021             (match_dup 1)
15022             (const_int 1)
15023             (match_dup 2))
15024           (const_int 0)))
15025    (set (pc)
15026         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15027                       (label_ref (match_dup 3))
15028                       (pc)))]
15029 {
15030   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15031
15032   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15033 })
15034
15035 ;; avoid useless masking of bit offset operand
15036 (define_insn_and_split "*jcc_btsi_mask"
15037   [(set (pc)
15038         (if_then_else (match_operator 0 "bt_comparison_operator"
15039                         [(zero_extract:SI
15040                            (match_operand:SI 1 "register_operand" "r")
15041                            (const_int 1)
15042                            (and:SI
15043                              (match_operand:SI 2 "register_operand" "r")
15044                              (match_operand:SI 3 "const_int_operand" "n")))])
15045                       (label_ref (match_operand 4 "" ""))
15046                       (pc)))
15047    (clobber (reg:CC FLAGS_REG))]
15048   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15049    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15050   "#"
15051   "&& 1"
15052   [(set (reg:CCC FLAGS_REG)
15053         (compare:CCC
15054           (zero_extract:SI
15055             (match_dup 1)
15056             (const_int 1)
15057             (match_dup 2))
15058           (const_int 0)))
15059    (set (pc)
15060         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15061                       (label_ref (match_dup 4))
15062                       (pc)))]
15063   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15064
15065 (define_insn_and_split "*jcc_btsi_1"
15066   [(set (pc)
15067         (if_then_else (match_operator 0 "bt_comparison_operator"
15068                         [(and:SI
15069                            (lshiftrt:SI
15070                              (match_operand:SI 1 "register_operand" "r")
15071                              (match_operand:QI 2 "register_operand" "r"))
15072                            (const_int 1))
15073                          (const_int 0)])
15074                       (label_ref (match_operand 3 "" ""))
15075                       (pc)))
15076    (clobber (reg:CC FLAGS_REG))]
15077   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15078   "#"
15079   "&& 1"
15080   [(set (reg:CCC FLAGS_REG)
15081         (compare:CCC
15082           (zero_extract:SI
15083             (match_dup 1)
15084             (const_int 1)
15085             (match_dup 2))
15086           (const_int 0)))
15087    (set (pc)
15088         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15089                       (label_ref (match_dup 3))
15090                       (pc)))]
15091 {
15092   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15093
15094   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15095 })
15096
15097 ;; avoid useless masking of bit offset operand
15098 (define_insn_and_split "*jcc_btsi_mask_1"
15099   [(set (pc)
15100         (if_then_else
15101           (match_operator 0 "bt_comparison_operator"
15102             [(and:SI
15103                (lshiftrt:SI
15104                  (match_operand:SI 1 "register_operand" "r")
15105                  (subreg:QI
15106                    (and:SI
15107                      (match_operand:SI 2 "register_operand" "r")
15108                      (match_operand:SI 3 "const_int_operand" "n")) 0))
15109                (const_int 1))
15110              (const_int 0)])
15111           (label_ref (match_operand 4 "" ""))
15112           (pc)))
15113    (clobber (reg:CC FLAGS_REG))]
15114   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15115    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15116   "#"
15117   "&& 1"
15118   [(set (reg:CCC FLAGS_REG)
15119         (compare:CCC
15120           (zero_extract:SI
15121             (match_dup 1)
15122             (const_int 1)
15123             (match_dup 2))
15124           (const_int 0)))
15125    (set (pc)
15126         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15127                       (label_ref (match_dup 4))
15128                       (pc)))]
15129   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15130
15131 ;; Define combination compare-and-branch fp compare instructions to use
15132 ;; during early optimization.  Splitting the operation apart early makes
15133 ;; for bad code when we want to reverse the operation.
15134
15135 (define_insn "*fp_jcc_1_mixed"
15136   [(set (pc)
15137         (if_then_else (match_operator 0 "comparison_operator"
15138                         [(match_operand 1 "register_operand" "f,x")
15139                          (match_operand 2 "nonimmediate_operand" "f,xm")])
15140           (label_ref (match_operand 3 "" ""))
15141           (pc)))
15142    (clobber (reg:CCFP FPSR_REG))
15143    (clobber (reg:CCFP FLAGS_REG))]
15144   "TARGET_MIX_SSE_I387
15145    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15146    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15147    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15148   "#")
15149
15150 (define_insn "*fp_jcc_1_sse"
15151   [(set (pc)
15152         (if_then_else (match_operator 0 "comparison_operator"
15153                         [(match_operand 1 "register_operand" "x")
15154                          (match_operand 2 "nonimmediate_operand" "xm")])
15155           (label_ref (match_operand 3 "" ""))
15156           (pc)))
15157    (clobber (reg:CCFP FPSR_REG))
15158    (clobber (reg:CCFP FLAGS_REG))]
15159   "TARGET_SSE_MATH
15160    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15161    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15162    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15163   "#")
15164
15165 (define_insn "*fp_jcc_1_387"
15166   [(set (pc)
15167         (if_then_else (match_operator 0 "comparison_operator"
15168                         [(match_operand 1 "register_operand" "f")
15169                          (match_operand 2 "register_operand" "f")])
15170           (label_ref (match_operand 3 "" ""))
15171           (pc)))
15172    (clobber (reg:CCFP FPSR_REG))
15173    (clobber (reg:CCFP FLAGS_REG))]
15174   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15175    && TARGET_CMOVE
15176    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15177    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15178   "#")
15179
15180 (define_insn "*fp_jcc_2_mixed"
15181   [(set (pc)
15182         (if_then_else (match_operator 0 "comparison_operator"
15183                         [(match_operand 1 "register_operand" "f,x")
15184                          (match_operand 2 "nonimmediate_operand" "f,xm")])
15185           (pc)
15186           (label_ref (match_operand 3 "" ""))))
15187    (clobber (reg:CCFP FPSR_REG))
15188    (clobber (reg:CCFP FLAGS_REG))]
15189   "TARGET_MIX_SSE_I387
15190    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15191    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15192    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15193   "#")
15194
15195 (define_insn "*fp_jcc_2_sse"
15196   [(set (pc)
15197         (if_then_else (match_operator 0 "comparison_operator"
15198                         [(match_operand 1 "register_operand" "x")
15199                          (match_operand 2 "nonimmediate_operand" "xm")])
15200           (pc)
15201           (label_ref (match_operand 3 "" ""))))
15202    (clobber (reg:CCFP FPSR_REG))
15203    (clobber (reg:CCFP FLAGS_REG))]
15204   "TARGET_SSE_MATH
15205    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15206    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15207    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15208   "#")
15209
15210 (define_insn "*fp_jcc_2_387"
15211   [(set (pc)
15212         (if_then_else (match_operator 0 "comparison_operator"
15213                         [(match_operand 1 "register_operand" "f")
15214                          (match_operand 2 "register_operand" "f")])
15215           (pc)
15216           (label_ref (match_operand 3 "" ""))))
15217    (clobber (reg:CCFP FPSR_REG))
15218    (clobber (reg:CCFP FLAGS_REG))]
15219   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15220    && TARGET_CMOVE
15221    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15222    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15223   "#")
15224
15225 (define_insn "*fp_jcc_3_387"
15226   [(set (pc)
15227         (if_then_else (match_operator 0 "comparison_operator"
15228                         [(match_operand 1 "register_operand" "f")
15229                          (match_operand 2 "nonimmediate_operand" "fm")])
15230           (label_ref (match_operand 3 "" ""))
15231           (pc)))
15232    (clobber (reg:CCFP FPSR_REG))
15233    (clobber (reg:CCFP FLAGS_REG))
15234    (clobber (match_scratch:HI 4 "=a"))]
15235   "TARGET_80387
15236    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15237    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15238    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15239    && SELECT_CC_MODE (GET_CODE (operands[0]),
15240                       operands[1], operands[2]) == CCFPmode
15241    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15242   "#")
15243
15244 (define_insn "*fp_jcc_4_387"
15245   [(set (pc)
15246         (if_then_else (match_operator 0 "comparison_operator"
15247                         [(match_operand 1 "register_operand" "f")
15248                          (match_operand 2 "nonimmediate_operand" "fm")])
15249           (pc)
15250           (label_ref (match_operand 3 "" ""))))
15251    (clobber (reg:CCFP FPSR_REG))
15252    (clobber (reg:CCFP FLAGS_REG))
15253    (clobber (match_scratch:HI 4 "=a"))]
15254   "TARGET_80387
15255    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15256    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15257    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15258    && SELECT_CC_MODE (GET_CODE (operands[0]),
15259                       operands[1], operands[2]) == CCFPmode
15260    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15261   "#")
15262
15263 (define_insn "*fp_jcc_5_387"
15264   [(set (pc)
15265         (if_then_else (match_operator 0 "comparison_operator"
15266                         [(match_operand 1 "register_operand" "f")
15267                          (match_operand 2 "register_operand" "f")])
15268           (label_ref (match_operand 3 "" ""))
15269           (pc)))
15270    (clobber (reg:CCFP FPSR_REG))
15271    (clobber (reg:CCFP FLAGS_REG))
15272    (clobber (match_scratch:HI 4 "=a"))]
15273   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15274    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15275    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15276   "#")
15277
15278 (define_insn "*fp_jcc_6_387"
15279   [(set (pc)
15280         (if_then_else (match_operator 0 "comparison_operator"
15281                         [(match_operand 1 "register_operand" "f")
15282                          (match_operand 2 "register_operand" "f")])
15283           (pc)
15284           (label_ref (match_operand 3 "" ""))))
15285    (clobber (reg:CCFP FPSR_REG))
15286    (clobber (reg:CCFP FLAGS_REG))
15287    (clobber (match_scratch:HI 4 "=a"))]
15288   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15289    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15290    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15291   "#")
15292
15293 (define_insn "*fp_jcc_7_387"
15294   [(set (pc)
15295         (if_then_else (match_operator 0 "comparison_operator"
15296                         [(match_operand 1 "register_operand" "f")
15297                          (match_operand 2 "const0_operand" "")])
15298           (label_ref (match_operand 3 "" ""))
15299           (pc)))
15300    (clobber (reg:CCFP FPSR_REG))
15301    (clobber (reg:CCFP FLAGS_REG))
15302    (clobber (match_scratch:HI 4 "=a"))]
15303   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15304    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15305    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15306    && SELECT_CC_MODE (GET_CODE (operands[0]),
15307                       operands[1], operands[2]) == CCFPmode
15308    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15309   "#")
15310
15311 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
15312 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
15313 ;; with a precedence over other operators and is always put in the first
15314 ;; place. Swap condition and operands to match ficom instruction.
15315
15316 (define_insn "*fp_jcc_8<mode>_387"
15317   [(set (pc)
15318         (if_then_else (match_operator 0 "comparison_operator"
15319                         [(match_operator 1 "float_operator"
15320                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
15321                            (match_operand 3 "register_operand" "f,f")])
15322           (label_ref (match_operand 4 "" ""))
15323           (pc)))
15324    (clobber (reg:CCFP FPSR_REG))
15325    (clobber (reg:CCFP FLAGS_REG))
15326    (clobber (match_scratch:HI 5 "=a,a"))]
15327   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
15328    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
15329    && GET_MODE (operands[1]) == GET_MODE (operands[3])
15330    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
15331    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
15332    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
15333   "#")
15334
15335 (define_split
15336   [(set (pc)
15337         (if_then_else (match_operator 0 "comparison_operator"
15338                         [(match_operand 1 "register_operand" "")
15339                          (match_operand 2 "nonimmediate_operand" "")])
15340           (match_operand 3 "" "")
15341           (match_operand 4 "" "")))
15342    (clobber (reg:CCFP FPSR_REG))
15343    (clobber (reg:CCFP FLAGS_REG))]
15344   "reload_completed"
15345   [(const_int 0)]
15346 {
15347   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15348                         operands[3], operands[4], NULL_RTX, NULL_RTX);
15349   DONE;
15350 })
15351
15352 (define_split
15353   [(set (pc)
15354         (if_then_else (match_operator 0 "comparison_operator"
15355                         [(match_operand 1 "register_operand" "")
15356                          (match_operand 2 "general_operand" "")])
15357           (match_operand 3 "" "")
15358           (match_operand 4 "" "")))
15359    (clobber (reg:CCFP FPSR_REG))
15360    (clobber (reg:CCFP FLAGS_REG))
15361    (clobber (match_scratch:HI 5 "=a"))]
15362   "reload_completed"
15363   [(const_int 0)]
15364 {
15365   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15366                         operands[3], operands[4], operands[5], NULL_RTX);
15367   DONE;
15368 })
15369
15370 (define_split
15371   [(set (pc)
15372         (if_then_else (match_operator 0 "comparison_operator"
15373                         [(match_operator 1 "float_operator"
15374                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
15375                            (match_operand 3 "register_operand" "")])
15376           (match_operand 4 "" "")
15377           (match_operand 5 "" "")))
15378    (clobber (reg:CCFP FPSR_REG))
15379    (clobber (reg:CCFP FLAGS_REG))
15380    (clobber (match_scratch:HI 6 "=a"))]
15381   "reload_completed"
15382   [(const_int 0)]
15383 {
15384   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
15385   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15386                         operands[3], operands[7],
15387                         operands[4], operands[5], operands[6], NULL_RTX);
15388   DONE;
15389 })
15390
15391 ;; %%% Kill this when reload knows how to do it.
15392 (define_split
15393   [(set (pc)
15394         (if_then_else (match_operator 0 "comparison_operator"
15395                         [(match_operator 1 "float_operator"
15396                            [(match_operand:X87MODEI12 2 "register_operand" "")])
15397                            (match_operand 3 "register_operand" "")])
15398           (match_operand 4 "" "")
15399           (match_operand 5 "" "")))
15400    (clobber (reg:CCFP FPSR_REG))
15401    (clobber (reg:CCFP FLAGS_REG))
15402    (clobber (match_scratch:HI 6 "=a"))]
15403   "reload_completed"
15404   [(const_int 0)]
15405 {
15406   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15407   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
15408   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15409                         operands[3], operands[7],
15410                         operands[4], operands[5], operands[6], operands[2]);
15411   DONE;
15412 })
15413 \f
15414 ;; Unconditional and other jump instructions
15415
15416 (define_insn "jump"
15417   [(set (pc)
15418         (label_ref (match_operand 0 "" "")))]
15419   ""
15420   "jmp\t%l0"
15421   [(set_attr "type" "ibr")
15422    (set (attr "length")
15423            (if_then_else (and (ge (minus (match_dup 0) (pc))
15424                                   (const_int -126))
15425                               (lt (minus (match_dup 0) (pc))
15426                                   (const_int 128)))
15427              (const_int 2)
15428              (const_int 5)))
15429    (set_attr "modrm" "0")])
15430
15431 (define_expand "indirect_jump"
15432   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
15433   ""
15434   "")
15435
15436 (define_insn "*indirect_jump"
15437   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
15438   ""
15439   "jmp\t%A0"
15440   [(set_attr "type" "ibr")
15441    (set_attr "length_immediate" "0")])
15442
15443 (define_expand "tablejump"
15444   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
15445               (use (label_ref (match_operand 1 "" "")))])]
15446   ""
15447 {
15448   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
15449      relative.  Convert the relative address to an absolute address.  */
15450   if (flag_pic)
15451     {
15452       rtx op0, op1;
15453       enum rtx_code code;
15454
15455       /* We can't use @GOTOFF for text labels on VxWorks;
15456          see gotoff_operand.  */
15457       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
15458         {
15459           code = PLUS;
15460           op0 = operands[0];
15461           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
15462         }
15463       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
15464         {
15465           code = PLUS;
15466           op0 = operands[0];
15467           op1 = pic_offset_table_rtx;
15468         }
15469       else
15470         {
15471           code = MINUS;
15472           op0 = pic_offset_table_rtx;
15473           op1 = operands[0];
15474         }
15475
15476       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
15477                                          OPTAB_DIRECT);
15478     }
15479 })
15480
15481 (define_insn "*tablejump_1"
15482   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
15483    (use (label_ref (match_operand 1 "" "")))]
15484   ""
15485   "jmp\t%A0"
15486   [(set_attr "type" "ibr")
15487    (set_attr "length_immediate" "0")])
15488 \f
15489 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
15490
15491 (define_peephole2
15492   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15493    (set (match_operand:QI 1 "register_operand" "")
15494         (match_operator:QI 2 "ix86_comparison_operator"
15495           [(reg FLAGS_REG) (const_int 0)]))
15496    (set (match_operand 3 "q_regs_operand" "")
15497         (zero_extend (match_dup 1)))]
15498   "(peep2_reg_dead_p (3, operands[1])
15499     || operands_match_p (operands[1], operands[3]))
15500    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15501   [(set (match_dup 4) (match_dup 0))
15502    (set (strict_low_part (match_dup 5))
15503         (match_dup 2))]
15504 {
15505   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15506   operands[5] = gen_lowpart (QImode, operands[3]);
15507   ix86_expand_clear (operands[3]);
15508 })
15509
15510 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15511
15512 (define_peephole2
15513   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15514    (set (match_operand:QI 1 "register_operand" "")
15515         (match_operator:QI 2 "ix86_comparison_operator"
15516           [(reg FLAGS_REG) (const_int 0)]))
15517    (parallel [(set (match_operand 3 "q_regs_operand" "")
15518                    (zero_extend (match_dup 1)))
15519               (clobber (reg:CC FLAGS_REG))])]
15520   "(peep2_reg_dead_p (3, operands[1])
15521     || operands_match_p (operands[1], operands[3]))
15522    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15523   [(set (match_dup 4) (match_dup 0))
15524    (set (strict_low_part (match_dup 5))
15525         (match_dup 2))]
15526 {
15527   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15528   operands[5] = gen_lowpart (QImode, operands[3]);
15529   ix86_expand_clear (operands[3]);
15530 })
15531 \f
15532 ;; Call instructions.
15533
15534 ;; The predicates normally associated with named expanders are not properly
15535 ;; checked for calls.  This is a bug in the generic code, but it isn't that
15536 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
15537
15538 ;; Call subroutine returning no value.
15539
15540 (define_expand "call_pop"
15541   [(parallel [(call (match_operand:QI 0 "" "")
15542                     (match_operand:SI 1 "" ""))
15543               (set (reg:SI SP_REG)
15544                    (plus:SI (reg:SI SP_REG)
15545                             (match_operand:SI 3 "" "")))])]
15546   "!TARGET_64BIT"
15547 {
15548   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15549   DONE;
15550 })
15551
15552 (define_insn "*call_pop_0"
15553   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15554          (match_operand:SI 1 "" ""))
15555    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15556                             (match_operand:SI 2 "immediate_operand" "")))]
15557   "!TARGET_64BIT"
15558 {
15559   if (SIBLING_CALL_P (insn))
15560     return "jmp\t%P0";
15561   else
15562     return "call\t%P0";
15563 }
15564   [(set_attr "type" "call")])
15565
15566 (define_insn "*call_pop_1"
15567   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15568          (match_operand:SI 1 "" ""))
15569    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15570                             (match_operand:SI 2 "immediate_operand" "i")))]
15571   "!TARGET_64BIT"
15572 {
15573   if (constant_call_address_operand (operands[0], Pmode))
15574     {
15575       if (SIBLING_CALL_P (insn))
15576         return "jmp\t%P0";
15577       else
15578         return "call\t%P0";
15579     }
15580   if (SIBLING_CALL_P (insn))
15581     return "jmp\t%A0";
15582   else
15583     return "call\t%A0";
15584 }
15585   [(set_attr "type" "call")])
15586
15587 (define_expand "call"
15588   [(call (match_operand:QI 0 "" "")
15589          (match_operand 1 "" ""))
15590    (use (match_operand 2 "" ""))]
15591   ""
15592 {
15593   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15594   DONE;
15595 })
15596
15597 (define_expand "sibcall"
15598   [(call (match_operand:QI 0 "" "")
15599          (match_operand 1 "" ""))
15600    (use (match_operand 2 "" ""))]
15601   ""
15602 {
15603   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15604   DONE;
15605 })
15606
15607 (define_insn "*call_0"
15608   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15609          (match_operand 1 "" ""))]
15610   ""
15611 {
15612   if (SIBLING_CALL_P (insn))
15613     return "jmp\t%P0";
15614   else
15615     return "call\t%P0";
15616 }
15617   [(set_attr "type" "call")])
15618
15619 (define_insn "*call_1"
15620   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15621          (match_operand 1 "" ""))]
15622   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15623 {
15624   if (constant_call_address_operand (operands[0], Pmode))
15625     return "call\t%P0";
15626   return "call\t%A0";
15627 }
15628   [(set_attr "type" "call")])
15629
15630 (define_insn "*sibcall_1"
15631   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15632          (match_operand 1 "" ""))]
15633   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15634 {
15635   if (constant_call_address_operand (operands[0], Pmode))
15636     return "jmp\t%P0";
15637   return "jmp\t%A0";
15638 }
15639   [(set_attr "type" "call")])
15640
15641 (define_insn "*call_1_rex64"
15642   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15643          (match_operand 1 "" ""))]
15644   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15645    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15646 {
15647   if (constant_call_address_operand (operands[0], Pmode))
15648     return "call\t%P0";
15649   return "call\t%A0";
15650 }
15651   [(set_attr "type" "call")])
15652
15653 (define_insn "*call_1_rex64_ms_sysv"
15654   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15655          (match_operand 1 "" ""))
15656    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15657    (clobber (reg:TI XMM6_REG))
15658    (clobber (reg:TI XMM7_REG))
15659    (clobber (reg:TI XMM8_REG))
15660    (clobber (reg:TI XMM9_REG))
15661    (clobber (reg:TI XMM10_REG))
15662    (clobber (reg:TI XMM11_REG))
15663    (clobber (reg:TI XMM12_REG))
15664    (clobber (reg:TI XMM13_REG))
15665    (clobber (reg:TI XMM14_REG))
15666    (clobber (reg:TI XMM15_REG))
15667    (clobber (reg:DI SI_REG))
15668    (clobber (reg:DI DI_REG))]
15669   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15670 {
15671   if (constant_call_address_operand (operands[0], Pmode))
15672     return "call\t%P0";
15673   return "call\t%A0";
15674 }
15675   [(set_attr "type" "call")])
15676
15677 (define_insn "*call_1_rex64_large"
15678   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15679          (match_operand 1 "" ""))]
15680   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15681   "call\t%A0"
15682   [(set_attr "type" "call")])
15683
15684 (define_insn "*sibcall_1_rex64"
15685   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15686          (match_operand 1 "" ""))]
15687   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15688   "jmp\t%P0"
15689   [(set_attr "type" "call")])
15690
15691 (define_insn "*sibcall_1_rex64_v"
15692   [(call (mem:QI (reg:DI R11_REG))
15693          (match_operand 0 "" ""))]
15694   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15695   "jmp\t{*%%}r11"
15696   [(set_attr "type" "call")])
15697
15698
15699 ;; Call subroutine, returning value in operand 0
15700
15701 (define_expand "call_value_pop"
15702   [(parallel [(set (match_operand 0 "" "")
15703                    (call (match_operand:QI 1 "" "")
15704                          (match_operand:SI 2 "" "")))
15705               (set (reg:SI SP_REG)
15706                    (plus:SI (reg:SI SP_REG)
15707                             (match_operand:SI 4 "" "")))])]
15708   "!TARGET_64BIT"
15709 {
15710   ix86_expand_call (operands[0], operands[1], operands[2],
15711                     operands[3], operands[4], 0);
15712   DONE;
15713 })
15714
15715 (define_expand "call_value"
15716   [(set (match_operand 0 "" "")
15717         (call (match_operand:QI 1 "" "")
15718               (match_operand:SI 2 "" "")))
15719    (use (match_operand:SI 3 "" ""))]
15720   ;; Operand 2 not used on the i386.
15721   ""
15722 {
15723   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15724   DONE;
15725 })
15726
15727 (define_expand "sibcall_value"
15728   [(set (match_operand 0 "" "")
15729         (call (match_operand:QI 1 "" "")
15730               (match_operand:SI 2 "" "")))
15731    (use (match_operand:SI 3 "" ""))]
15732   ;; Operand 2 not used on the i386.
15733   ""
15734 {
15735   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15736   DONE;
15737 })
15738
15739 ;; Call subroutine returning any type.
15740
15741 (define_expand "untyped_call"
15742   [(parallel [(call (match_operand 0 "" "")
15743                     (const_int 0))
15744               (match_operand 1 "" "")
15745               (match_operand 2 "" "")])]
15746   ""
15747 {
15748   int i;
15749
15750   /* In order to give reg-stack an easier job in validating two
15751      coprocessor registers as containing a possible return value,
15752      simply pretend the untyped call returns a complex long double
15753      value. 
15754
15755      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15756      and should have the default ABI.  */
15757
15758   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15759                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15760                     operands[0], const0_rtx,
15761                     GEN_INT ((TARGET_64BIT
15762                               ? (ix86_abi == SYSV_ABI
15763                                  ? X86_64_SSE_REGPARM_MAX
15764                                  : X86_64_MS_SSE_REGPARM_MAX)
15765                               : X86_32_SSE_REGPARM_MAX)
15766                              - 1),
15767                     NULL, 0);
15768
15769   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15770     {
15771       rtx set = XVECEXP (operands[2], 0, i);
15772       emit_move_insn (SET_DEST (set), SET_SRC (set));
15773     }
15774
15775   /* The optimizer does not know that the call sets the function value
15776      registers we stored in the result block.  We avoid problems by
15777      claiming that all hard registers are used and clobbered at this
15778      point.  */
15779   emit_insn (gen_blockage ());
15780
15781   DONE;
15782 })
15783 \f
15784 ;; Prologue and epilogue instructions
15785
15786 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15787 ;; all of memory.  This blocks insns from being moved across this point.
15788
15789 (define_insn "blockage"
15790   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15791   ""
15792   ""
15793   [(set_attr "length" "0")])
15794
15795 ;; Do not schedule instructions accessing memory across this point.
15796
15797 (define_expand "memory_blockage"
15798   [(set (match_dup 0)
15799         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15800   ""
15801 {
15802   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15803   MEM_VOLATILE_P (operands[0]) = 1;
15804 })
15805
15806 (define_insn "*memory_blockage"
15807   [(set (match_operand:BLK 0 "" "")
15808         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15809   ""
15810   ""
15811   [(set_attr "length" "0")])
15812
15813 ;; As USE insns aren't meaningful after reload, this is used instead
15814 ;; to prevent deleting instructions setting registers for PIC code
15815 (define_insn "prologue_use"
15816   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15817   ""
15818   ""
15819   [(set_attr "length" "0")])
15820
15821 ;; Insn emitted into the body of a function to return from a function.
15822 ;; This is only done if the function's epilogue is known to be simple.
15823 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15824
15825 (define_expand "return"
15826   [(return)]
15827   "ix86_can_use_return_insn_p ()"
15828 {
15829   if (crtl->args.pops_args)
15830     {
15831       rtx popc = GEN_INT (crtl->args.pops_args);
15832       emit_jump_insn (gen_return_pop_internal (popc));
15833       DONE;
15834     }
15835 })
15836
15837 (define_insn "return_internal"
15838   [(return)]
15839   "reload_completed"
15840   "ret"
15841   [(set_attr "length" "1")
15842    (set_attr "atom_unit" "jeu")
15843    (set_attr "length_immediate" "0")
15844    (set_attr "modrm" "0")])
15845
15846 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15847 ;; instruction Athlon and K8 have.
15848
15849 (define_insn "return_internal_long"
15850   [(return)
15851    (unspec [(const_int 0)] UNSPEC_REP)]
15852   "reload_completed"
15853   "rep\;ret"
15854   [(set_attr "length" "2")
15855    (set_attr "atom_unit" "jeu")
15856    (set_attr "length_immediate" "0")
15857    (set_attr "prefix_rep" "1")
15858    (set_attr "modrm" "0")])
15859
15860 (define_insn "return_pop_internal"
15861   [(return)
15862    (use (match_operand:SI 0 "const_int_operand" ""))]
15863   "reload_completed"
15864   "ret\t%0"
15865   [(set_attr "length" "3")
15866    (set_attr "atom_unit" "jeu")
15867    (set_attr "length_immediate" "2")
15868    (set_attr "modrm" "0")])
15869
15870 (define_insn "return_indirect_internal"
15871   [(return)
15872    (use (match_operand:SI 0 "register_operand" "r"))]
15873   "reload_completed"
15874   "jmp\t%A0"
15875   [(set_attr "type" "ibr")
15876    (set_attr "length_immediate" "0")])
15877
15878 (define_insn "nop"
15879   [(const_int 0)]
15880   ""
15881   "nop"
15882   [(set_attr "length" "1")
15883    (set_attr "length_immediate" "0")
15884    (set_attr "modrm" "0")])
15885
15886 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
15887 ;; branch prediction penalty for the third jump in a 16-byte
15888 ;; block on K8.
15889
15890 (define_insn "pad"
15891   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15892   ""
15893 {
15894 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15895   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15896 #else
15897   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15898      The align insn is used to avoid 3 jump instructions in the row to improve
15899      branch prediction and the benefits hardly outweigh the cost of extra 8
15900      nops on the average inserted by full alignment pseudo operation.  */
15901 #endif
15902   return "";
15903 }
15904   [(set_attr "length" "16")])
15905
15906 (define_expand "prologue"
15907   [(const_int 0)]
15908   ""
15909   "ix86_expand_prologue (); DONE;")
15910
15911 (define_insn "set_got"
15912   [(set (match_operand:SI 0 "register_operand" "=r")
15913         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15914    (clobber (reg:CC FLAGS_REG))]
15915   "!TARGET_64BIT"
15916   { return output_set_got (operands[0], NULL_RTX); }
15917   [(set_attr "type" "multi")
15918    (set_attr "length" "12")])
15919
15920 (define_insn "set_got_labelled"
15921   [(set (match_operand:SI 0 "register_operand" "=r")
15922         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15923          UNSPEC_SET_GOT))
15924    (clobber (reg:CC FLAGS_REG))]
15925   "!TARGET_64BIT"
15926   { return output_set_got (operands[0], operands[1]); }
15927   [(set_attr "type" "multi")
15928    (set_attr "length" "12")])
15929
15930 (define_insn "set_got_rex64"
15931   [(set (match_operand:DI 0 "register_operand" "=r")
15932         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15933   "TARGET_64BIT"
15934   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15935   [(set_attr "type" "lea")
15936    (set_attr "length_address" "4")
15937    (set_attr "mode" "DI")])
15938
15939 (define_insn "set_rip_rex64"
15940   [(set (match_operand:DI 0 "register_operand" "=r")
15941         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15942   "TARGET_64BIT"
15943   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15944   [(set_attr "type" "lea")
15945    (set_attr "length_address" "4")
15946    (set_attr "mode" "DI")])
15947
15948 (define_insn "set_got_offset_rex64"
15949   [(set (match_operand:DI 0 "register_operand" "=r")
15950         (unspec:DI
15951           [(label_ref (match_operand 1 "" ""))]
15952           UNSPEC_SET_GOT_OFFSET))]
15953   "TARGET_64BIT"
15954   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15955   [(set_attr "type" "imov")
15956    (set_attr "length_immediate" "0")
15957    (set_attr "length_address" "8")
15958    (set_attr "mode" "DI")])
15959
15960 (define_expand "epilogue"
15961   [(const_int 0)]
15962   ""
15963   "ix86_expand_epilogue (1); DONE;")
15964
15965 (define_expand "sibcall_epilogue"
15966   [(const_int 0)]
15967   ""
15968   "ix86_expand_epilogue (0); DONE;")
15969
15970 (define_expand "eh_return"
15971   [(use (match_operand 0 "register_operand" ""))]
15972   ""
15973 {
15974   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15975
15976   /* Tricky bit: we write the address of the handler to which we will
15977      be returning into someone else's stack frame, one word below the
15978      stack address we wish to restore.  */
15979   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15980   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15981   tmp = gen_rtx_MEM (Pmode, tmp);
15982   emit_move_insn (tmp, ra);
15983
15984   emit_jump_insn (gen_eh_return_internal ());
15985   emit_barrier ();
15986   DONE;
15987 })
15988
15989 (define_insn_and_split "eh_return_internal"
15990   [(eh_return)]
15991   ""
15992   "#"
15993   "epilogue_completed"
15994   [(const_int 0)]
15995   "ix86_expand_epilogue (2); DONE;")
15996
15997 (define_insn "leave"
15998   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15999    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
16000    (clobber (mem:BLK (scratch)))]
16001   "!TARGET_64BIT"
16002   "leave"
16003   [(set_attr "type" "leave")])
16004
16005 (define_insn "leave_rex64"
16006   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
16007    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
16008    (clobber (mem:BLK (scratch)))]
16009   "TARGET_64BIT"
16010   "leave"
16011   [(set_attr "type" "leave")])
16012 \f
16013 (define_expand "ffssi2"
16014   [(parallel
16015      [(set (match_operand:SI 0 "register_operand" "")
16016            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
16017       (clobber (match_scratch:SI 2 ""))
16018       (clobber (reg:CC FLAGS_REG))])]
16019   ""
16020 {
16021   if (TARGET_CMOVE)
16022     {
16023       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
16024       DONE;
16025     }
16026 })
16027
16028 (define_expand "ffs_cmove"
16029   [(set (match_dup 2) (const_int -1))
16030    (parallel [(set (reg:CCZ FLAGS_REG)
16031                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
16032                                 (const_int 0)))
16033               (set (match_operand:SI 0 "register_operand" "")
16034                    (ctz:SI (match_dup 1)))])
16035    (set (match_dup 0) (if_then_else:SI
16036                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
16037                         (match_dup 2)
16038                         (match_dup 0)))
16039    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16040               (clobber (reg:CC FLAGS_REG))])]
16041   "TARGET_CMOVE"
16042   "operands[2] = gen_reg_rtx (SImode);")
16043
16044 (define_insn_and_split "*ffs_no_cmove"
16045   [(set (match_operand:SI 0 "register_operand" "=r")
16046         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16047    (clobber (match_scratch:SI 2 "=&q"))
16048    (clobber (reg:CC FLAGS_REG))]
16049   "!TARGET_CMOVE"
16050   "#"
16051   "&& reload_completed"
16052   [(parallel [(set (reg:CCZ FLAGS_REG)
16053                    (compare:CCZ (match_dup 1) (const_int 0)))
16054               (set (match_dup 0) (ctz:SI (match_dup 1)))])
16055    (set (strict_low_part (match_dup 3))
16056         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
16057    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
16058               (clobber (reg:CC FLAGS_REG))])
16059    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
16060               (clobber (reg:CC FLAGS_REG))])
16061    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16062               (clobber (reg:CC FLAGS_REG))])]
16063 {
16064   operands[3] = gen_lowpart (QImode, operands[2]);
16065   ix86_expand_clear (operands[2]);
16066 })
16067
16068 (define_insn "*ffssi_1"
16069   [(set (reg:CCZ FLAGS_REG)
16070         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
16071                      (const_int 0)))
16072    (set (match_operand:SI 0 "register_operand" "=r")
16073         (ctz:SI (match_dup 1)))]
16074   ""
16075   "bsf{l}\t{%1, %0|%0, %1}"
16076   [(set_attr "type" "alu1")
16077    (set_attr "prefix_0f" "1")
16078    (set_attr "mode" "SI")])
16079
16080 (define_expand "ffsdi2"
16081   [(set (match_dup 2) (const_int -1))
16082    (parallel [(set (reg:CCZ FLAGS_REG)
16083                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
16084                                 (const_int 0)))
16085               (set (match_operand:DI 0 "register_operand" "")
16086                    (ctz:DI (match_dup 1)))])
16087    (set (match_dup 0) (if_then_else:DI
16088                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
16089                         (match_dup 2)
16090                         (match_dup 0)))
16091    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16092               (clobber (reg:CC FLAGS_REG))])]
16093   "TARGET_64BIT"
16094   "operands[2] = gen_reg_rtx (DImode);")
16095
16096 (define_insn "*ffsdi_1"
16097   [(set (reg:CCZ FLAGS_REG)
16098         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
16099                      (const_int 0)))
16100    (set (match_operand:DI 0 "register_operand" "=r")
16101         (ctz:DI (match_dup 1)))]
16102   "TARGET_64BIT"
16103   "bsf{q}\t{%1, %0|%0, %1}"
16104   [(set_attr "type" "alu1")
16105    (set_attr "prefix_0f" "1")
16106    (set_attr "mode" "DI")])
16107
16108 (define_insn "ctzsi2"
16109   [(set (match_operand:SI 0 "register_operand" "=r")
16110         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16111    (clobber (reg:CC FLAGS_REG))]
16112   ""
16113   "bsf{l}\t{%1, %0|%0, %1}"
16114   [(set_attr "type" "alu1")
16115    (set_attr "prefix_0f" "1")
16116    (set_attr "mode" "SI")])
16117
16118 (define_insn "ctzdi2"
16119   [(set (match_operand:DI 0 "register_operand" "=r")
16120         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16121    (clobber (reg:CC FLAGS_REG))]
16122   "TARGET_64BIT"
16123   "bsf{q}\t{%1, %0|%0, %1}"
16124   [(set_attr "type" "alu1")
16125    (set_attr "prefix_0f" "1")
16126    (set_attr "mode" "DI")])
16127
16128 (define_expand "clzsi2"
16129   [(parallel
16130      [(set (match_operand:SI 0 "register_operand" "")
16131            (minus:SI (const_int 31)
16132                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
16133       (clobber (reg:CC FLAGS_REG))])
16134    (parallel
16135      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
16136       (clobber (reg:CC FLAGS_REG))])]
16137   ""
16138 {
16139   if (TARGET_ABM)
16140     {
16141       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16142       DONE;
16143     }
16144 })
16145
16146 (define_insn "clzsi2_abm"
16147   [(set (match_operand:SI 0 "register_operand" "=r")
16148         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16149    (clobber (reg:CC FLAGS_REG))]
16150   "TARGET_ABM"
16151   "lzcnt{l}\t{%1, %0|%0, %1}"
16152   [(set_attr "prefix_rep" "1")
16153    (set_attr "type" "bitmanip")
16154    (set_attr "mode" "SI")])
16155
16156 (define_insn "*bsr"
16157   [(set (match_operand:SI 0 "register_operand" "=r")
16158         (minus:SI (const_int 31)
16159                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
16160    (clobber (reg:CC FLAGS_REG))]
16161   ""
16162   "bsr{l}\t{%1, %0|%0, %1}"
16163   [(set_attr "type" "alu1")
16164    (set_attr "prefix_0f" "1")
16165    (set_attr "mode" "SI")])
16166
16167 (define_insn "popcount<mode>2"
16168   [(set (match_operand:SWI248 0 "register_operand" "=r")
16169         (popcount:SWI248
16170           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
16171    (clobber (reg:CC FLAGS_REG))]
16172   "TARGET_POPCNT"
16173 {
16174 #if TARGET_MACHO
16175   return "popcnt\t{%1, %0|%0, %1}";
16176 #else
16177   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16178 #endif
16179 }
16180   [(set_attr "prefix_rep" "1")
16181    (set_attr "type" "bitmanip")
16182    (set_attr "mode" "<MODE>")])
16183
16184 (define_insn "*popcount<mode>2_cmp"
16185   [(set (reg FLAGS_REG)
16186         (compare
16187           (popcount:SWI248
16188             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
16189           (const_int 0)))
16190    (set (match_operand:SWI248 0 "register_operand" "=r")
16191         (popcount:SWI248 (match_dup 1)))]
16192   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16193 {
16194 #if TARGET_MACHO
16195   return "popcnt\t{%1, %0|%0, %1}";
16196 #else
16197   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16198 #endif
16199 }
16200   [(set_attr "prefix_rep" "1")
16201    (set_attr "type" "bitmanip")
16202    (set_attr "mode" "<MODE>")])
16203
16204 (define_insn "*popcountsi2_cmp_zext"
16205   [(set (reg FLAGS_REG)
16206         (compare
16207           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16208           (const_int 0)))
16209    (set (match_operand:DI 0 "register_operand" "=r")
16210         (zero_extend:DI(popcount:SI (match_dup 1))))]
16211   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16212 {
16213 #if TARGET_MACHO
16214   return "popcnt\t{%1, %0|%0, %1}";
16215 #else
16216   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16217 #endif
16218 }
16219   [(set_attr "prefix_rep" "1")
16220    (set_attr "type" "bitmanip")
16221    (set_attr "mode" "SI")])
16222
16223 (define_expand "bswapsi2"
16224   [(set (match_operand:SI 0 "register_operand" "")
16225         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16226   ""
16227 {
16228   if (!(TARGET_BSWAP || TARGET_MOVBE))
16229     {
16230       rtx x = operands[0];
16231
16232       emit_move_insn (x, operands[1]);
16233       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16234       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16235       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16236       DONE;
16237     }
16238 })
16239
16240 (define_insn "*bswapsi_movbe"
16241   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16242         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16243   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16244   "@
16245     bswap\t%0
16246     movbe\t{%1, %0|%0, %1}
16247     movbe\t{%1, %0|%0, %1}"
16248   [(set_attr "type" "*,imov,imov")
16249    (set_attr "modrm" "*,1,1")
16250    (set_attr "prefix_0f" "1")
16251    (set_attr "prefix_extra" "*,1,1")
16252    (set_attr "length" "2,*,*")
16253    (set_attr "mode" "SI")])
16254
16255 (define_insn "*bswapsi_1"
16256   [(set (match_operand:SI 0 "register_operand" "=r")
16257         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
16258   "TARGET_BSWAP"
16259   "bswap\t%0"
16260   [(set_attr "prefix_0f" "1")
16261    (set_attr "length" "2")])
16262
16263 (define_insn "*bswaphi_lowpart_1"
16264   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16265         (bswap:HI (match_dup 0)))
16266    (clobber (reg:CC FLAGS_REG))]
16267   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
16268   "@
16269     xchg{b}\t{%h0, %b0|%b0, %h0}
16270     rol{w}\t{$8, %0|%0, 8}"
16271   [(set_attr "length" "2,4")
16272    (set_attr "mode" "QI,HI")])
16273
16274 (define_insn "bswaphi_lowpart"
16275   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16276         (bswap:HI (match_dup 0)))
16277    (clobber (reg:CC FLAGS_REG))]
16278   ""
16279   "rol{w}\t{$8, %0|%0, 8}"
16280   [(set_attr "length" "4")
16281    (set_attr "mode" "HI")])
16282
16283 (define_expand "bswapdi2"
16284   [(set (match_operand:DI 0 "register_operand" "")
16285         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16286   "TARGET_64BIT"
16287   "")
16288
16289 (define_insn "*bswapdi_movbe"
16290   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16291         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16292   "TARGET_64BIT && TARGET_MOVBE
16293    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16294   "@
16295     bswap\t%0
16296     movbe\t{%1, %0|%0, %1}
16297     movbe\t{%1, %0|%0, %1}"
16298   [(set_attr "type" "*,imov,imov")
16299    (set_attr "modrm" "*,1,1")
16300    (set_attr "prefix_0f" "1")
16301    (set_attr "prefix_extra" "*,1,1")
16302    (set_attr "length" "3,*,*")
16303    (set_attr "mode" "DI")])
16304
16305 (define_insn "*bswapdi_1"
16306   [(set (match_operand:DI 0 "register_operand" "=r")
16307         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16308   "TARGET_64BIT"
16309   "bswap\t%0"
16310   [(set_attr "prefix_0f" "1")
16311    (set_attr "length" "3")])
16312
16313 (define_expand "clzdi2"
16314   [(parallel
16315      [(set (match_operand:DI 0 "register_operand" "")
16316            (minus:DI (const_int 63)
16317                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
16318       (clobber (reg:CC FLAGS_REG))])
16319    (parallel
16320      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
16321       (clobber (reg:CC FLAGS_REG))])]
16322   "TARGET_64BIT"
16323 {
16324   if (TARGET_ABM)
16325     {
16326       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16327       DONE;
16328     }
16329 })
16330
16331 (define_insn "clzdi2_abm"
16332   [(set (match_operand:DI 0 "register_operand" "=r")
16333         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16334    (clobber (reg:CC FLAGS_REG))]
16335   "TARGET_64BIT && TARGET_ABM"
16336   "lzcnt{q}\t{%1, %0|%0, %1}"
16337   [(set_attr "prefix_rep" "1")
16338    (set_attr "type" "bitmanip")
16339    (set_attr "mode" "DI")])
16340
16341 (define_insn "*bsr_rex64"
16342   [(set (match_operand:DI 0 "register_operand" "=r")
16343         (minus:DI (const_int 63)
16344                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
16345    (clobber (reg:CC FLAGS_REG))]
16346   "TARGET_64BIT"
16347   "bsr{q}\t{%1, %0|%0, %1}"
16348   [(set_attr "type" "alu1")
16349    (set_attr "prefix_0f" "1")
16350    (set_attr "mode" "DI")])
16351
16352 (define_expand "clzhi2"
16353   [(parallel
16354      [(set (match_operand:HI 0 "register_operand" "")
16355            (minus:HI (const_int 15)
16356                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16357       (clobber (reg:CC FLAGS_REG))])
16358    (parallel
16359      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16360       (clobber (reg:CC FLAGS_REG))])]
16361   ""
16362 {
16363   if (TARGET_ABM)
16364     {
16365       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16366       DONE;
16367     }
16368 })
16369
16370 (define_insn "clzhi2_abm"
16371   [(set (match_operand:HI 0 "register_operand" "=r")
16372         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
16373    (clobber (reg:CC FLAGS_REG))]
16374   "TARGET_ABM"
16375   "lzcnt{w}\t{%1, %0|%0, %1}"
16376   [(set_attr "prefix_rep" "1")
16377    (set_attr "type" "bitmanip")
16378    (set_attr "mode" "HI")])
16379
16380 (define_insn "*bsrhi"
16381   [(set (match_operand:HI 0 "register_operand" "=r")
16382         (minus:HI (const_int 15)
16383                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16384    (clobber (reg:CC FLAGS_REG))]
16385   ""
16386   "bsr{w}\t{%1, %0|%0, %1}"
16387   [(set_attr "type" "alu1")
16388    (set_attr "prefix_0f" "1")
16389    (set_attr "mode" "HI")])
16390
16391 (define_expand "paritydi2"
16392   [(set (match_operand:DI 0 "register_operand" "")
16393         (parity:DI (match_operand:DI 1 "register_operand" "")))]
16394   "! TARGET_POPCNT"
16395 {
16396   rtx scratch = gen_reg_rtx (QImode);
16397   rtx cond;
16398
16399   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16400                                 NULL_RTX, operands[1]));
16401
16402   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16403                          gen_rtx_REG (CCmode, FLAGS_REG),
16404                          const0_rtx);
16405   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16406
16407   if (TARGET_64BIT)
16408     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16409   else
16410     {
16411       rtx tmp = gen_reg_rtx (SImode);
16412
16413       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16414       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16415     }
16416   DONE;
16417 })
16418
16419 (define_insn_and_split "paritydi2_cmp"
16420   [(set (reg:CC FLAGS_REG)
16421         (parity:CC (match_operand:DI 3 "register_operand" "0")))
16422    (clobber (match_scratch:DI 0 "=r"))
16423    (clobber (match_scratch:SI 1 "=&r"))
16424    (clobber (match_scratch:HI 2 "=Q"))]
16425   "! TARGET_POPCNT"
16426   "#"
16427   "&& reload_completed"
16428   [(parallel
16429      [(set (match_dup 1)
16430            (xor:SI (match_dup 1) (match_dup 4)))
16431       (clobber (reg:CC FLAGS_REG))])
16432    (parallel
16433      [(set (reg:CC FLAGS_REG)
16434            (parity:CC (match_dup 1)))
16435       (clobber (match_dup 1))
16436       (clobber (match_dup 2))])]
16437 {
16438   operands[4] = gen_lowpart (SImode, operands[3]);
16439
16440   if (TARGET_64BIT)
16441     {
16442       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16443       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16444     }
16445   else
16446     operands[1] = gen_highpart (SImode, operands[3]);
16447 })
16448
16449 (define_expand "paritysi2"
16450   [(set (match_operand:SI 0 "register_operand" "")
16451         (parity:SI (match_operand:SI 1 "register_operand" "")))]
16452   "! TARGET_POPCNT"
16453 {
16454   rtx scratch = gen_reg_rtx (QImode);
16455   rtx cond;
16456
16457   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16458
16459   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16460                          gen_rtx_REG (CCmode, FLAGS_REG),
16461                          const0_rtx);
16462   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16463
16464   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16465   DONE;
16466 })
16467
16468 (define_insn_and_split "paritysi2_cmp"
16469   [(set (reg:CC FLAGS_REG)
16470         (parity:CC (match_operand:SI 2 "register_operand" "0")))
16471    (clobber (match_scratch:SI 0 "=r"))
16472    (clobber (match_scratch:HI 1 "=&Q"))]
16473   "! TARGET_POPCNT"
16474   "#"
16475   "&& reload_completed"
16476   [(parallel
16477      [(set (match_dup 1)
16478            (xor:HI (match_dup 1) (match_dup 3)))
16479       (clobber (reg:CC FLAGS_REG))])
16480    (parallel
16481      [(set (reg:CC FLAGS_REG)
16482            (parity:CC (match_dup 1)))
16483       (clobber (match_dup 1))])]
16484 {
16485   operands[3] = gen_lowpart (HImode, operands[2]);
16486
16487   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16488   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16489 })
16490
16491 (define_insn "*parityhi2_cmp"
16492   [(set (reg:CC FLAGS_REG)
16493         (parity:CC (match_operand:HI 1 "register_operand" "0")))
16494    (clobber (match_scratch:HI 0 "=Q"))]
16495   "! TARGET_POPCNT"
16496   "xor{b}\t{%h0, %b0|%b0, %h0}"
16497   [(set_attr "length" "2")
16498    (set_attr "mode" "HI")])
16499
16500 (define_insn "*parityqi2_cmp"
16501   [(set (reg:CC FLAGS_REG)
16502         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16503   "! TARGET_POPCNT"
16504   "test{b}\t%0, %0"
16505   [(set_attr "length" "2")
16506    (set_attr "mode" "QI")])
16507 \f
16508 ;; Thread-local storage patterns for ELF.
16509 ;;
16510 ;; Note that these code sequences must appear exactly as shown
16511 ;; in order to allow linker relaxation.
16512
16513 (define_insn "*tls_global_dynamic_32_gnu"
16514   [(set (match_operand:SI 0 "register_operand" "=a")
16515         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16516                     (match_operand:SI 2 "tls_symbolic_operand" "")
16517                     (match_operand:SI 3 "call_insn_operand" "")]
16518                     UNSPEC_TLS_GD))
16519    (clobber (match_scratch:SI 4 "=d"))
16520    (clobber (match_scratch:SI 5 "=c"))
16521    (clobber (reg:CC FLAGS_REG))]
16522   "!TARGET_64BIT && TARGET_GNU_TLS"
16523   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16524   [(set_attr "type" "multi")
16525    (set_attr "length" "12")])
16526
16527 (define_insn "*tls_global_dynamic_32_sun"
16528   [(set (match_operand:SI 0 "register_operand" "=a")
16529         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16530                     (match_operand:SI 2 "tls_symbolic_operand" "")
16531                     (match_operand:SI 3 "call_insn_operand" "")]
16532                     UNSPEC_TLS_GD))
16533    (clobber (match_scratch:SI 4 "=d"))
16534    (clobber (match_scratch:SI 5 "=c"))
16535    (clobber (reg:CC FLAGS_REG))]
16536   "!TARGET_64BIT && TARGET_SUN_TLS"
16537   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16538         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16539   [(set_attr "type" "multi")
16540    (set_attr "length" "14")])
16541
16542 (define_expand "tls_global_dynamic_32"
16543   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16544                    (unspec:SI
16545                     [(match_dup 2)
16546                      (match_operand:SI 1 "tls_symbolic_operand" "")
16547                      (match_dup 3)]
16548                     UNSPEC_TLS_GD))
16549               (clobber (match_scratch:SI 4 ""))
16550               (clobber (match_scratch:SI 5 ""))
16551               (clobber (reg:CC FLAGS_REG))])]
16552   ""
16553 {
16554   if (flag_pic)
16555     operands[2] = pic_offset_table_rtx;
16556   else
16557     {
16558       operands[2] = gen_reg_rtx (Pmode);
16559       emit_insn (gen_set_got (operands[2]));
16560     }
16561   if (TARGET_GNU2_TLS)
16562     {
16563        emit_insn (gen_tls_dynamic_gnu2_32
16564                   (operands[0], operands[1], operands[2]));
16565        DONE;
16566     }
16567   operands[3] = ix86_tls_get_addr ();
16568 })
16569
16570 (define_insn "*tls_global_dynamic_64"
16571   [(set (match_operand:DI 0 "register_operand" "=a")
16572         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16573                  (match_operand:DI 3 "" "")))
16574    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16575               UNSPEC_TLS_GD)]
16576   "TARGET_64BIT"
16577   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16578   [(set_attr "type" "multi")
16579    (set_attr "length" "16")])
16580
16581 (define_expand "tls_global_dynamic_64"
16582   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16583                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16584               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16585                          UNSPEC_TLS_GD)])]
16586   ""
16587 {
16588   if (TARGET_GNU2_TLS)
16589     {
16590        emit_insn (gen_tls_dynamic_gnu2_64
16591                   (operands[0], operands[1]));
16592        DONE;
16593     }
16594   operands[2] = ix86_tls_get_addr ();
16595 })
16596
16597 (define_insn "*tls_local_dynamic_base_32_gnu"
16598   [(set (match_operand:SI 0 "register_operand" "=a")
16599         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16600                     (match_operand:SI 2 "call_insn_operand" "")]
16601                    UNSPEC_TLS_LD_BASE))
16602    (clobber (match_scratch:SI 3 "=d"))
16603    (clobber (match_scratch:SI 4 "=c"))
16604    (clobber (reg:CC FLAGS_REG))]
16605   "!TARGET_64BIT && TARGET_GNU_TLS"
16606   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16607   [(set_attr "type" "multi")
16608    (set_attr "length" "11")])
16609
16610 (define_insn "*tls_local_dynamic_base_32_sun"
16611   [(set (match_operand:SI 0 "register_operand" "=a")
16612         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16613                     (match_operand:SI 2 "call_insn_operand" "")]
16614                    UNSPEC_TLS_LD_BASE))
16615    (clobber (match_scratch:SI 3 "=d"))
16616    (clobber (match_scratch:SI 4 "=c"))
16617    (clobber (reg:CC FLAGS_REG))]
16618   "!TARGET_64BIT && TARGET_SUN_TLS"
16619   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16620         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16621   [(set_attr "type" "multi")
16622    (set_attr "length" "13")])
16623
16624 (define_expand "tls_local_dynamic_base_32"
16625   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16626                    (unspec:SI [(match_dup 1) (match_dup 2)]
16627                               UNSPEC_TLS_LD_BASE))
16628               (clobber (match_scratch:SI 3 ""))
16629               (clobber (match_scratch:SI 4 ""))
16630               (clobber (reg:CC FLAGS_REG))])]
16631   ""
16632 {
16633   if (flag_pic)
16634     operands[1] = pic_offset_table_rtx;
16635   else
16636     {
16637       operands[1] = gen_reg_rtx (Pmode);
16638       emit_insn (gen_set_got (operands[1]));
16639     }
16640   if (TARGET_GNU2_TLS)
16641     {
16642        emit_insn (gen_tls_dynamic_gnu2_32
16643                   (operands[0], ix86_tls_module_base (), operands[1]));
16644        DONE;
16645     }
16646   operands[2] = ix86_tls_get_addr ();
16647 })
16648
16649 (define_insn "*tls_local_dynamic_base_64"
16650   [(set (match_operand:DI 0 "register_operand" "=a")
16651         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16652                  (match_operand:DI 2 "" "")))
16653    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16654   "TARGET_64BIT"
16655   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16656   [(set_attr "type" "multi")
16657    (set_attr "length" "12")])
16658
16659 (define_expand "tls_local_dynamic_base_64"
16660   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16661                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16662               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16663   ""
16664 {
16665   if (TARGET_GNU2_TLS)
16666     {
16667        emit_insn (gen_tls_dynamic_gnu2_64
16668                   (operands[0], ix86_tls_module_base ()));
16669        DONE;
16670     }
16671   operands[1] = ix86_tls_get_addr ();
16672 })
16673
16674 ;; Local dynamic of a single variable is a lose.  Show combine how
16675 ;; to convert that back to global dynamic.
16676
16677 (define_insn_and_split "*tls_local_dynamic_32_once"
16678   [(set (match_operand:SI 0 "register_operand" "=a")
16679         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16680                              (match_operand:SI 2 "call_insn_operand" "")]
16681                             UNSPEC_TLS_LD_BASE)
16682                  (const:SI (unspec:SI
16683                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16684                             UNSPEC_DTPOFF))))
16685    (clobber (match_scratch:SI 4 "=d"))
16686    (clobber (match_scratch:SI 5 "=c"))
16687    (clobber (reg:CC FLAGS_REG))]
16688   ""
16689   "#"
16690   ""
16691   [(parallel [(set (match_dup 0)
16692                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16693                               UNSPEC_TLS_GD))
16694               (clobber (match_dup 4))
16695               (clobber (match_dup 5))
16696               (clobber (reg:CC FLAGS_REG))])]
16697   "")
16698
16699 ;; Load and add the thread base pointer from %gs:0.
16700
16701 (define_insn "*load_tp_si"
16702   [(set (match_operand:SI 0 "register_operand" "=r")
16703         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16704   "!TARGET_64BIT"
16705   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16706   [(set_attr "type" "imov")
16707    (set_attr "modrm" "0")
16708    (set_attr "length" "7")
16709    (set_attr "memory" "load")
16710    (set_attr "imm_disp" "false")])
16711
16712 (define_insn "*add_tp_si"
16713   [(set (match_operand:SI 0 "register_operand" "=r")
16714         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16715                  (match_operand:SI 1 "register_operand" "0")))
16716    (clobber (reg:CC FLAGS_REG))]
16717   "!TARGET_64BIT"
16718   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16719   [(set_attr "type" "alu")
16720    (set_attr "modrm" "0")
16721    (set_attr "length" "7")
16722    (set_attr "memory" "load")
16723    (set_attr "imm_disp" "false")])
16724
16725 (define_insn "*load_tp_di"
16726   [(set (match_operand:DI 0 "register_operand" "=r")
16727         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16728   "TARGET_64BIT"
16729   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16730   [(set_attr "type" "imov")
16731    (set_attr "modrm" "0")
16732    (set_attr "length" "7")
16733    (set_attr "memory" "load")
16734    (set_attr "imm_disp" "false")])
16735
16736 (define_insn "*add_tp_di"
16737   [(set (match_operand:DI 0 "register_operand" "=r")
16738         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16739                  (match_operand:DI 1 "register_operand" "0")))
16740    (clobber (reg:CC FLAGS_REG))]
16741   "TARGET_64BIT"
16742   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16743   [(set_attr "type" "alu")
16744    (set_attr "modrm" "0")
16745    (set_attr "length" "7")
16746    (set_attr "memory" "load")
16747    (set_attr "imm_disp" "false")])
16748
16749 ;; GNU2 TLS patterns can be split.
16750
16751 (define_expand "tls_dynamic_gnu2_32"
16752   [(set (match_dup 3)
16753         (plus:SI (match_operand:SI 2 "register_operand" "")
16754                  (const:SI
16755                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16756                              UNSPEC_TLSDESC))))
16757    (parallel
16758     [(set (match_operand:SI 0 "register_operand" "")
16759           (unspec:SI [(match_dup 1) (match_dup 3)
16760                       (match_dup 2) (reg:SI SP_REG)]
16761                       UNSPEC_TLSDESC))
16762      (clobber (reg:CC FLAGS_REG))])]
16763   "!TARGET_64BIT && TARGET_GNU2_TLS"
16764 {
16765   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16766   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16767 })
16768
16769 (define_insn "*tls_dynamic_lea_32"
16770   [(set (match_operand:SI 0 "register_operand" "=r")
16771         (plus:SI (match_operand:SI 1 "register_operand" "b")
16772                  (const:SI
16773                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16774                               UNSPEC_TLSDESC))))]
16775   "!TARGET_64BIT && TARGET_GNU2_TLS"
16776   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16777   [(set_attr "type" "lea")
16778    (set_attr "mode" "SI")
16779    (set_attr "length" "6")
16780    (set_attr "length_address" "4")])
16781
16782 (define_insn "*tls_dynamic_call_32"
16783   [(set (match_operand:SI 0 "register_operand" "=a")
16784         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16785                     (match_operand:SI 2 "register_operand" "0")
16786                     ;; we have to make sure %ebx still points to the GOT
16787                     (match_operand:SI 3 "register_operand" "b")
16788                     (reg:SI SP_REG)]
16789                    UNSPEC_TLSDESC))
16790    (clobber (reg:CC FLAGS_REG))]
16791   "!TARGET_64BIT && TARGET_GNU2_TLS"
16792   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16793   [(set_attr "type" "call")
16794    (set_attr "length" "2")
16795    (set_attr "length_address" "0")])
16796
16797 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16798   [(set (match_operand:SI 0 "register_operand" "=&a")
16799         (plus:SI
16800          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16801                      (match_operand:SI 4 "" "")
16802                      (match_operand:SI 2 "register_operand" "b")
16803                      (reg:SI SP_REG)]
16804                     UNSPEC_TLSDESC)
16805          (const:SI (unspec:SI
16806                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16807                     UNSPEC_DTPOFF))))
16808    (clobber (reg:CC FLAGS_REG))]
16809   "!TARGET_64BIT && TARGET_GNU2_TLS"
16810   "#"
16811   ""
16812   [(set (match_dup 0) (match_dup 5))]
16813 {
16814   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16815   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16816 })
16817
16818 (define_expand "tls_dynamic_gnu2_64"
16819   [(set (match_dup 2)
16820         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16821                    UNSPEC_TLSDESC))
16822    (parallel
16823     [(set (match_operand:DI 0 "register_operand" "")
16824           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16825                      UNSPEC_TLSDESC))
16826      (clobber (reg:CC FLAGS_REG))])]
16827   "TARGET_64BIT && TARGET_GNU2_TLS"
16828 {
16829   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16830   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16831 })
16832
16833 (define_insn "*tls_dynamic_lea_64"
16834   [(set (match_operand:DI 0 "register_operand" "=r")
16835         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16836                    UNSPEC_TLSDESC))]
16837   "TARGET_64BIT && TARGET_GNU2_TLS"
16838   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16839   [(set_attr "type" "lea")
16840    (set_attr "mode" "DI")
16841    (set_attr "length" "7")
16842    (set_attr "length_address" "4")])
16843
16844 (define_insn "*tls_dynamic_call_64"
16845   [(set (match_operand:DI 0 "register_operand" "=a")
16846         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16847                     (match_operand:DI 2 "register_operand" "0")
16848                     (reg:DI SP_REG)]
16849                    UNSPEC_TLSDESC))
16850    (clobber (reg:CC FLAGS_REG))]
16851   "TARGET_64BIT && TARGET_GNU2_TLS"
16852   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16853   [(set_attr "type" "call")
16854    (set_attr "length" "2")
16855    (set_attr "length_address" "0")])
16856
16857 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16858   [(set (match_operand:DI 0 "register_operand" "=&a")
16859         (plus:DI
16860          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16861                      (match_operand:DI 3 "" "")
16862                      (reg:DI SP_REG)]
16863                     UNSPEC_TLSDESC)
16864          (const:DI (unspec:DI
16865                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16866                     UNSPEC_DTPOFF))))
16867    (clobber (reg:CC FLAGS_REG))]
16868   "TARGET_64BIT && TARGET_GNU2_TLS"
16869   "#"
16870   ""
16871   [(set (match_dup 0) (match_dup 4))]
16872 {
16873   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16874   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16875 })
16876
16877 ;;
16878 \f
16879 ;; These patterns match the binary 387 instructions for addM3, subM3,
16880 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16881 ;; SFmode.  The first is the normal insn, the second the same insn but
16882 ;; with one operand a conversion, and the third the same insn but with
16883 ;; the other operand a conversion.  The conversion may be SFmode or
16884 ;; SImode if the target mode DFmode, but only SImode if the target mode
16885 ;; is SFmode.
16886
16887 ;; Gcc is slightly more smart about handling normal two address instructions
16888 ;; so use special patterns for add and mull.
16889
16890 (define_insn "*fop_<mode>_comm_mixed_avx"
16891   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16892         (match_operator:MODEF 3 "binary_fp_operator"
16893           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16894            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16895   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16896    && COMMUTATIVE_ARITH_P (operands[3])
16897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16898   "* return output_387_binary_op (insn, operands);"
16899   [(set (attr "type")
16900         (if_then_else (eq_attr "alternative" "1")
16901            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16902               (const_string "ssemul")
16903               (const_string "sseadd"))
16904            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16905               (const_string "fmul")
16906               (const_string "fop"))))
16907    (set_attr "prefix" "orig,maybe_vex")
16908    (set_attr "mode" "<MODE>")])
16909
16910 (define_insn "*fop_<mode>_comm_mixed"
16911   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16912         (match_operator:MODEF 3 "binary_fp_operator"
16913           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16914            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16915   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16916    && COMMUTATIVE_ARITH_P (operands[3])
16917    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16918   "* return output_387_binary_op (insn, operands);"
16919   [(set (attr "type")
16920         (if_then_else (eq_attr "alternative" "1")
16921            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16922               (const_string "ssemul")
16923               (const_string "sseadd"))
16924            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16925               (const_string "fmul")
16926               (const_string "fop"))))
16927    (set_attr "mode" "<MODE>")])
16928
16929 (define_insn "*fop_<mode>_comm_avx"
16930   [(set (match_operand:MODEF 0 "register_operand" "=x")
16931         (match_operator:MODEF 3 "binary_fp_operator"
16932           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16933            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16934   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16935    && COMMUTATIVE_ARITH_P (operands[3])
16936    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16937   "* return output_387_binary_op (insn, operands);"
16938   [(set (attr "type")
16939         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16940            (const_string "ssemul")
16941            (const_string "sseadd")))
16942    (set_attr "prefix" "vex")
16943    (set_attr "mode" "<MODE>")])
16944
16945 (define_insn "*fop_<mode>_comm_sse"
16946   [(set (match_operand:MODEF 0 "register_operand" "=x")
16947         (match_operator:MODEF 3 "binary_fp_operator"
16948           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16949            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16950   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16951    && COMMUTATIVE_ARITH_P (operands[3])
16952    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16953   "* return output_387_binary_op (insn, operands);"
16954   [(set (attr "type")
16955         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16956            (const_string "ssemul")
16957            (const_string "sseadd")))
16958    (set_attr "mode" "<MODE>")])
16959
16960 (define_insn "*fop_<mode>_comm_i387"
16961   [(set (match_operand:MODEF 0 "register_operand" "=f")
16962         (match_operator:MODEF 3 "binary_fp_operator"
16963           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16964            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16965   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16966    && COMMUTATIVE_ARITH_P (operands[3])
16967    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16968   "* return output_387_binary_op (insn, operands);"
16969   [(set (attr "type")
16970         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16971            (const_string "fmul")
16972            (const_string "fop")))
16973    (set_attr "mode" "<MODE>")])
16974
16975 (define_insn "*fop_<mode>_1_mixed_avx"
16976   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16977         (match_operator:MODEF 3 "binary_fp_operator"
16978           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16979            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16980   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16981    && !COMMUTATIVE_ARITH_P (operands[3])
16982    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16983   "* return output_387_binary_op (insn, operands);"
16984   [(set (attr "type")
16985         (cond [(and (eq_attr "alternative" "2")
16986                     (match_operand:MODEF 3 "mult_operator" ""))
16987                  (const_string "ssemul")
16988                (and (eq_attr "alternative" "2")
16989                     (match_operand:MODEF 3 "div_operator" ""))
16990                  (const_string "ssediv")
16991                (eq_attr "alternative" "2")
16992                  (const_string "sseadd")
16993                (match_operand:MODEF 3 "mult_operator" "")
16994                  (const_string "fmul")
16995                (match_operand:MODEF 3 "div_operator" "")
16996                  (const_string "fdiv")
16997               ]
16998               (const_string "fop")))
16999    (set_attr "prefix" "orig,orig,maybe_vex")
17000    (set_attr "mode" "<MODE>")])
17001
17002 (define_insn "*fop_<mode>_1_mixed"
17003   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
17004         (match_operator:MODEF 3 "binary_fp_operator"
17005           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
17006            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
17007   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
17008    && !COMMUTATIVE_ARITH_P (operands[3])
17009    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17010   "* return output_387_binary_op (insn, operands);"
17011   [(set (attr "type")
17012         (cond [(and (eq_attr "alternative" "2")
17013                     (match_operand:MODEF 3 "mult_operator" ""))
17014                  (const_string "ssemul")
17015                (and (eq_attr "alternative" "2")
17016                     (match_operand:MODEF 3 "div_operator" ""))
17017                  (const_string "ssediv")
17018                (eq_attr "alternative" "2")
17019                  (const_string "sseadd")
17020                (match_operand:MODEF 3 "mult_operator" "")
17021                  (const_string "fmul")
17022                (match_operand:MODEF 3 "div_operator" "")
17023                  (const_string "fdiv")
17024               ]
17025               (const_string "fop")))
17026    (set_attr "mode" "<MODE>")])
17027
17028 (define_insn "*rcpsf2_sse"
17029   [(set (match_operand:SF 0 "register_operand" "=x")
17030         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17031                    UNSPEC_RCP))]
17032   "TARGET_SSE_MATH"
17033   "%vrcpss\t{%1, %d0|%d0, %1}"
17034   [(set_attr "type" "sse")
17035    (set_attr "atom_sse_attr" "rcp")
17036    (set_attr "prefix" "maybe_vex")
17037    (set_attr "mode" "SF")])
17038
17039 (define_insn "*fop_<mode>_1_avx"
17040   [(set (match_operand:MODEF 0 "register_operand" "=x")
17041         (match_operator:MODEF 3 "binary_fp_operator"
17042           [(match_operand:MODEF 1 "register_operand" "x")
17043            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
17044   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17045    && !COMMUTATIVE_ARITH_P (operands[3])"
17046   "* return output_387_binary_op (insn, operands);"
17047   [(set (attr "type")
17048         (cond [(match_operand:MODEF 3 "mult_operator" "")
17049                  (const_string "ssemul")
17050                (match_operand:MODEF 3 "div_operator" "")
17051                  (const_string "ssediv")
17052               ]
17053               (const_string "sseadd")))
17054    (set_attr "prefix" "vex")
17055    (set_attr "mode" "<MODE>")])
17056
17057 (define_insn "*fop_<mode>_1_sse"
17058   [(set (match_operand:MODEF 0 "register_operand" "=x")
17059         (match_operator:MODEF 3 "binary_fp_operator"
17060           [(match_operand:MODEF 1 "register_operand" "0")
17061            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
17062   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17063    && !COMMUTATIVE_ARITH_P (operands[3])"
17064   "* return output_387_binary_op (insn, operands);"
17065   [(set (attr "type")
17066         (cond [(match_operand:MODEF 3 "mult_operator" "")
17067                  (const_string "ssemul")
17068                (match_operand:MODEF 3 "div_operator" "")
17069                  (const_string "ssediv")
17070               ]
17071               (const_string "sseadd")))
17072    (set_attr "mode" "<MODE>")])
17073
17074 ;; This pattern is not fully shadowed by the pattern above.
17075 (define_insn "*fop_<mode>_1_i387"
17076   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17077         (match_operator:MODEF 3 "binary_fp_operator"
17078           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
17079            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
17080   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
17081    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17082    && !COMMUTATIVE_ARITH_P (operands[3])
17083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17084   "* return output_387_binary_op (insn, operands);"
17085   [(set (attr "type")
17086         (cond [(match_operand:MODEF 3 "mult_operator" "")
17087                  (const_string "fmul")
17088                (match_operand:MODEF 3 "div_operator" "")
17089                  (const_string "fdiv")
17090               ]
17091               (const_string "fop")))
17092    (set_attr "mode" "<MODE>")])
17093
17094 ;; ??? Add SSE splitters for these!
17095 (define_insn "*fop_<MODEF:mode>_2_i387"
17096   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17097         (match_operator:MODEF 3 "binary_fp_operator"
17098           [(float:MODEF
17099              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17100            (match_operand:MODEF 2 "register_operand" "0,0")]))]
17101   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17102    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17103    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17104   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17105   [(set (attr "type")
17106         (cond [(match_operand:MODEF 3 "mult_operator" "")
17107                  (const_string "fmul")
17108                (match_operand:MODEF 3 "div_operator" "")
17109                  (const_string "fdiv")
17110               ]
17111               (const_string "fop")))
17112    (set_attr "fp_int_src" "true")
17113    (set_attr "mode" "<X87MODEI12:MODE>")])
17114
17115 (define_insn "*fop_<MODEF:mode>_3_i387"
17116   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17117         (match_operator:MODEF 3 "binary_fp_operator"
17118           [(match_operand:MODEF 1 "register_operand" "0,0")
17119            (float:MODEF
17120              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17121   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17122    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17123    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17124   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17125   [(set (attr "type")
17126         (cond [(match_operand:MODEF 3 "mult_operator" "")
17127                  (const_string "fmul")
17128                (match_operand:MODEF 3 "div_operator" "")
17129                  (const_string "fdiv")
17130               ]
17131               (const_string "fop")))
17132    (set_attr "fp_int_src" "true")
17133    (set_attr "mode" "<MODE>")])
17134
17135 (define_insn "*fop_df_4_i387"
17136   [(set (match_operand:DF 0 "register_operand" "=f,f")
17137         (match_operator:DF 3 "binary_fp_operator"
17138            [(float_extend:DF
17139              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
17140             (match_operand:DF 2 "register_operand" "0,f")]))]
17141   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17142    && !(TARGET_SSE2 && TARGET_SSE_MATH)
17143    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17144   "* return output_387_binary_op (insn, operands);"
17145   [(set (attr "type")
17146         (cond [(match_operand:DF 3 "mult_operator" "")
17147                  (const_string "fmul")
17148                (match_operand:DF 3 "div_operator" "")
17149                  (const_string "fdiv")
17150               ]
17151               (const_string "fop")))
17152    (set_attr "mode" "SF")])
17153
17154 (define_insn "*fop_df_5_i387"
17155   [(set (match_operand:DF 0 "register_operand" "=f,f")
17156         (match_operator:DF 3 "binary_fp_operator"
17157           [(match_operand:DF 1 "register_operand" "0,f")
17158            (float_extend:DF
17159             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17160   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17161    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17162   "* return output_387_binary_op (insn, operands);"
17163   [(set (attr "type")
17164         (cond [(match_operand:DF 3 "mult_operator" "")
17165                  (const_string "fmul")
17166                (match_operand:DF 3 "div_operator" "")
17167                  (const_string "fdiv")
17168               ]
17169               (const_string "fop")))
17170    (set_attr "mode" "SF")])
17171
17172 (define_insn "*fop_df_6_i387"
17173   [(set (match_operand:DF 0 "register_operand" "=f,f")
17174         (match_operator:DF 3 "binary_fp_operator"
17175           [(float_extend:DF
17176             (match_operand:SF 1 "register_operand" "0,f"))
17177            (float_extend:DF
17178             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17179   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17180    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17181   "* return output_387_binary_op (insn, operands);"
17182   [(set (attr "type")
17183         (cond [(match_operand:DF 3 "mult_operator" "")
17184                  (const_string "fmul")
17185                (match_operand:DF 3 "div_operator" "")
17186                  (const_string "fdiv")
17187               ]
17188               (const_string "fop")))
17189    (set_attr "mode" "SF")])
17190
17191 (define_insn "*fop_xf_comm_i387"
17192   [(set (match_operand:XF 0 "register_operand" "=f")
17193         (match_operator:XF 3 "binary_fp_operator"
17194                         [(match_operand:XF 1 "register_operand" "%0")
17195                          (match_operand:XF 2 "register_operand" "f")]))]
17196   "TARGET_80387
17197    && COMMUTATIVE_ARITH_P (operands[3])"
17198   "* return output_387_binary_op (insn, operands);"
17199   [(set (attr "type")
17200         (if_then_else (match_operand:XF 3 "mult_operator" "")
17201            (const_string "fmul")
17202            (const_string "fop")))
17203    (set_attr "mode" "XF")])
17204
17205 (define_insn "*fop_xf_1_i387"
17206   [(set (match_operand:XF 0 "register_operand" "=f,f")
17207         (match_operator:XF 3 "binary_fp_operator"
17208                         [(match_operand:XF 1 "register_operand" "0,f")
17209                          (match_operand:XF 2 "register_operand" "f,0")]))]
17210   "TARGET_80387
17211    && !COMMUTATIVE_ARITH_P (operands[3])"
17212   "* return output_387_binary_op (insn, operands);"
17213   [(set (attr "type")
17214         (cond [(match_operand:XF 3 "mult_operator" "")
17215                  (const_string "fmul")
17216                (match_operand:XF 3 "div_operator" "")
17217                  (const_string "fdiv")
17218               ]
17219               (const_string "fop")))
17220    (set_attr "mode" "XF")])
17221
17222 (define_insn "*fop_xf_2_i387"
17223   [(set (match_operand:XF 0 "register_operand" "=f,f")
17224         (match_operator:XF 3 "binary_fp_operator"
17225           [(float:XF
17226              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17227            (match_operand:XF 2 "register_operand" "0,0")]))]
17228   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17229   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17230   [(set (attr "type")
17231         (cond [(match_operand:XF 3 "mult_operator" "")
17232                  (const_string "fmul")
17233                (match_operand:XF 3 "div_operator" "")
17234                  (const_string "fdiv")
17235               ]
17236               (const_string "fop")))
17237    (set_attr "fp_int_src" "true")
17238    (set_attr "mode" "<MODE>")])
17239
17240 (define_insn "*fop_xf_3_i387"
17241   [(set (match_operand:XF 0 "register_operand" "=f,f")
17242         (match_operator:XF 3 "binary_fp_operator"
17243           [(match_operand:XF 1 "register_operand" "0,0")
17244            (float:XF
17245              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17246   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17247   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17248   [(set (attr "type")
17249         (cond [(match_operand:XF 3 "mult_operator" "")
17250                  (const_string "fmul")
17251                (match_operand:XF 3 "div_operator" "")
17252                  (const_string "fdiv")
17253               ]
17254               (const_string "fop")))
17255    (set_attr "fp_int_src" "true")
17256    (set_attr "mode" "<MODE>")])
17257
17258 (define_insn "*fop_xf_4_i387"
17259   [(set (match_operand:XF 0 "register_operand" "=f,f")
17260         (match_operator:XF 3 "binary_fp_operator"
17261            [(float_extend:XF
17262               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
17263             (match_operand:XF 2 "register_operand" "0,f")]))]
17264   "TARGET_80387"
17265   "* return output_387_binary_op (insn, operands);"
17266   [(set (attr "type")
17267         (cond [(match_operand:XF 3 "mult_operator" "")
17268                  (const_string "fmul")
17269                (match_operand:XF 3 "div_operator" "")
17270                  (const_string "fdiv")
17271               ]
17272               (const_string "fop")))
17273    (set_attr "mode" "<MODE>")])
17274
17275 (define_insn "*fop_xf_5_i387"
17276   [(set (match_operand:XF 0 "register_operand" "=f,f")
17277         (match_operator:XF 3 "binary_fp_operator"
17278           [(match_operand:XF 1 "register_operand" "0,f")
17279            (float_extend:XF
17280              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17281   "TARGET_80387"
17282   "* return output_387_binary_op (insn, operands);"
17283   [(set (attr "type")
17284         (cond [(match_operand:XF 3 "mult_operator" "")
17285                  (const_string "fmul")
17286                (match_operand:XF 3 "div_operator" "")
17287                  (const_string "fdiv")
17288               ]
17289               (const_string "fop")))
17290    (set_attr "mode" "<MODE>")])
17291
17292 (define_insn "*fop_xf_6_i387"
17293   [(set (match_operand:XF 0 "register_operand" "=f,f")
17294         (match_operator:XF 3 "binary_fp_operator"
17295           [(float_extend:XF
17296              (match_operand:MODEF 1 "register_operand" "0,f"))
17297            (float_extend:XF
17298              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17299   "TARGET_80387"
17300   "* return output_387_binary_op (insn, operands);"
17301   [(set (attr "type")
17302         (cond [(match_operand:XF 3 "mult_operator" "")
17303                  (const_string "fmul")
17304                (match_operand:XF 3 "div_operator" "")
17305                  (const_string "fdiv")
17306               ]
17307               (const_string "fop")))
17308    (set_attr "mode" "<MODE>")])
17309
17310 (define_split
17311   [(set (match_operand 0 "register_operand" "")
17312         (match_operator 3 "binary_fp_operator"
17313            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
17314             (match_operand 2 "register_operand" "")]))]
17315   "reload_completed
17316    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17317    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
17318   [(const_int 0)]
17319 {
17320   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17321   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17322   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17323                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17324                                           GET_MODE (operands[3]),
17325                                           operands[4],
17326                                           operands[2])));
17327   ix86_free_from_memory (GET_MODE (operands[1]));
17328   DONE;
17329 })
17330
17331 (define_split
17332   [(set (match_operand 0 "register_operand" "")
17333         (match_operator 3 "binary_fp_operator"
17334            [(match_operand 1 "register_operand" "")
17335             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
17336   "reload_completed
17337    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17338    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
17339   [(const_int 0)]
17340 {
17341   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17342   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17343   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17344                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17345                                           GET_MODE (operands[3]),
17346                                           operands[1],
17347                                           operands[4])));
17348   ix86_free_from_memory (GET_MODE (operands[2]));
17349   DONE;
17350 })
17351 \f
17352 ;; FPU special functions.
17353
17354 ;; This pattern implements a no-op XFmode truncation for
17355 ;; all fancy i386 XFmode math functions.
17356
17357 (define_insn "truncxf<mode>2_i387_noop_unspec"
17358   [(set (match_operand:MODEF 0 "register_operand" "=f")
17359         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
17360         UNSPEC_TRUNC_NOOP))]
17361   "TARGET_USE_FANCY_MATH_387"
17362   "* return output_387_reg_move (insn, operands);"
17363   [(set_attr "type" "fmov")
17364    (set_attr "mode" "<MODE>")])
17365
17366 (define_insn "sqrtxf2"
17367   [(set (match_operand:XF 0 "register_operand" "=f")
17368         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
17369   "TARGET_USE_FANCY_MATH_387"
17370   "fsqrt"
17371   [(set_attr "type" "fpspc")
17372    (set_attr "mode" "XF")
17373    (set_attr "athlon_decode" "direct")
17374    (set_attr "amdfam10_decode" "direct")])
17375
17376 (define_insn "sqrt_extend<mode>xf2_i387"
17377   [(set (match_operand:XF 0 "register_operand" "=f")
17378         (sqrt:XF
17379           (float_extend:XF
17380             (match_operand:MODEF 1 "register_operand" "0"))))]
17381   "TARGET_USE_FANCY_MATH_387"
17382   "fsqrt"
17383   [(set_attr "type" "fpspc")
17384    (set_attr "mode" "XF")
17385    (set_attr "athlon_decode" "direct")
17386    (set_attr "amdfam10_decode" "direct")])
17387
17388 (define_insn "*rsqrtsf2_sse"
17389   [(set (match_operand:SF 0 "register_operand" "=x")
17390         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17391                    UNSPEC_RSQRT))]
17392   "TARGET_SSE_MATH"
17393   "%vrsqrtss\t{%1, %d0|%d0, %1}"
17394   [(set_attr "type" "sse")
17395    (set_attr "atom_sse_attr" "rcp")
17396    (set_attr "prefix" "maybe_vex")
17397    (set_attr "mode" "SF")])
17398
17399 (define_expand "rsqrtsf2"
17400   [(set (match_operand:SF 0 "register_operand" "")
17401         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
17402                    UNSPEC_RSQRT))]
17403   "TARGET_SSE_MATH"
17404 {
17405   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17406   DONE;
17407 })
17408
17409 (define_insn "*sqrt<mode>2_sse"
17410   [(set (match_operand:MODEF 0 "register_operand" "=x")
17411         (sqrt:MODEF
17412           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17413   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17414   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17415   [(set_attr "type" "sse")
17416    (set_attr "atom_sse_attr" "sqrt")
17417    (set_attr "prefix" "maybe_vex")
17418    (set_attr "mode" "<MODE>")
17419    (set_attr "athlon_decode" "*")
17420    (set_attr "amdfam10_decode" "*")])
17421
17422 (define_expand "sqrt<mode>2"
17423   [(set (match_operand:MODEF 0 "register_operand" "")
17424         (sqrt:MODEF
17425           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17426   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17427    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17428 {
17429   if (<MODE>mode == SFmode
17430       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17431       && flag_finite_math_only && !flag_trapping_math
17432       && flag_unsafe_math_optimizations)
17433     {
17434       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17435       DONE;
17436     }
17437
17438   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17439     {
17440       rtx op0 = gen_reg_rtx (XFmode);
17441       rtx op1 = force_reg (<MODE>mode, operands[1]);
17442
17443       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17444       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17445       DONE;
17446    }
17447 })
17448
17449 (define_insn "fpremxf4_i387"
17450   [(set (match_operand:XF 0 "register_operand" "=f")
17451         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17452                     (match_operand:XF 3 "register_operand" "1")]
17453                    UNSPEC_FPREM_F))
17454    (set (match_operand:XF 1 "register_operand" "=u")
17455         (unspec:XF [(match_dup 2) (match_dup 3)]
17456                    UNSPEC_FPREM_U))
17457    (set (reg:CCFP FPSR_REG)
17458         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17459                      UNSPEC_C2_FLAG))]
17460   "TARGET_USE_FANCY_MATH_387"
17461   "fprem"
17462   [(set_attr "type" "fpspc")
17463    (set_attr "mode" "XF")])
17464
17465 (define_expand "fmodxf3"
17466   [(use (match_operand:XF 0 "register_operand" ""))
17467    (use (match_operand:XF 1 "general_operand" ""))
17468    (use (match_operand:XF 2 "general_operand" ""))]
17469   "TARGET_USE_FANCY_MATH_387"
17470 {
17471   rtx label = gen_label_rtx ();
17472
17473   rtx op1 = gen_reg_rtx (XFmode);
17474   rtx op2 = gen_reg_rtx (XFmode);
17475
17476   emit_move_insn (op2, operands[2]);
17477   emit_move_insn (op1, operands[1]);
17478
17479   emit_label (label);
17480   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17481   ix86_emit_fp_unordered_jump (label);
17482   LABEL_NUSES (label) = 1;
17483
17484   emit_move_insn (operands[0], op1);
17485   DONE;
17486 })
17487
17488 (define_expand "fmod<mode>3"
17489   [(use (match_operand:MODEF 0 "register_operand" ""))
17490    (use (match_operand:MODEF 1 "general_operand" ""))
17491    (use (match_operand:MODEF 2 "general_operand" ""))]
17492   "TARGET_USE_FANCY_MATH_387"
17493 {
17494   rtx label = gen_label_rtx ();
17495
17496   rtx op1 = gen_reg_rtx (XFmode);
17497   rtx op2 = gen_reg_rtx (XFmode);
17498
17499   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17500   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17501
17502   emit_label (label);
17503   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17504   ix86_emit_fp_unordered_jump (label);
17505   LABEL_NUSES (label) = 1;
17506
17507   /* Truncate the result properly for strict SSE math.  */
17508   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17509       && !TARGET_MIX_SSE_I387)
17510     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17511   else
17512     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17513
17514   DONE;
17515 })
17516
17517 (define_insn "fprem1xf4_i387"
17518   [(set (match_operand:XF 0 "register_operand" "=f")
17519         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17520                     (match_operand:XF 3 "register_operand" "1")]
17521                    UNSPEC_FPREM1_F))
17522    (set (match_operand:XF 1 "register_operand" "=u")
17523         (unspec:XF [(match_dup 2) (match_dup 3)]
17524                    UNSPEC_FPREM1_U))
17525    (set (reg:CCFP FPSR_REG)
17526         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17527                      UNSPEC_C2_FLAG))]
17528   "TARGET_USE_FANCY_MATH_387"
17529   "fprem1"
17530   [(set_attr "type" "fpspc")
17531    (set_attr "mode" "XF")])
17532
17533 (define_expand "remainderxf3"
17534   [(use (match_operand:XF 0 "register_operand" ""))
17535    (use (match_operand:XF 1 "general_operand" ""))
17536    (use (match_operand:XF 2 "general_operand" ""))]
17537   "TARGET_USE_FANCY_MATH_387"
17538 {
17539   rtx label = gen_label_rtx ();
17540
17541   rtx op1 = gen_reg_rtx (XFmode);
17542   rtx op2 = gen_reg_rtx (XFmode);
17543
17544   emit_move_insn (op2, operands[2]);
17545   emit_move_insn (op1, operands[1]);
17546
17547   emit_label (label);
17548   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17549   ix86_emit_fp_unordered_jump (label);
17550   LABEL_NUSES (label) = 1;
17551
17552   emit_move_insn (operands[0], op1);
17553   DONE;
17554 })
17555
17556 (define_expand "remainder<mode>3"
17557   [(use (match_operand:MODEF 0 "register_operand" ""))
17558    (use (match_operand:MODEF 1 "general_operand" ""))
17559    (use (match_operand:MODEF 2 "general_operand" ""))]
17560   "TARGET_USE_FANCY_MATH_387"
17561 {
17562   rtx label = gen_label_rtx ();
17563
17564   rtx op1 = gen_reg_rtx (XFmode);
17565   rtx op2 = gen_reg_rtx (XFmode);
17566
17567   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17568   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17569
17570   emit_label (label);
17571
17572   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17573   ix86_emit_fp_unordered_jump (label);
17574   LABEL_NUSES (label) = 1;
17575
17576   /* Truncate the result properly for strict SSE math.  */
17577   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17578       && !TARGET_MIX_SSE_I387)
17579     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17580   else
17581     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17582
17583   DONE;
17584 })
17585
17586 (define_insn "*sinxf2_i387"
17587   [(set (match_operand:XF 0 "register_operand" "=f")
17588         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17589   "TARGET_USE_FANCY_MATH_387
17590    && flag_unsafe_math_optimizations"
17591   "fsin"
17592   [(set_attr "type" "fpspc")
17593    (set_attr "mode" "XF")])
17594
17595 (define_insn "*sin_extend<mode>xf2_i387"
17596   [(set (match_operand:XF 0 "register_operand" "=f")
17597         (unspec:XF [(float_extend:XF
17598                       (match_operand:MODEF 1 "register_operand" "0"))]
17599                    UNSPEC_SIN))]
17600   "TARGET_USE_FANCY_MATH_387
17601    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17602        || TARGET_MIX_SSE_I387)
17603    && flag_unsafe_math_optimizations"
17604   "fsin"
17605   [(set_attr "type" "fpspc")
17606    (set_attr "mode" "XF")])
17607
17608 (define_insn "*cosxf2_i387"
17609   [(set (match_operand:XF 0 "register_operand" "=f")
17610         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17611   "TARGET_USE_FANCY_MATH_387
17612    && flag_unsafe_math_optimizations"
17613   "fcos"
17614   [(set_attr "type" "fpspc")
17615    (set_attr "mode" "XF")])
17616
17617 (define_insn "*cos_extend<mode>xf2_i387"
17618   [(set (match_operand:XF 0 "register_operand" "=f")
17619         (unspec:XF [(float_extend:XF
17620                       (match_operand:MODEF 1 "register_operand" "0"))]
17621                    UNSPEC_COS))]
17622   "TARGET_USE_FANCY_MATH_387
17623    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17624        || TARGET_MIX_SSE_I387)
17625    && flag_unsafe_math_optimizations"
17626   "fcos"
17627   [(set_attr "type" "fpspc")
17628    (set_attr "mode" "XF")])
17629
17630 ;; When sincos pattern is defined, sin and cos builtin functions will be
17631 ;; expanded to sincos pattern with one of its outputs left unused.
17632 ;; CSE pass will figure out if two sincos patterns can be combined,
17633 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17634 ;; depending on the unused output.
17635
17636 (define_insn "sincosxf3"
17637   [(set (match_operand:XF 0 "register_operand" "=f")
17638         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17639                    UNSPEC_SINCOS_COS))
17640    (set (match_operand:XF 1 "register_operand" "=u")
17641         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17642   "TARGET_USE_FANCY_MATH_387
17643    && flag_unsafe_math_optimizations"
17644   "fsincos"
17645   [(set_attr "type" "fpspc")
17646    (set_attr "mode" "XF")])
17647
17648 (define_split
17649   [(set (match_operand:XF 0 "register_operand" "")
17650         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17651                    UNSPEC_SINCOS_COS))
17652    (set (match_operand:XF 1 "register_operand" "")
17653         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17654   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17655    && !(reload_completed || reload_in_progress)"
17656   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17657   "")
17658
17659 (define_split
17660   [(set (match_operand:XF 0 "register_operand" "")
17661         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17662                    UNSPEC_SINCOS_COS))
17663    (set (match_operand:XF 1 "register_operand" "")
17664         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17665   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17666    && !(reload_completed || reload_in_progress)"
17667   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17668   "")
17669
17670 (define_insn "sincos_extend<mode>xf3_i387"
17671   [(set (match_operand:XF 0 "register_operand" "=f")
17672         (unspec:XF [(float_extend:XF
17673                       (match_operand:MODEF 2 "register_operand" "0"))]
17674                    UNSPEC_SINCOS_COS))
17675    (set (match_operand:XF 1 "register_operand" "=u")
17676         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17677   "TARGET_USE_FANCY_MATH_387
17678    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17679        || TARGET_MIX_SSE_I387)
17680    && flag_unsafe_math_optimizations"
17681   "fsincos"
17682   [(set_attr "type" "fpspc")
17683    (set_attr "mode" "XF")])
17684
17685 (define_split
17686   [(set (match_operand:XF 0 "register_operand" "")
17687         (unspec:XF [(float_extend:XF
17688                       (match_operand:MODEF 2 "register_operand" ""))]
17689                    UNSPEC_SINCOS_COS))
17690    (set (match_operand:XF 1 "register_operand" "")
17691         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17692   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17693    && !(reload_completed || reload_in_progress)"
17694   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17695   "")
17696
17697 (define_split
17698   [(set (match_operand:XF 0 "register_operand" "")
17699         (unspec:XF [(float_extend:XF
17700                       (match_operand:MODEF 2 "register_operand" ""))]
17701                    UNSPEC_SINCOS_COS))
17702    (set (match_operand:XF 1 "register_operand" "")
17703         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17704   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17705    && !(reload_completed || reload_in_progress)"
17706   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17707   "")
17708
17709 (define_expand "sincos<mode>3"
17710   [(use (match_operand:MODEF 0 "register_operand" ""))
17711    (use (match_operand:MODEF 1 "register_operand" ""))
17712    (use (match_operand:MODEF 2 "register_operand" ""))]
17713   "TARGET_USE_FANCY_MATH_387
17714    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17715        || TARGET_MIX_SSE_I387)
17716    && flag_unsafe_math_optimizations"
17717 {
17718   rtx op0 = gen_reg_rtx (XFmode);
17719   rtx op1 = gen_reg_rtx (XFmode);
17720
17721   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17722   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17723   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17724   DONE;
17725 })
17726
17727 (define_insn "fptanxf4_i387"
17728   [(set (match_operand:XF 0 "register_operand" "=f")
17729         (match_operand:XF 3 "const_double_operand" "F"))
17730    (set (match_operand:XF 1 "register_operand" "=u")
17731         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17732                    UNSPEC_TAN))]
17733   "TARGET_USE_FANCY_MATH_387
17734    && flag_unsafe_math_optimizations
17735    && standard_80387_constant_p (operands[3]) == 2"
17736   "fptan"
17737   [(set_attr "type" "fpspc")
17738    (set_attr "mode" "XF")])
17739
17740 (define_insn "fptan_extend<mode>xf4_i387"
17741   [(set (match_operand:MODEF 0 "register_operand" "=f")
17742         (match_operand:MODEF 3 "const_double_operand" "F"))
17743    (set (match_operand:XF 1 "register_operand" "=u")
17744         (unspec:XF [(float_extend:XF
17745                       (match_operand:MODEF 2 "register_operand" "0"))]
17746                    UNSPEC_TAN))]
17747   "TARGET_USE_FANCY_MATH_387
17748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17749        || TARGET_MIX_SSE_I387)
17750    && flag_unsafe_math_optimizations
17751    && standard_80387_constant_p (operands[3]) == 2"
17752   "fptan"
17753   [(set_attr "type" "fpspc")
17754    (set_attr "mode" "XF")])
17755
17756 (define_expand "tanxf2"
17757   [(use (match_operand:XF 0 "register_operand" ""))
17758    (use (match_operand:XF 1 "register_operand" ""))]
17759   "TARGET_USE_FANCY_MATH_387
17760    && flag_unsafe_math_optimizations"
17761 {
17762   rtx one = gen_reg_rtx (XFmode);
17763   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17764
17765   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17766   DONE;
17767 })
17768
17769 (define_expand "tan<mode>2"
17770   [(use (match_operand:MODEF 0 "register_operand" ""))
17771    (use (match_operand:MODEF 1 "register_operand" ""))]
17772   "TARGET_USE_FANCY_MATH_387
17773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17774        || TARGET_MIX_SSE_I387)
17775    && flag_unsafe_math_optimizations"
17776 {
17777   rtx op0 = gen_reg_rtx (XFmode);
17778
17779   rtx one = gen_reg_rtx (<MODE>mode);
17780   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17781
17782   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17783                                              operands[1], op2));
17784   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17785   DONE;
17786 })
17787
17788 (define_insn "*fpatanxf3_i387"
17789   [(set (match_operand:XF 0 "register_operand" "=f")
17790         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17791                     (match_operand:XF 2 "register_operand" "u")]
17792                    UNSPEC_FPATAN))
17793    (clobber (match_scratch:XF 3 "=2"))]
17794   "TARGET_USE_FANCY_MATH_387
17795    && flag_unsafe_math_optimizations"
17796   "fpatan"
17797   [(set_attr "type" "fpspc")
17798    (set_attr "mode" "XF")])
17799
17800 (define_insn "fpatan_extend<mode>xf3_i387"
17801   [(set (match_operand:XF 0 "register_operand" "=f")
17802         (unspec:XF [(float_extend:XF
17803                       (match_operand:MODEF 1 "register_operand" "0"))
17804                     (float_extend:XF
17805                       (match_operand:MODEF 2 "register_operand" "u"))]
17806                    UNSPEC_FPATAN))
17807    (clobber (match_scratch:XF 3 "=2"))]
17808   "TARGET_USE_FANCY_MATH_387
17809    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17810        || TARGET_MIX_SSE_I387)
17811    && flag_unsafe_math_optimizations"
17812   "fpatan"
17813   [(set_attr "type" "fpspc")
17814    (set_attr "mode" "XF")])
17815
17816 (define_expand "atan2xf3"
17817   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17818                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17819                                (match_operand:XF 1 "register_operand" "")]
17820                               UNSPEC_FPATAN))
17821               (clobber (match_scratch:XF 3 ""))])]
17822   "TARGET_USE_FANCY_MATH_387
17823    && flag_unsafe_math_optimizations"
17824   "")
17825
17826 (define_expand "atan2<mode>3"
17827   [(use (match_operand:MODEF 0 "register_operand" ""))
17828    (use (match_operand:MODEF 1 "register_operand" ""))
17829    (use (match_operand:MODEF 2 "register_operand" ""))]
17830   "TARGET_USE_FANCY_MATH_387
17831    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17832        || TARGET_MIX_SSE_I387)
17833    && flag_unsafe_math_optimizations"
17834 {
17835   rtx op0 = gen_reg_rtx (XFmode);
17836
17837   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17838   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17839   DONE;
17840 })
17841
17842 (define_expand "atanxf2"
17843   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17844                    (unspec:XF [(match_dup 2)
17845                                (match_operand:XF 1 "register_operand" "")]
17846                               UNSPEC_FPATAN))
17847               (clobber (match_scratch:XF 3 ""))])]
17848   "TARGET_USE_FANCY_MATH_387
17849    && flag_unsafe_math_optimizations"
17850 {
17851   operands[2] = gen_reg_rtx (XFmode);
17852   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17853 })
17854
17855 (define_expand "atan<mode>2"
17856   [(use (match_operand:MODEF 0 "register_operand" ""))
17857    (use (match_operand:MODEF 1 "register_operand" ""))]
17858   "TARGET_USE_FANCY_MATH_387
17859    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17860        || TARGET_MIX_SSE_I387)
17861    && flag_unsafe_math_optimizations"
17862 {
17863   rtx op0 = gen_reg_rtx (XFmode);
17864
17865   rtx op2 = gen_reg_rtx (<MODE>mode);
17866   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17867
17868   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17869   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17870   DONE;
17871 })
17872
17873 (define_expand "asinxf2"
17874   [(set (match_dup 2)
17875         (mult:XF (match_operand:XF 1 "register_operand" "")
17876                  (match_dup 1)))
17877    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17878    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17879    (parallel [(set (match_operand:XF 0 "register_operand" "")
17880                    (unspec:XF [(match_dup 5) (match_dup 1)]
17881                               UNSPEC_FPATAN))
17882               (clobber (match_scratch:XF 6 ""))])]
17883   "TARGET_USE_FANCY_MATH_387
17884    && flag_unsafe_math_optimizations"
17885 {
17886   int i;
17887
17888   if (optimize_insn_for_size_p ())
17889     FAIL;
17890
17891   for (i = 2; i < 6; i++)
17892     operands[i] = gen_reg_rtx (XFmode);
17893
17894   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17895 })
17896
17897 (define_expand "asin<mode>2"
17898   [(use (match_operand:MODEF 0 "register_operand" ""))
17899    (use (match_operand:MODEF 1 "general_operand" ""))]
17900  "TARGET_USE_FANCY_MATH_387
17901    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17902        || TARGET_MIX_SSE_I387)
17903    && flag_unsafe_math_optimizations"
17904 {
17905   rtx op0 = gen_reg_rtx (XFmode);
17906   rtx op1 = gen_reg_rtx (XFmode);
17907
17908   if (optimize_insn_for_size_p ())
17909     FAIL;
17910
17911   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17912   emit_insn (gen_asinxf2 (op0, op1));
17913   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17914   DONE;
17915 })
17916
17917 (define_expand "acosxf2"
17918   [(set (match_dup 2)
17919         (mult:XF (match_operand:XF 1 "register_operand" "")
17920                  (match_dup 1)))
17921    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17922    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17923    (parallel [(set (match_operand:XF 0 "register_operand" "")
17924                    (unspec:XF [(match_dup 1) (match_dup 5)]
17925                               UNSPEC_FPATAN))
17926               (clobber (match_scratch:XF 6 ""))])]
17927   "TARGET_USE_FANCY_MATH_387
17928    && flag_unsafe_math_optimizations"
17929 {
17930   int i;
17931
17932   if (optimize_insn_for_size_p ())
17933     FAIL;
17934
17935   for (i = 2; i < 6; i++)
17936     operands[i] = gen_reg_rtx (XFmode);
17937
17938   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17939 })
17940
17941 (define_expand "acos<mode>2"
17942   [(use (match_operand:MODEF 0 "register_operand" ""))
17943    (use (match_operand:MODEF 1 "general_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 = gen_reg_rtx (XFmode);
17950   rtx op1 = gen_reg_rtx (XFmode);
17951
17952   if (optimize_insn_for_size_p ())
17953     FAIL;
17954
17955   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17956   emit_insn (gen_acosxf2 (op0, op1));
17957   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17958   DONE;
17959 })
17960
17961 (define_insn "fyl2xxf3_i387"
17962   [(set (match_operand:XF 0 "register_operand" "=f")
17963         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17964                     (match_operand:XF 2 "register_operand" "u")]
17965                    UNSPEC_FYL2X))
17966    (clobber (match_scratch:XF 3 "=2"))]
17967   "TARGET_USE_FANCY_MATH_387
17968    && flag_unsafe_math_optimizations"
17969   "fyl2x"
17970   [(set_attr "type" "fpspc")
17971    (set_attr "mode" "XF")])
17972
17973 (define_insn "fyl2x_extend<mode>xf3_i387"
17974   [(set (match_operand:XF 0 "register_operand" "=f")
17975         (unspec:XF [(float_extend:XF
17976                       (match_operand:MODEF 1 "register_operand" "0"))
17977                     (match_operand:XF 2 "register_operand" "u")]
17978                    UNSPEC_FYL2X))
17979    (clobber (match_scratch:XF 3 "=2"))]
17980   "TARGET_USE_FANCY_MATH_387
17981    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17982        || TARGET_MIX_SSE_I387)
17983    && flag_unsafe_math_optimizations"
17984   "fyl2x"
17985   [(set_attr "type" "fpspc")
17986    (set_attr "mode" "XF")])
17987
17988 (define_expand "logxf2"
17989   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17990                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17991                                (match_dup 2)] UNSPEC_FYL2X))
17992               (clobber (match_scratch:XF 3 ""))])]
17993   "TARGET_USE_FANCY_MATH_387
17994    && flag_unsafe_math_optimizations"
17995 {
17996   operands[2] = gen_reg_rtx (XFmode);
17997   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17998 })
17999
18000 (define_expand "log<mode>2"
18001   [(use (match_operand:MODEF 0 "register_operand" ""))
18002    (use (match_operand:MODEF 1 "register_operand" ""))]
18003   "TARGET_USE_FANCY_MATH_387
18004    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18005        || TARGET_MIX_SSE_I387)
18006    && flag_unsafe_math_optimizations"
18007 {
18008   rtx op0 = gen_reg_rtx (XFmode);
18009
18010   rtx op2 = gen_reg_rtx (XFmode);
18011   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
18012
18013   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
18014   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18015   DONE;
18016 })
18017
18018 (define_expand "log10xf2"
18019   [(parallel [(set (match_operand:XF 0 "register_operand" "")
18020                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18021                                (match_dup 2)] UNSPEC_FYL2X))
18022               (clobber (match_scratch:XF 3 ""))])]
18023   "TARGET_USE_FANCY_MATH_387
18024    && flag_unsafe_math_optimizations"
18025 {
18026   operands[2] = gen_reg_rtx (XFmode);
18027   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
18028 })
18029
18030 (define_expand "log10<mode>2"
18031   [(use (match_operand:MODEF 0 "register_operand" ""))
18032    (use (match_operand:MODEF 1 "register_operand" ""))]
18033   "TARGET_USE_FANCY_MATH_387
18034    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18035        || TARGET_MIX_SSE_I387)
18036    && flag_unsafe_math_optimizations"
18037 {
18038   rtx op0 = gen_reg_rtx (XFmode);
18039
18040   rtx op2 = gen_reg_rtx (XFmode);
18041   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
18042
18043   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
18044   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18045   DONE;
18046 })
18047
18048 (define_expand "log2xf2"
18049   [(parallel [(set (match_operand:XF 0 "register_operand" "")
18050                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18051                                (match_dup 2)] UNSPEC_FYL2X))
18052               (clobber (match_scratch:XF 3 ""))])]
18053   "TARGET_USE_FANCY_MATH_387
18054    && flag_unsafe_math_optimizations"
18055 {
18056   operands[2] = gen_reg_rtx (XFmode);
18057   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
18058 })
18059
18060 (define_expand "log2<mode>2"
18061   [(use (match_operand:MODEF 0 "register_operand" ""))
18062    (use (match_operand:MODEF 1 "register_operand" ""))]
18063   "TARGET_USE_FANCY_MATH_387
18064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18065        || TARGET_MIX_SSE_I387)
18066    && flag_unsafe_math_optimizations"
18067 {
18068   rtx op0 = gen_reg_rtx (XFmode);
18069
18070   rtx op2 = gen_reg_rtx (XFmode);
18071   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
18072
18073   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
18074   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18075   DONE;
18076 })
18077
18078 (define_insn "fyl2xp1xf3_i387"
18079   [(set (match_operand:XF 0 "register_operand" "=f")
18080         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
18081                     (match_operand:XF 2 "register_operand" "u")]
18082                    UNSPEC_FYL2XP1))
18083    (clobber (match_scratch:XF 3 "=2"))]
18084   "TARGET_USE_FANCY_MATH_387
18085    && flag_unsafe_math_optimizations"
18086   "fyl2xp1"
18087   [(set_attr "type" "fpspc")
18088    (set_attr "mode" "XF")])
18089
18090 (define_insn "fyl2xp1_extend<mode>xf3_i387"
18091   [(set (match_operand:XF 0 "register_operand" "=f")
18092         (unspec:XF [(float_extend:XF
18093                       (match_operand:MODEF 1 "register_operand" "0"))
18094                     (match_operand:XF 2 "register_operand" "u")]
18095                    UNSPEC_FYL2XP1))
18096    (clobber (match_scratch:XF 3 "=2"))]
18097   "TARGET_USE_FANCY_MATH_387
18098    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18099        || TARGET_MIX_SSE_I387)
18100    && flag_unsafe_math_optimizations"
18101   "fyl2xp1"
18102   [(set_attr "type" "fpspc")
18103    (set_attr "mode" "XF")])
18104
18105 (define_expand "log1pxf2"
18106   [(use (match_operand:XF 0 "register_operand" ""))
18107    (use (match_operand:XF 1 "register_operand" ""))]
18108   "TARGET_USE_FANCY_MATH_387
18109    && flag_unsafe_math_optimizations"
18110 {
18111   if (optimize_insn_for_size_p ())
18112     FAIL;
18113
18114   ix86_emit_i387_log1p (operands[0], operands[1]);
18115   DONE;
18116 })
18117
18118 (define_expand "log1p<mode>2"
18119   [(use (match_operand:MODEF 0 "register_operand" ""))
18120    (use (match_operand:MODEF 1 "register_operand" ""))]
18121   "TARGET_USE_FANCY_MATH_387
18122    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18123        || TARGET_MIX_SSE_I387)
18124    && flag_unsafe_math_optimizations"
18125 {
18126   rtx op0;
18127
18128   if (optimize_insn_for_size_p ())
18129     FAIL;
18130
18131   op0 = gen_reg_rtx (XFmode);
18132
18133   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
18134
18135   ix86_emit_i387_log1p (op0, operands[1]);
18136   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18137   DONE;
18138 })
18139
18140 (define_insn "fxtractxf3_i387"
18141   [(set (match_operand:XF 0 "register_operand" "=f")
18142         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
18143                    UNSPEC_XTRACT_FRACT))
18144    (set (match_operand:XF 1 "register_operand" "=u")
18145         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
18146   "TARGET_USE_FANCY_MATH_387
18147    && flag_unsafe_math_optimizations"
18148   "fxtract"
18149   [(set_attr "type" "fpspc")
18150    (set_attr "mode" "XF")])
18151
18152 (define_insn "fxtract_extend<mode>xf3_i387"
18153   [(set (match_operand:XF 0 "register_operand" "=f")
18154         (unspec:XF [(float_extend:XF
18155                       (match_operand:MODEF 2 "register_operand" "0"))]
18156                    UNSPEC_XTRACT_FRACT))
18157    (set (match_operand:XF 1 "register_operand" "=u")
18158         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
18159   "TARGET_USE_FANCY_MATH_387
18160    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18161        || TARGET_MIX_SSE_I387)
18162    && flag_unsafe_math_optimizations"
18163   "fxtract"
18164   [(set_attr "type" "fpspc")
18165    (set_attr "mode" "XF")])
18166
18167 (define_expand "logbxf2"
18168   [(parallel [(set (match_dup 2)
18169                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18170                               UNSPEC_XTRACT_FRACT))
18171               (set (match_operand:XF 0 "register_operand" "")
18172                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18173   "TARGET_USE_FANCY_MATH_387
18174    && flag_unsafe_math_optimizations"
18175 {
18176   operands[2] = gen_reg_rtx (XFmode);
18177 })
18178
18179 (define_expand "logb<mode>2"
18180   [(use (match_operand:MODEF 0 "register_operand" ""))
18181    (use (match_operand:MODEF 1 "register_operand" ""))]
18182   "TARGET_USE_FANCY_MATH_387
18183    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18184        || TARGET_MIX_SSE_I387)
18185    && flag_unsafe_math_optimizations"
18186 {
18187   rtx op0 = gen_reg_rtx (XFmode);
18188   rtx op1 = gen_reg_rtx (XFmode);
18189
18190   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18191   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
18192   DONE;
18193 })
18194
18195 (define_expand "ilogbxf2"
18196   [(use (match_operand:SI 0 "register_operand" ""))
18197    (use (match_operand:XF 1 "register_operand" ""))]
18198   "TARGET_USE_FANCY_MATH_387
18199    && flag_unsafe_math_optimizations"
18200 {
18201   rtx op0, op1;
18202
18203   if (optimize_insn_for_size_p ())
18204     FAIL;
18205
18206   op0 = gen_reg_rtx (XFmode);
18207   op1 = gen_reg_rtx (XFmode);
18208
18209   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18210   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18211   DONE;
18212 })
18213
18214 (define_expand "ilogb<mode>2"
18215   [(use (match_operand:SI 0 "register_operand" ""))
18216    (use (match_operand:MODEF 1 "register_operand" ""))]
18217   "TARGET_USE_FANCY_MATH_387
18218    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18219        || TARGET_MIX_SSE_I387)
18220    && flag_unsafe_math_optimizations"
18221 {
18222   rtx op0, op1;
18223
18224   if (optimize_insn_for_size_p ())
18225     FAIL;
18226
18227   op0 = gen_reg_rtx (XFmode);
18228   op1 = gen_reg_rtx (XFmode);
18229
18230   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18231   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18232   DONE;
18233 })
18234
18235 (define_insn "*f2xm1xf2_i387"
18236   [(set (match_operand:XF 0 "register_operand" "=f")
18237         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18238                    UNSPEC_F2XM1))]
18239   "TARGET_USE_FANCY_MATH_387
18240    && flag_unsafe_math_optimizations"
18241   "f2xm1"
18242   [(set_attr "type" "fpspc")
18243    (set_attr "mode" "XF")])
18244
18245 (define_insn "*fscalexf4_i387"
18246   [(set (match_operand:XF 0 "register_operand" "=f")
18247         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18248                     (match_operand:XF 3 "register_operand" "1")]
18249                    UNSPEC_FSCALE_FRACT))
18250    (set (match_operand:XF 1 "register_operand" "=u")
18251         (unspec:XF [(match_dup 2) (match_dup 3)]
18252                    UNSPEC_FSCALE_EXP))]
18253   "TARGET_USE_FANCY_MATH_387
18254    && flag_unsafe_math_optimizations"
18255   "fscale"
18256   [(set_attr "type" "fpspc")
18257    (set_attr "mode" "XF")])
18258
18259 (define_expand "expNcorexf3"
18260   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18261                                (match_operand:XF 2 "register_operand" "")))
18262    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18263    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18264    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18265    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18266    (parallel [(set (match_operand:XF 0 "register_operand" "")
18267                    (unspec:XF [(match_dup 8) (match_dup 4)]
18268                               UNSPEC_FSCALE_FRACT))
18269               (set (match_dup 9)
18270                    (unspec:XF [(match_dup 8) (match_dup 4)]
18271                               UNSPEC_FSCALE_EXP))])]
18272   "TARGET_USE_FANCY_MATH_387
18273    && flag_unsafe_math_optimizations"
18274 {
18275   int i;
18276
18277   if (optimize_insn_for_size_p ())
18278     FAIL;
18279
18280   for (i = 3; i < 10; i++)
18281     operands[i] = gen_reg_rtx (XFmode);
18282
18283   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
18284 })
18285
18286 (define_expand "expxf2"
18287   [(use (match_operand:XF 0 "register_operand" ""))
18288    (use (match_operand:XF 1 "register_operand" ""))]
18289   "TARGET_USE_FANCY_MATH_387
18290    && flag_unsafe_math_optimizations"
18291 {
18292   rtx op2;
18293
18294   if (optimize_insn_for_size_p ())
18295     FAIL;
18296
18297   op2 = gen_reg_rtx (XFmode);
18298   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
18299
18300   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18301   DONE;
18302 })
18303
18304 (define_expand "exp<mode>2"
18305   [(use (match_operand:MODEF 0 "register_operand" ""))
18306    (use (match_operand:MODEF 1 "general_operand" ""))]
18307  "TARGET_USE_FANCY_MATH_387
18308    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18309        || TARGET_MIX_SSE_I387)
18310    && flag_unsafe_math_optimizations"
18311 {
18312   rtx op0, op1;
18313
18314   if (optimize_insn_for_size_p ())
18315     FAIL;
18316
18317   op0 = gen_reg_rtx (XFmode);
18318   op1 = gen_reg_rtx (XFmode);
18319
18320   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18321   emit_insn (gen_expxf2 (op0, op1));
18322   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18323   DONE;
18324 })
18325
18326 (define_expand "exp10xf2"
18327   [(use (match_operand:XF 0 "register_operand" ""))
18328    (use (match_operand:XF 1 "register_operand" ""))]
18329   "TARGET_USE_FANCY_MATH_387
18330    && flag_unsafe_math_optimizations"
18331 {
18332   rtx op2;
18333
18334   if (optimize_insn_for_size_p ())
18335     FAIL;
18336
18337   op2 = gen_reg_rtx (XFmode);
18338   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
18339
18340   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18341   DONE;
18342 })
18343
18344 (define_expand "exp10<mode>2"
18345   [(use (match_operand:MODEF 0 "register_operand" ""))
18346    (use (match_operand:MODEF 1 "general_operand" ""))]
18347  "TARGET_USE_FANCY_MATH_387
18348    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18349        || TARGET_MIX_SSE_I387)
18350    && flag_unsafe_math_optimizations"
18351 {
18352   rtx op0, op1;
18353
18354   if (optimize_insn_for_size_p ())
18355     FAIL;
18356
18357   op0 = gen_reg_rtx (XFmode);
18358   op1 = gen_reg_rtx (XFmode);
18359
18360   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18361   emit_insn (gen_exp10xf2 (op0, op1));
18362   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18363   DONE;
18364 })
18365
18366 (define_expand "exp2xf2"
18367   [(use (match_operand:XF 0 "register_operand" ""))
18368    (use (match_operand:XF 1 "register_operand" ""))]
18369   "TARGET_USE_FANCY_MATH_387
18370    && flag_unsafe_math_optimizations"
18371 {
18372   rtx op2;
18373
18374   if (optimize_insn_for_size_p ())
18375     FAIL;
18376
18377   op2 = gen_reg_rtx (XFmode);
18378   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
18379
18380   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18381   DONE;
18382 })
18383
18384 (define_expand "exp2<mode>2"
18385   [(use (match_operand:MODEF 0 "register_operand" ""))
18386    (use (match_operand:MODEF 1 "general_operand" ""))]
18387  "TARGET_USE_FANCY_MATH_387
18388    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18389        || TARGET_MIX_SSE_I387)
18390    && flag_unsafe_math_optimizations"
18391 {
18392   rtx op0, op1;
18393
18394   if (optimize_insn_for_size_p ())
18395     FAIL;
18396
18397   op0 = gen_reg_rtx (XFmode);
18398   op1 = gen_reg_rtx (XFmode);
18399
18400   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18401   emit_insn (gen_exp2xf2 (op0, op1));
18402   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18403   DONE;
18404 })
18405
18406 (define_expand "expm1xf2"
18407   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18408                                (match_dup 2)))
18409    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18410    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18411    (set (match_dup 9) (float_extend:XF (match_dup 13)))
18412    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18413    (parallel [(set (match_dup 7)
18414                    (unspec:XF [(match_dup 6) (match_dup 4)]
18415                               UNSPEC_FSCALE_FRACT))
18416               (set (match_dup 8)
18417                    (unspec:XF [(match_dup 6) (match_dup 4)]
18418                               UNSPEC_FSCALE_EXP))])
18419    (parallel [(set (match_dup 10)
18420                    (unspec:XF [(match_dup 9) (match_dup 8)]
18421                               UNSPEC_FSCALE_FRACT))
18422               (set (match_dup 11)
18423                    (unspec:XF [(match_dup 9) (match_dup 8)]
18424                               UNSPEC_FSCALE_EXP))])
18425    (set (match_dup 12) (minus:XF (match_dup 10)
18426                                  (float_extend:XF (match_dup 13))))
18427    (set (match_operand:XF 0 "register_operand" "")
18428         (plus:XF (match_dup 12) (match_dup 7)))]
18429   "TARGET_USE_FANCY_MATH_387
18430    && flag_unsafe_math_optimizations"
18431 {
18432   int i;
18433
18434   if (optimize_insn_for_size_p ())
18435     FAIL;
18436
18437   for (i = 2; i < 13; i++)
18438     operands[i] = gen_reg_rtx (XFmode);
18439
18440   operands[13]
18441     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18442
18443   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18444 })
18445
18446 (define_expand "expm1<mode>2"
18447   [(use (match_operand:MODEF 0 "register_operand" ""))
18448    (use (match_operand:MODEF 1 "general_operand" ""))]
18449  "TARGET_USE_FANCY_MATH_387
18450    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18451        || TARGET_MIX_SSE_I387)
18452    && flag_unsafe_math_optimizations"
18453 {
18454   rtx op0, op1;
18455
18456   if (optimize_insn_for_size_p ())
18457     FAIL;
18458
18459   op0 = gen_reg_rtx (XFmode);
18460   op1 = gen_reg_rtx (XFmode);
18461
18462   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18463   emit_insn (gen_expm1xf2 (op0, op1));
18464   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18465   DONE;
18466 })
18467
18468 (define_expand "ldexpxf3"
18469   [(set (match_dup 3)
18470         (float:XF (match_operand:SI 2 "register_operand" "")))
18471    (parallel [(set (match_operand:XF 0 " register_operand" "")
18472                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18473                                (match_dup 3)]
18474                               UNSPEC_FSCALE_FRACT))
18475               (set (match_dup 4)
18476                    (unspec:XF [(match_dup 1) (match_dup 3)]
18477                               UNSPEC_FSCALE_EXP))])]
18478   "TARGET_USE_FANCY_MATH_387
18479    && flag_unsafe_math_optimizations"
18480 {
18481   if (optimize_insn_for_size_p ())
18482     FAIL;
18483
18484   operands[3] = gen_reg_rtx (XFmode);
18485   operands[4] = gen_reg_rtx (XFmode);
18486 })
18487
18488 (define_expand "ldexp<mode>3"
18489   [(use (match_operand:MODEF 0 "register_operand" ""))
18490    (use (match_operand:MODEF 1 "general_operand" ""))
18491    (use (match_operand:SI 2 "register_operand" ""))]
18492  "TARGET_USE_FANCY_MATH_387
18493    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18494        || TARGET_MIX_SSE_I387)
18495    && flag_unsafe_math_optimizations"
18496 {
18497   rtx op0, op1;
18498
18499   if (optimize_insn_for_size_p ())
18500     FAIL;
18501
18502   op0 = gen_reg_rtx (XFmode);
18503   op1 = gen_reg_rtx (XFmode);
18504
18505   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18506   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18507   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18508   DONE;
18509 })
18510
18511 (define_expand "scalbxf3"
18512   [(parallel [(set (match_operand:XF 0 " register_operand" "")
18513                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18514                                (match_operand:XF 2 "register_operand" "")]
18515                               UNSPEC_FSCALE_FRACT))
18516               (set (match_dup 3)
18517                    (unspec:XF [(match_dup 1) (match_dup 2)]
18518                               UNSPEC_FSCALE_EXP))])]
18519   "TARGET_USE_FANCY_MATH_387
18520    && flag_unsafe_math_optimizations"
18521 {
18522   if (optimize_insn_for_size_p ())
18523     FAIL;
18524
18525   operands[3] = gen_reg_rtx (XFmode);
18526 })
18527
18528 (define_expand "scalb<mode>3"
18529   [(use (match_operand:MODEF 0 "register_operand" ""))
18530    (use (match_operand:MODEF 1 "general_operand" ""))
18531    (use (match_operand:MODEF 2 "register_operand" ""))]
18532  "TARGET_USE_FANCY_MATH_387
18533    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18534        || TARGET_MIX_SSE_I387)
18535    && flag_unsafe_math_optimizations"
18536 {
18537   rtx op0, op1, op2;
18538
18539   if (optimize_insn_for_size_p ())
18540     FAIL;
18541
18542   op0 = gen_reg_rtx (XFmode);
18543   op1 = gen_reg_rtx (XFmode);
18544   op2 = gen_reg_rtx (XFmode);
18545
18546   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18547   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18548   emit_insn (gen_scalbxf3 (op0, op1, op2));
18549   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18550   DONE;
18551 })
18552 \f
18553
18554 (define_insn "sse4_1_round<mode>2"
18555   [(set (match_operand:MODEF 0 "register_operand" "=x")
18556         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18557                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
18558                       UNSPEC_ROUND))]
18559   "TARGET_ROUND"
18560   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18561   [(set_attr "type" "ssecvt")
18562    (set_attr "prefix_extra" "1")
18563    (set_attr "prefix" "maybe_vex")
18564    (set_attr "mode" "<MODE>")])
18565
18566 (define_insn "rintxf2"
18567   [(set (match_operand:XF 0 "register_operand" "=f")
18568         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18569                    UNSPEC_FRNDINT))]
18570   "TARGET_USE_FANCY_MATH_387
18571    && flag_unsafe_math_optimizations"
18572   "frndint"
18573   [(set_attr "type" "fpspc")
18574    (set_attr "mode" "XF")])
18575
18576 (define_expand "rint<mode>2"
18577   [(use (match_operand:MODEF 0 "register_operand" ""))
18578    (use (match_operand:MODEF 1 "register_operand" ""))]
18579   "(TARGET_USE_FANCY_MATH_387
18580     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18581         || TARGET_MIX_SSE_I387)
18582     && flag_unsafe_math_optimizations)
18583    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18584        && !flag_trapping_math)"
18585 {
18586   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18587       && !flag_trapping_math)
18588     {
18589       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18590         FAIL;
18591       if (TARGET_ROUND)
18592         emit_insn (gen_sse4_1_round<mode>2
18593                    (operands[0], operands[1], GEN_INT (0x04)));
18594       else
18595         ix86_expand_rint (operand0, operand1);
18596     }
18597   else
18598     {
18599       rtx op0 = gen_reg_rtx (XFmode);
18600       rtx op1 = gen_reg_rtx (XFmode);
18601
18602       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18603       emit_insn (gen_rintxf2 (op0, op1));
18604
18605       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18606     }
18607   DONE;
18608 })
18609
18610 (define_expand "round<mode>2"
18611   [(match_operand:MODEF 0 "register_operand" "")
18612    (match_operand:MODEF 1 "nonimmediate_operand" "")]
18613   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18614    && !flag_trapping_math && !flag_rounding_math"
18615 {
18616   if (optimize_insn_for_size_p ())
18617     FAIL;
18618   if (TARGET_64BIT || (<MODE>mode != DFmode))
18619     ix86_expand_round (operand0, operand1);
18620   else
18621     ix86_expand_rounddf_32 (operand0, operand1);
18622   DONE;
18623 })
18624
18625 (define_insn_and_split "*fistdi2_1"
18626   [(set (match_operand:DI 0 "nonimmediate_operand" "")
18627         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18628                    UNSPEC_FIST))]
18629   "TARGET_USE_FANCY_MATH_387
18630    && !(reload_completed || reload_in_progress)"
18631   "#"
18632   "&& 1"
18633   [(const_int 0)]
18634 {
18635   if (memory_operand (operands[0], VOIDmode))
18636     emit_insn (gen_fistdi2 (operands[0], operands[1]));
18637   else
18638     {
18639       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18640       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18641                                          operands[2]));
18642     }
18643   DONE;
18644 }
18645   [(set_attr "type" "fpspc")
18646    (set_attr "mode" "DI")])
18647
18648 (define_insn "fistdi2"
18649   [(set (match_operand:DI 0 "memory_operand" "=m")
18650         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18651                    UNSPEC_FIST))
18652    (clobber (match_scratch:XF 2 "=&1f"))]
18653   "TARGET_USE_FANCY_MATH_387"
18654   "* return output_fix_trunc (insn, operands, 0);"
18655   [(set_attr "type" "fpspc")
18656    (set_attr "mode" "DI")])
18657
18658 (define_insn "fistdi2_with_temp"
18659   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18660         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18661                    UNSPEC_FIST))
18662    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18663    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18664   "TARGET_USE_FANCY_MATH_387"
18665   "#"
18666   [(set_attr "type" "fpspc")
18667    (set_attr "mode" "DI")])
18668
18669 (define_split
18670   [(set (match_operand:DI 0 "register_operand" "")
18671         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18672                    UNSPEC_FIST))
18673    (clobber (match_operand:DI 2 "memory_operand" ""))
18674    (clobber (match_scratch 3 ""))]
18675   "reload_completed"
18676   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18677               (clobber (match_dup 3))])
18678    (set (match_dup 0) (match_dup 2))]
18679   "")
18680
18681 (define_split
18682   [(set (match_operand:DI 0 "memory_operand" "")
18683         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18684                    UNSPEC_FIST))
18685    (clobber (match_operand:DI 2 "memory_operand" ""))
18686    (clobber (match_scratch 3 ""))]
18687   "reload_completed"
18688   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18689               (clobber (match_dup 3))])]
18690   "")
18691
18692 (define_insn_and_split "*fist<mode>2_1"
18693   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18694         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18695                            UNSPEC_FIST))]
18696   "TARGET_USE_FANCY_MATH_387
18697    && !(reload_completed || reload_in_progress)"
18698   "#"
18699   "&& 1"
18700   [(const_int 0)]
18701 {
18702   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18703   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18704                                         operands[2]));
18705   DONE;
18706 }
18707   [(set_attr "type" "fpspc")
18708    (set_attr "mode" "<MODE>")])
18709
18710 (define_insn "fist<mode>2"
18711   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18712         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18713                            UNSPEC_FIST))]
18714   "TARGET_USE_FANCY_MATH_387"
18715   "* return output_fix_trunc (insn, operands, 0);"
18716   [(set_attr "type" "fpspc")
18717    (set_attr "mode" "<MODE>")])
18718
18719 (define_insn "fist<mode>2_with_temp"
18720   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18721         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18722                            UNSPEC_FIST))
18723    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18724   "TARGET_USE_FANCY_MATH_387"
18725   "#"
18726   [(set_attr "type" "fpspc")
18727    (set_attr "mode" "<MODE>")])
18728
18729 (define_split
18730   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18731         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18732                            UNSPEC_FIST))
18733    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18734   "reload_completed"
18735   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18736    (set (match_dup 0) (match_dup 2))]
18737   "")
18738
18739 (define_split
18740   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18741         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18742                            UNSPEC_FIST))
18743    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18744   "reload_completed"
18745   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18746   "")
18747
18748 (define_expand "lrintxf<mode>2"
18749   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18750      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18751                       UNSPEC_FIST))]
18752   "TARGET_USE_FANCY_MATH_387"
18753   "")
18754
18755 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18756   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18757      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18758                         UNSPEC_FIX_NOTRUNC))]
18759   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18760    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18761   "")
18762
18763 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18764   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18765    (match_operand:MODEF 1 "register_operand" "")]
18766   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18767    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18768    && !flag_trapping_math && !flag_rounding_math"
18769 {
18770   if (optimize_insn_for_size_p ())
18771     FAIL;
18772   ix86_expand_lround (operand0, operand1);
18773   DONE;
18774 })
18775
18776 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18777 (define_insn_and_split "frndintxf2_floor"
18778   [(set (match_operand:XF 0 "register_operand" "")
18779         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18780          UNSPEC_FRNDINT_FLOOR))
18781    (clobber (reg:CC FLAGS_REG))]
18782   "TARGET_USE_FANCY_MATH_387
18783    && flag_unsafe_math_optimizations
18784    && !(reload_completed || reload_in_progress)"
18785   "#"
18786   "&& 1"
18787   [(const_int 0)]
18788 {
18789   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18790
18791   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18792   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18793
18794   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18795                                         operands[2], operands[3]));
18796   DONE;
18797 }
18798   [(set_attr "type" "frndint")
18799    (set_attr "i387_cw" "floor")
18800    (set_attr "mode" "XF")])
18801
18802 (define_insn "frndintxf2_floor_i387"
18803   [(set (match_operand:XF 0 "register_operand" "=f")
18804         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18805          UNSPEC_FRNDINT_FLOOR))
18806    (use (match_operand:HI 2 "memory_operand" "m"))
18807    (use (match_operand:HI 3 "memory_operand" "m"))]
18808   "TARGET_USE_FANCY_MATH_387
18809    && flag_unsafe_math_optimizations"
18810   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18811   [(set_attr "type" "frndint")
18812    (set_attr "i387_cw" "floor")
18813    (set_attr "mode" "XF")])
18814
18815 (define_expand "floorxf2"
18816   [(use (match_operand:XF 0 "register_operand" ""))
18817    (use (match_operand:XF 1 "register_operand" ""))]
18818   "TARGET_USE_FANCY_MATH_387
18819    && flag_unsafe_math_optimizations"
18820 {
18821   if (optimize_insn_for_size_p ())
18822     FAIL;
18823   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18824   DONE;
18825 })
18826
18827 (define_expand "floor<mode>2"
18828   [(use (match_operand:MODEF 0 "register_operand" ""))
18829    (use (match_operand:MODEF 1 "register_operand" ""))]
18830   "(TARGET_USE_FANCY_MATH_387
18831     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18832         || TARGET_MIX_SSE_I387)
18833     && flag_unsafe_math_optimizations)
18834    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18835        && !flag_trapping_math)"
18836 {
18837   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18838       && !flag_trapping_math
18839       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18840     {
18841       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18842         FAIL;
18843       if (TARGET_ROUND)
18844         emit_insn (gen_sse4_1_round<mode>2
18845                    (operands[0], operands[1], GEN_INT (0x01)));
18846       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18847         ix86_expand_floorceil (operand0, operand1, true);
18848       else
18849         ix86_expand_floorceildf_32 (operand0, operand1, true);
18850     }
18851   else
18852     {
18853       rtx op0, op1;
18854
18855       if (optimize_insn_for_size_p ())
18856         FAIL;
18857
18858       op0 = gen_reg_rtx (XFmode);
18859       op1 = gen_reg_rtx (XFmode);
18860       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18861       emit_insn (gen_frndintxf2_floor (op0, op1));
18862
18863       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18864     }
18865   DONE;
18866 })
18867
18868 (define_insn_and_split "*fist<mode>2_floor_1"
18869   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18870         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18871          UNSPEC_FIST_FLOOR))
18872    (clobber (reg:CC FLAGS_REG))]
18873   "TARGET_USE_FANCY_MATH_387
18874    && flag_unsafe_math_optimizations
18875    && !(reload_completed || reload_in_progress)"
18876   "#"
18877   "&& 1"
18878   [(const_int 0)]
18879 {
18880   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18881
18882   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18883   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18884   if (memory_operand (operands[0], VOIDmode))
18885     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18886                                       operands[2], operands[3]));
18887   else
18888     {
18889       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18890       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18891                                                   operands[2], operands[3],
18892                                                   operands[4]));
18893     }
18894   DONE;
18895 }
18896   [(set_attr "type" "fistp")
18897    (set_attr "i387_cw" "floor")
18898    (set_attr "mode" "<MODE>")])
18899
18900 (define_insn "fistdi2_floor"
18901   [(set (match_operand:DI 0 "memory_operand" "=m")
18902         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18903          UNSPEC_FIST_FLOOR))
18904    (use (match_operand:HI 2 "memory_operand" "m"))
18905    (use (match_operand:HI 3 "memory_operand" "m"))
18906    (clobber (match_scratch:XF 4 "=&1f"))]
18907   "TARGET_USE_FANCY_MATH_387
18908    && flag_unsafe_math_optimizations"
18909   "* return output_fix_trunc (insn, operands, 0);"
18910   [(set_attr "type" "fistp")
18911    (set_attr "i387_cw" "floor")
18912    (set_attr "mode" "DI")])
18913
18914 (define_insn "fistdi2_floor_with_temp"
18915   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18916         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18917          UNSPEC_FIST_FLOOR))
18918    (use (match_operand:HI 2 "memory_operand" "m,m"))
18919    (use (match_operand:HI 3 "memory_operand" "m,m"))
18920    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18921    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18922   "TARGET_USE_FANCY_MATH_387
18923    && flag_unsafe_math_optimizations"
18924   "#"
18925   [(set_attr "type" "fistp")
18926    (set_attr "i387_cw" "floor")
18927    (set_attr "mode" "DI")])
18928
18929 (define_split
18930   [(set (match_operand:DI 0 "register_operand" "")
18931         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18932          UNSPEC_FIST_FLOOR))
18933    (use (match_operand:HI 2 "memory_operand" ""))
18934    (use (match_operand:HI 3 "memory_operand" ""))
18935    (clobber (match_operand:DI 4 "memory_operand" ""))
18936    (clobber (match_scratch 5 ""))]
18937   "reload_completed"
18938   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18939               (use (match_dup 2))
18940               (use (match_dup 3))
18941               (clobber (match_dup 5))])
18942    (set (match_dup 0) (match_dup 4))]
18943   "")
18944
18945 (define_split
18946   [(set (match_operand:DI 0 "memory_operand" "")
18947         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18948          UNSPEC_FIST_FLOOR))
18949    (use (match_operand:HI 2 "memory_operand" ""))
18950    (use (match_operand:HI 3 "memory_operand" ""))
18951    (clobber (match_operand:DI 4 "memory_operand" ""))
18952    (clobber (match_scratch 5 ""))]
18953   "reload_completed"
18954   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18955               (use (match_dup 2))
18956               (use (match_dup 3))
18957               (clobber (match_dup 5))])]
18958   "")
18959
18960 (define_insn "fist<mode>2_floor"
18961   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18962         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18963          UNSPEC_FIST_FLOOR))
18964    (use (match_operand:HI 2 "memory_operand" "m"))
18965    (use (match_operand:HI 3 "memory_operand" "m"))]
18966   "TARGET_USE_FANCY_MATH_387
18967    && flag_unsafe_math_optimizations"
18968   "* return output_fix_trunc (insn, operands, 0);"
18969   [(set_attr "type" "fistp")
18970    (set_attr "i387_cw" "floor")
18971    (set_attr "mode" "<MODE>")])
18972
18973 (define_insn "fist<mode>2_floor_with_temp"
18974   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18975         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18976          UNSPEC_FIST_FLOOR))
18977    (use (match_operand:HI 2 "memory_operand" "m,m"))
18978    (use (match_operand:HI 3 "memory_operand" "m,m"))
18979    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18980   "TARGET_USE_FANCY_MATH_387
18981    && flag_unsafe_math_optimizations"
18982   "#"
18983   [(set_attr "type" "fistp")
18984    (set_attr "i387_cw" "floor")
18985    (set_attr "mode" "<MODE>")])
18986
18987 (define_split
18988   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18989         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18990          UNSPEC_FIST_FLOOR))
18991    (use (match_operand:HI 2 "memory_operand" ""))
18992    (use (match_operand:HI 3 "memory_operand" ""))
18993    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18994   "reload_completed"
18995   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18996                                   UNSPEC_FIST_FLOOR))
18997               (use (match_dup 2))
18998               (use (match_dup 3))])
18999    (set (match_dup 0) (match_dup 4))]
19000   "")
19001
19002 (define_split
19003   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19004         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19005          UNSPEC_FIST_FLOOR))
19006    (use (match_operand:HI 2 "memory_operand" ""))
19007    (use (match_operand:HI 3 "memory_operand" ""))
19008    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19009   "reload_completed"
19010   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19011                                   UNSPEC_FIST_FLOOR))
19012               (use (match_dup 2))
19013               (use (match_dup 3))])]
19014   "")
19015
19016 (define_expand "lfloorxf<mode>2"
19017   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19018                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19019                     UNSPEC_FIST_FLOOR))
19020               (clobber (reg:CC FLAGS_REG))])]
19021   "TARGET_USE_FANCY_MATH_387
19022    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19023    && flag_unsafe_math_optimizations"
19024   "")
19025
19026 (define_expand "lfloor<mode>di2"
19027   [(match_operand:DI 0 "nonimmediate_operand" "")
19028    (match_operand:MODEF 1 "register_operand" "")]
19029   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19030    && !flag_trapping_math"
19031 {
19032   if (optimize_insn_for_size_p ())
19033     FAIL;
19034   ix86_expand_lfloorceil (operand0, operand1, true);
19035   DONE;
19036 })
19037
19038 (define_expand "lfloor<mode>si2"
19039   [(match_operand:SI 0 "nonimmediate_operand" "")
19040    (match_operand:MODEF 1 "register_operand" "")]
19041   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19042    && !flag_trapping_math"
19043 {
19044   if (optimize_insn_for_size_p () && TARGET_64BIT)
19045     FAIL;
19046   ix86_expand_lfloorceil (operand0, operand1, true);
19047   DONE;
19048 })
19049
19050 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19051 (define_insn_and_split "frndintxf2_ceil"
19052   [(set (match_operand:XF 0 "register_operand" "")
19053         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19054          UNSPEC_FRNDINT_CEIL))
19055    (clobber (reg:CC FLAGS_REG))]
19056   "TARGET_USE_FANCY_MATH_387
19057    && flag_unsafe_math_optimizations
19058    && !(reload_completed || reload_in_progress)"
19059   "#"
19060   "&& 1"
19061   [(const_int 0)]
19062 {
19063   ix86_optimize_mode_switching[I387_CEIL] = 1;
19064
19065   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19066   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19067
19068   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
19069                                        operands[2], operands[3]));
19070   DONE;
19071 }
19072   [(set_attr "type" "frndint")
19073    (set_attr "i387_cw" "ceil")
19074    (set_attr "mode" "XF")])
19075
19076 (define_insn "frndintxf2_ceil_i387"
19077   [(set (match_operand:XF 0 "register_operand" "=f")
19078         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19079          UNSPEC_FRNDINT_CEIL))
19080    (use (match_operand:HI 2 "memory_operand" "m"))
19081    (use (match_operand:HI 3 "memory_operand" "m"))]
19082   "TARGET_USE_FANCY_MATH_387
19083    && flag_unsafe_math_optimizations"
19084   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19085   [(set_attr "type" "frndint")
19086    (set_attr "i387_cw" "ceil")
19087    (set_attr "mode" "XF")])
19088
19089 (define_expand "ceilxf2"
19090   [(use (match_operand:XF 0 "register_operand" ""))
19091    (use (match_operand:XF 1 "register_operand" ""))]
19092   "TARGET_USE_FANCY_MATH_387
19093    && flag_unsafe_math_optimizations"
19094 {
19095   if (optimize_insn_for_size_p ())
19096     FAIL;
19097   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19098   DONE;
19099 })
19100
19101 (define_expand "ceil<mode>2"
19102   [(use (match_operand:MODEF 0 "register_operand" ""))
19103    (use (match_operand:MODEF 1 "register_operand" ""))]
19104   "(TARGET_USE_FANCY_MATH_387
19105     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19106         || TARGET_MIX_SSE_I387)
19107     && flag_unsafe_math_optimizations)
19108    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19109        && !flag_trapping_math)"
19110 {
19111   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19112       && !flag_trapping_math
19113       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19114     {
19115       if (TARGET_ROUND)
19116         emit_insn (gen_sse4_1_round<mode>2
19117                    (operands[0], operands[1], GEN_INT (0x02)));
19118       else if (optimize_insn_for_size_p ())
19119         FAIL;
19120       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19121         ix86_expand_floorceil (operand0, operand1, false);
19122       else
19123         ix86_expand_floorceildf_32 (operand0, operand1, false);
19124     }
19125   else
19126     {
19127       rtx op0, op1;
19128
19129       if (optimize_insn_for_size_p ())
19130         FAIL;
19131
19132       op0 = gen_reg_rtx (XFmode);
19133       op1 = gen_reg_rtx (XFmode);
19134       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19135       emit_insn (gen_frndintxf2_ceil (op0, op1));
19136
19137       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19138     }
19139   DONE;
19140 })
19141
19142 (define_insn_and_split "*fist<mode>2_ceil_1"
19143   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19144         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19145          UNSPEC_FIST_CEIL))
19146    (clobber (reg:CC FLAGS_REG))]
19147   "TARGET_USE_FANCY_MATH_387
19148    && flag_unsafe_math_optimizations
19149    && !(reload_completed || reload_in_progress)"
19150   "#"
19151   "&& 1"
19152   [(const_int 0)]
19153 {
19154   ix86_optimize_mode_switching[I387_CEIL] = 1;
19155
19156   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19157   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19158   if (memory_operand (operands[0], VOIDmode))
19159     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19160                                      operands[2], operands[3]));
19161   else
19162     {
19163       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
19164       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19165                                                  operands[2], operands[3],
19166                                                  operands[4]));
19167     }
19168   DONE;
19169 }
19170   [(set_attr "type" "fistp")
19171    (set_attr "i387_cw" "ceil")
19172    (set_attr "mode" "<MODE>")])
19173
19174 (define_insn "fistdi2_ceil"
19175   [(set (match_operand:DI 0 "memory_operand" "=m")
19176         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19177          UNSPEC_FIST_CEIL))
19178    (use (match_operand:HI 2 "memory_operand" "m"))
19179    (use (match_operand:HI 3 "memory_operand" "m"))
19180    (clobber (match_scratch:XF 4 "=&1f"))]
19181   "TARGET_USE_FANCY_MATH_387
19182    && flag_unsafe_math_optimizations"
19183   "* return output_fix_trunc (insn, operands, 0);"
19184   [(set_attr "type" "fistp")
19185    (set_attr "i387_cw" "ceil")
19186    (set_attr "mode" "DI")])
19187
19188 (define_insn "fistdi2_ceil_with_temp"
19189   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19190         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19191          UNSPEC_FIST_CEIL))
19192    (use (match_operand:HI 2 "memory_operand" "m,m"))
19193    (use (match_operand:HI 3 "memory_operand" "m,m"))
19194    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
19195    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19196   "TARGET_USE_FANCY_MATH_387
19197    && flag_unsafe_math_optimizations"
19198   "#"
19199   [(set_attr "type" "fistp")
19200    (set_attr "i387_cw" "ceil")
19201    (set_attr "mode" "DI")])
19202
19203 (define_split
19204   [(set (match_operand:DI 0 "register_operand" "")
19205         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19206          UNSPEC_FIST_CEIL))
19207    (use (match_operand:HI 2 "memory_operand" ""))
19208    (use (match_operand:HI 3 "memory_operand" ""))
19209    (clobber (match_operand:DI 4 "memory_operand" ""))
19210    (clobber (match_scratch 5 ""))]
19211   "reload_completed"
19212   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19213               (use (match_dup 2))
19214               (use (match_dup 3))
19215               (clobber (match_dup 5))])
19216    (set (match_dup 0) (match_dup 4))]
19217   "")
19218
19219 (define_split
19220   [(set (match_operand:DI 0 "memory_operand" "")
19221         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19222          UNSPEC_FIST_CEIL))
19223    (use (match_operand:HI 2 "memory_operand" ""))
19224    (use (match_operand:HI 3 "memory_operand" ""))
19225    (clobber (match_operand:DI 4 "memory_operand" ""))
19226    (clobber (match_scratch 5 ""))]
19227   "reload_completed"
19228   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19229               (use (match_dup 2))
19230               (use (match_dup 3))
19231               (clobber (match_dup 5))])]
19232   "")
19233
19234 (define_insn "fist<mode>2_ceil"
19235   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19236         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19237          UNSPEC_FIST_CEIL))
19238    (use (match_operand:HI 2 "memory_operand" "m"))
19239    (use (match_operand:HI 3 "memory_operand" "m"))]
19240   "TARGET_USE_FANCY_MATH_387
19241    && flag_unsafe_math_optimizations"
19242   "* return output_fix_trunc (insn, operands, 0);"
19243   [(set_attr "type" "fistp")
19244    (set_attr "i387_cw" "ceil")
19245    (set_attr "mode" "<MODE>")])
19246
19247 (define_insn "fist<mode>2_ceil_with_temp"
19248   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19249         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19250          UNSPEC_FIST_CEIL))
19251    (use (match_operand:HI 2 "memory_operand" "m,m"))
19252    (use (match_operand:HI 3 "memory_operand" "m,m"))
19253    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
19254   "TARGET_USE_FANCY_MATH_387
19255    && flag_unsafe_math_optimizations"
19256   "#"
19257   [(set_attr "type" "fistp")
19258    (set_attr "i387_cw" "ceil")
19259    (set_attr "mode" "<MODE>")])
19260
19261 (define_split
19262   [(set (match_operand:X87MODEI12 0 "register_operand" "")
19263         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19264          UNSPEC_FIST_CEIL))
19265    (use (match_operand:HI 2 "memory_operand" ""))
19266    (use (match_operand:HI 3 "memory_operand" ""))
19267    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19268   "reload_completed"
19269   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19270                                   UNSPEC_FIST_CEIL))
19271               (use (match_dup 2))
19272               (use (match_dup 3))])
19273    (set (match_dup 0) (match_dup 4))]
19274   "")
19275
19276 (define_split
19277   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19278         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19279          UNSPEC_FIST_CEIL))
19280    (use (match_operand:HI 2 "memory_operand" ""))
19281    (use (match_operand:HI 3 "memory_operand" ""))
19282    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19283   "reload_completed"
19284   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19285                                   UNSPEC_FIST_CEIL))
19286               (use (match_dup 2))
19287               (use (match_dup 3))])]
19288   "")
19289
19290 (define_expand "lceilxf<mode>2"
19291   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19292                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19293                     UNSPEC_FIST_CEIL))
19294               (clobber (reg:CC FLAGS_REG))])]
19295   "TARGET_USE_FANCY_MATH_387
19296    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19297    && flag_unsafe_math_optimizations"
19298   "")
19299
19300 (define_expand "lceil<mode>di2"
19301   [(match_operand:DI 0 "nonimmediate_operand" "")
19302    (match_operand:MODEF 1 "register_operand" "")]
19303   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19304    && !flag_trapping_math"
19305 {
19306   ix86_expand_lfloorceil (operand0, operand1, false);
19307   DONE;
19308 })
19309
19310 (define_expand "lceil<mode>si2"
19311   [(match_operand:SI 0 "nonimmediate_operand" "")
19312    (match_operand:MODEF 1 "register_operand" "")]
19313   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19314    && !flag_trapping_math"
19315 {
19316   ix86_expand_lfloorceil (operand0, operand1, false);
19317   DONE;
19318 })
19319
19320 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19321 (define_insn_and_split "frndintxf2_trunc"
19322   [(set (match_operand:XF 0 "register_operand" "")
19323         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19324          UNSPEC_FRNDINT_TRUNC))
19325    (clobber (reg:CC FLAGS_REG))]
19326   "TARGET_USE_FANCY_MATH_387
19327    && flag_unsafe_math_optimizations
19328    && !(reload_completed || reload_in_progress)"
19329   "#"
19330   "&& 1"
19331   [(const_int 0)]
19332 {
19333   ix86_optimize_mode_switching[I387_TRUNC] = 1;
19334
19335   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19336   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
19337
19338   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19339                                         operands[2], operands[3]));
19340   DONE;
19341 }
19342   [(set_attr "type" "frndint")
19343    (set_attr "i387_cw" "trunc")
19344    (set_attr "mode" "XF")])
19345
19346 (define_insn "frndintxf2_trunc_i387"
19347   [(set (match_operand:XF 0 "register_operand" "=f")
19348         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19349          UNSPEC_FRNDINT_TRUNC))
19350    (use (match_operand:HI 2 "memory_operand" "m"))
19351    (use (match_operand:HI 3 "memory_operand" "m"))]
19352   "TARGET_USE_FANCY_MATH_387
19353    && flag_unsafe_math_optimizations"
19354   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19355   [(set_attr "type" "frndint")
19356    (set_attr "i387_cw" "trunc")
19357    (set_attr "mode" "XF")])
19358
19359 (define_expand "btruncxf2"
19360   [(use (match_operand:XF 0 "register_operand" ""))
19361    (use (match_operand:XF 1 "register_operand" ""))]
19362   "TARGET_USE_FANCY_MATH_387
19363    && flag_unsafe_math_optimizations"
19364 {
19365   if (optimize_insn_for_size_p ())
19366     FAIL;
19367   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19368   DONE;
19369 })
19370
19371 (define_expand "btrunc<mode>2"
19372   [(use (match_operand:MODEF 0 "register_operand" ""))
19373    (use (match_operand:MODEF 1 "register_operand" ""))]
19374   "(TARGET_USE_FANCY_MATH_387
19375     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19376         || TARGET_MIX_SSE_I387)
19377     && flag_unsafe_math_optimizations)
19378    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19379        && !flag_trapping_math)"
19380 {
19381   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19382       && !flag_trapping_math
19383       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19384     {
19385       if (TARGET_ROUND)
19386         emit_insn (gen_sse4_1_round<mode>2
19387                    (operands[0], operands[1], GEN_INT (0x03)));
19388       else if (optimize_insn_for_size_p ())
19389         FAIL;
19390       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19391         ix86_expand_trunc (operand0, operand1);
19392       else
19393         ix86_expand_truncdf_32 (operand0, operand1);
19394     }
19395   else
19396     {
19397       rtx op0, op1;
19398
19399       if (optimize_insn_for_size_p ())
19400         FAIL;
19401
19402       op0 = gen_reg_rtx (XFmode);
19403       op1 = gen_reg_rtx (XFmode);
19404       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19405       emit_insn (gen_frndintxf2_trunc (op0, op1));
19406
19407       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19408     }
19409   DONE;
19410 })
19411
19412 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19413 (define_insn_and_split "frndintxf2_mask_pm"
19414   [(set (match_operand:XF 0 "register_operand" "")
19415         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19416          UNSPEC_FRNDINT_MASK_PM))
19417    (clobber (reg:CC FLAGS_REG))]
19418   "TARGET_USE_FANCY_MATH_387
19419    && flag_unsafe_math_optimizations
19420    && !(reload_completed || reload_in_progress)"
19421   "#"
19422   "&& 1"
19423   [(const_int 0)]
19424 {
19425   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19426
19427   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19428   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19429
19430   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19431                                           operands[2], operands[3]));
19432   DONE;
19433 }
19434   [(set_attr "type" "frndint")
19435    (set_attr "i387_cw" "mask_pm")
19436    (set_attr "mode" "XF")])
19437
19438 (define_insn "frndintxf2_mask_pm_i387"
19439   [(set (match_operand:XF 0 "register_operand" "=f")
19440         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19441          UNSPEC_FRNDINT_MASK_PM))
19442    (use (match_operand:HI 2 "memory_operand" "m"))
19443    (use (match_operand:HI 3 "memory_operand" "m"))]
19444   "TARGET_USE_FANCY_MATH_387
19445    && flag_unsafe_math_optimizations"
19446   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19447   [(set_attr "type" "frndint")
19448    (set_attr "i387_cw" "mask_pm")
19449    (set_attr "mode" "XF")])
19450
19451 (define_expand "nearbyintxf2"
19452   [(use (match_operand:XF 0 "register_operand" ""))
19453    (use (match_operand:XF 1 "register_operand" ""))]
19454   "TARGET_USE_FANCY_MATH_387
19455    && flag_unsafe_math_optimizations"
19456 {
19457   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19458
19459   DONE;
19460 })
19461
19462 (define_expand "nearbyint<mode>2"
19463   [(use (match_operand:MODEF 0 "register_operand" ""))
19464    (use (match_operand:MODEF 1 "register_operand" ""))]
19465   "TARGET_USE_FANCY_MATH_387
19466    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19467        || TARGET_MIX_SSE_I387)
19468    && flag_unsafe_math_optimizations"
19469 {
19470   rtx op0 = gen_reg_rtx (XFmode);
19471   rtx op1 = gen_reg_rtx (XFmode);
19472
19473   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19474   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19475
19476   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19477   DONE;
19478 })
19479
19480 (define_insn "fxam<mode>2_i387"
19481   [(set (match_operand:HI 0 "register_operand" "=a")
19482         (unspec:HI
19483           [(match_operand:X87MODEF 1 "register_operand" "f")]
19484           UNSPEC_FXAM))]
19485   "TARGET_USE_FANCY_MATH_387"
19486   "fxam\n\tfnstsw\t%0"
19487   [(set_attr "type" "multi")
19488    (set_attr "length" "4")
19489    (set_attr "unit" "i387")
19490    (set_attr "mode" "<MODE>")])
19491
19492 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19493   [(set (match_operand:HI 0 "register_operand" "")
19494         (unspec:HI
19495           [(match_operand:MODEF 1 "memory_operand" "")]
19496           UNSPEC_FXAM_MEM))]
19497   "TARGET_USE_FANCY_MATH_387
19498    && !(reload_completed || reload_in_progress)"
19499   "#"
19500   "&& 1"
19501   [(set (match_dup 2)(match_dup 1))
19502    (set (match_dup 0)
19503         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19504 {
19505   operands[2] = gen_reg_rtx (<MODE>mode);
19506
19507   MEM_VOLATILE_P (operands[1]) = 1;
19508 }
19509   [(set_attr "type" "multi")
19510    (set_attr "unit" "i387")
19511    (set_attr "mode" "<MODE>")])
19512
19513 (define_expand "isinfxf2"
19514   [(use (match_operand:SI 0 "register_operand" ""))
19515    (use (match_operand:XF 1 "register_operand" ""))]
19516   "TARGET_USE_FANCY_MATH_387
19517    && TARGET_C99_FUNCTIONS"
19518 {
19519   rtx mask = GEN_INT (0x45);
19520   rtx val = GEN_INT (0x05);
19521
19522   rtx cond;
19523
19524   rtx scratch = gen_reg_rtx (HImode);
19525   rtx res = gen_reg_rtx (QImode);
19526
19527   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19528
19529   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19530   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19531   cond = gen_rtx_fmt_ee (EQ, QImode,
19532                          gen_rtx_REG (CCmode, FLAGS_REG),
19533                          const0_rtx);
19534   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19535   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19536   DONE;
19537 })
19538
19539 (define_expand "isinf<mode>2"
19540   [(use (match_operand:SI 0 "register_operand" ""))
19541    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19542   "TARGET_USE_FANCY_MATH_387
19543    && TARGET_C99_FUNCTIONS
19544    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19545 {
19546   rtx mask = GEN_INT (0x45);
19547   rtx val = GEN_INT (0x05);
19548
19549   rtx cond;
19550
19551   rtx scratch = gen_reg_rtx (HImode);
19552   rtx res = gen_reg_rtx (QImode);
19553
19554   /* Remove excess precision by forcing value through memory. */
19555   if (memory_operand (operands[1], VOIDmode))
19556     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19557   else
19558     {
19559       enum ix86_stack_slot slot = (virtuals_instantiated
19560                                    ? SLOT_TEMP
19561                                    : SLOT_VIRTUAL);
19562       rtx temp = assign_386_stack_local (<MODE>mode, slot);
19563
19564       emit_move_insn (temp, operands[1]);
19565       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19566     }
19567
19568   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19569   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19570   cond = gen_rtx_fmt_ee (EQ, QImode,
19571                          gen_rtx_REG (CCmode, FLAGS_REG),
19572                          const0_rtx);
19573   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19574   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19575   DONE;
19576 })
19577
19578 (define_expand "signbit<mode>2"
19579   [(use (match_operand:SI 0 "register_operand" ""))
19580    (use (match_operand:X87MODEF 1 "register_operand" ""))]
19581   "TARGET_USE_FANCY_MATH_387
19582    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19583 {
19584   rtx mask = GEN_INT (0x0200);
19585
19586   rtx scratch = gen_reg_rtx (HImode);
19587
19588   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19589   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19590   DONE;
19591 })
19592 \f
19593 ;; Block operation instructions
19594
19595 (define_insn "cld"
19596   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19597   ""
19598   "cld"
19599   [(set_attr "length" "1")
19600    (set_attr "length_immediate" "0")
19601    (set_attr "modrm" "0")])
19602
19603 (define_expand "movmemsi"
19604   [(use (match_operand:BLK 0 "memory_operand" ""))
19605    (use (match_operand:BLK 1 "memory_operand" ""))
19606    (use (match_operand:SI 2 "nonmemory_operand" ""))
19607    (use (match_operand:SI 3 "const_int_operand" ""))
19608    (use (match_operand:SI 4 "const_int_operand" ""))
19609    (use (match_operand:SI 5 "const_int_operand" ""))]
19610   ""
19611 {
19612  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19613                          operands[4], operands[5]))
19614    DONE;
19615  else
19616    FAIL;
19617 })
19618
19619 (define_expand "movmemdi"
19620   [(use (match_operand:BLK 0 "memory_operand" ""))
19621    (use (match_operand:BLK 1 "memory_operand" ""))
19622    (use (match_operand:DI 2 "nonmemory_operand" ""))
19623    (use (match_operand:DI 3 "const_int_operand" ""))
19624    (use (match_operand:SI 4 "const_int_operand" ""))
19625    (use (match_operand:SI 5 "const_int_operand" ""))]
19626   "TARGET_64BIT"
19627 {
19628  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19629                          operands[4], operands[5]))
19630    DONE;
19631  else
19632    FAIL;
19633 })
19634
19635 ;; Most CPUs don't like single string operations
19636 ;; Handle this case here to simplify previous expander.
19637
19638 (define_expand "strmov"
19639   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19640    (set (match_operand 1 "memory_operand" "") (match_dup 4))
19641    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19642               (clobber (reg:CC FLAGS_REG))])
19643    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19644               (clobber (reg:CC FLAGS_REG))])]
19645   ""
19646 {
19647   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19648
19649   /* If .md ever supports :P for Pmode, these can be directly
19650      in the pattern above.  */
19651   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19652   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19653
19654   /* Can't use this if the user has appropriated esi or edi.  */
19655   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19656       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19657     {
19658       emit_insn (gen_strmov_singleop (operands[0], operands[1],
19659                                       operands[2], operands[3],
19660                                       operands[5], operands[6]));
19661       DONE;
19662     }
19663
19664   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19665 })
19666
19667 (define_expand "strmov_singleop"
19668   [(parallel [(set (match_operand 1 "memory_operand" "")
19669                    (match_operand 3 "memory_operand" ""))
19670               (set (match_operand 0 "register_operand" "")
19671                    (match_operand 4 "" ""))
19672               (set (match_operand 2 "register_operand" "")
19673                    (match_operand 5 "" ""))])]
19674   ""
19675   "ix86_current_function_needs_cld = 1;")
19676
19677 (define_insn "*strmovdi_rex_1"
19678   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19679         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19680    (set (match_operand:DI 0 "register_operand" "=D")
19681         (plus:DI (match_dup 2)
19682                  (const_int 8)))
19683    (set (match_operand:DI 1 "register_operand" "=S")
19684         (plus:DI (match_dup 3)
19685                  (const_int 8)))]
19686   "TARGET_64BIT"
19687   "movsq"
19688   [(set_attr "type" "str")
19689    (set_attr "mode" "DI")
19690    (set_attr "memory" "both")])
19691
19692 (define_insn "*strmovsi_1"
19693   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19694         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19695    (set (match_operand:SI 0 "register_operand" "=D")
19696         (plus:SI (match_dup 2)
19697                  (const_int 4)))
19698    (set (match_operand:SI 1 "register_operand" "=S")
19699         (plus:SI (match_dup 3)
19700                  (const_int 4)))]
19701   "!TARGET_64BIT"
19702   "movs{l|d}"
19703   [(set_attr "type" "str")
19704    (set_attr "mode" "SI")
19705    (set_attr "memory" "both")])
19706
19707 (define_insn "*strmovsi_rex_1"
19708   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19709         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19710    (set (match_operand:DI 0 "register_operand" "=D")
19711         (plus:DI (match_dup 2)
19712                  (const_int 4)))
19713    (set (match_operand:DI 1 "register_operand" "=S")
19714         (plus:DI (match_dup 3)
19715                  (const_int 4)))]
19716   "TARGET_64BIT"
19717   "movs{l|d}"
19718   [(set_attr "type" "str")
19719    (set_attr "mode" "SI")
19720    (set_attr "memory" "both")])
19721
19722 (define_insn "*strmovhi_1"
19723   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19724         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19725    (set (match_operand:SI 0 "register_operand" "=D")
19726         (plus:SI (match_dup 2)
19727                  (const_int 2)))
19728    (set (match_operand:SI 1 "register_operand" "=S")
19729         (plus:SI (match_dup 3)
19730                  (const_int 2)))]
19731   "!TARGET_64BIT"
19732   "movsw"
19733   [(set_attr "type" "str")
19734    (set_attr "memory" "both")
19735    (set_attr "mode" "HI")])
19736
19737 (define_insn "*strmovhi_rex_1"
19738   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19739         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19740    (set (match_operand:DI 0 "register_operand" "=D")
19741         (plus:DI (match_dup 2)
19742                  (const_int 2)))
19743    (set (match_operand:DI 1 "register_operand" "=S")
19744         (plus:DI (match_dup 3)
19745                  (const_int 2)))]
19746   "TARGET_64BIT"
19747   "movsw"
19748   [(set_attr "type" "str")
19749    (set_attr "memory" "both")
19750    (set_attr "mode" "HI")])
19751
19752 (define_insn "*strmovqi_1"
19753   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19754         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19755    (set (match_operand:SI 0 "register_operand" "=D")
19756         (plus:SI (match_dup 2)
19757                  (const_int 1)))
19758    (set (match_operand:SI 1 "register_operand" "=S")
19759         (plus:SI (match_dup 3)
19760                  (const_int 1)))]
19761   "!TARGET_64BIT"
19762   "movsb"
19763   [(set_attr "type" "str")
19764    (set_attr "memory" "both")
19765    (set_attr "mode" "QI")])
19766
19767 (define_insn "*strmovqi_rex_1"
19768   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19769         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19770    (set (match_operand:DI 0 "register_operand" "=D")
19771         (plus:DI (match_dup 2)
19772                  (const_int 1)))
19773    (set (match_operand:DI 1 "register_operand" "=S")
19774         (plus:DI (match_dup 3)
19775                  (const_int 1)))]
19776   "TARGET_64BIT"
19777   "movsb"
19778   [(set_attr "type" "str")
19779    (set_attr "memory" "both")
19780    (set_attr "prefix_rex" "0")
19781    (set_attr "mode" "QI")])
19782
19783 (define_expand "rep_mov"
19784   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19785               (set (match_operand 0 "register_operand" "")
19786                    (match_operand 5 "" ""))
19787               (set (match_operand 2 "register_operand" "")
19788                    (match_operand 6 "" ""))
19789               (set (match_operand 1 "memory_operand" "")
19790                    (match_operand 3 "memory_operand" ""))
19791               (use (match_dup 4))])]
19792   ""
19793   "ix86_current_function_needs_cld = 1;")
19794
19795 (define_insn "*rep_movdi_rex64"
19796   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19797    (set (match_operand:DI 0 "register_operand" "=D")
19798         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19799                             (const_int 3))
19800                  (match_operand:DI 3 "register_operand" "0")))
19801    (set (match_operand:DI 1 "register_operand" "=S")
19802         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19803                  (match_operand:DI 4 "register_operand" "1")))
19804    (set (mem:BLK (match_dup 3))
19805         (mem:BLK (match_dup 4)))
19806    (use (match_dup 5))]
19807   "TARGET_64BIT"
19808   "rep movsq"
19809   [(set_attr "type" "str")
19810    (set_attr "prefix_rep" "1")
19811    (set_attr "memory" "both")
19812    (set_attr "mode" "DI")])
19813
19814 (define_insn "*rep_movsi"
19815   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19816    (set (match_operand:SI 0 "register_operand" "=D")
19817         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19818                             (const_int 2))
19819                  (match_operand:SI 3 "register_operand" "0")))
19820    (set (match_operand:SI 1 "register_operand" "=S")
19821         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19822                  (match_operand:SI 4 "register_operand" "1")))
19823    (set (mem:BLK (match_dup 3))
19824         (mem:BLK (match_dup 4)))
19825    (use (match_dup 5))]
19826   "!TARGET_64BIT"
19827   "rep movs{l|d}"
19828   [(set_attr "type" "str")
19829    (set_attr "prefix_rep" "1")
19830    (set_attr "memory" "both")
19831    (set_attr "mode" "SI")])
19832
19833 (define_insn "*rep_movsi_rex64"
19834   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19835    (set (match_operand:DI 0 "register_operand" "=D")
19836         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19837                             (const_int 2))
19838                  (match_operand:DI 3 "register_operand" "0")))
19839    (set (match_operand:DI 1 "register_operand" "=S")
19840         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19841                  (match_operand:DI 4 "register_operand" "1")))
19842    (set (mem:BLK (match_dup 3))
19843         (mem:BLK (match_dup 4)))
19844    (use (match_dup 5))]
19845   "TARGET_64BIT"
19846   "rep movs{l|d}"
19847   [(set_attr "type" "str")
19848    (set_attr "prefix_rep" "1")
19849    (set_attr "memory" "both")
19850    (set_attr "mode" "SI")])
19851
19852 (define_insn "*rep_movqi"
19853   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19854    (set (match_operand:SI 0 "register_operand" "=D")
19855         (plus:SI (match_operand:SI 3 "register_operand" "0")
19856                  (match_operand:SI 5 "register_operand" "2")))
19857    (set (match_operand:SI 1 "register_operand" "=S")
19858         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19859    (set (mem:BLK (match_dup 3))
19860         (mem:BLK (match_dup 4)))
19861    (use (match_dup 5))]
19862   "!TARGET_64BIT"
19863   "rep movsb"
19864   [(set_attr "type" "str")
19865    (set_attr "prefix_rep" "1")
19866    (set_attr "memory" "both")
19867    (set_attr "mode" "SI")])
19868
19869 (define_insn "*rep_movqi_rex64"
19870   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19871    (set (match_operand:DI 0 "register_operand" "=D")
19872         (plus:DI (match_operand:DI 3 "register_operand" "0")
19873                  (match_operand:DI 5 "register_operand" "2")))
19874    (set (match_operand:DI 1 "register_operand" "=S")
19875         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19876    (set (mem:BLK (match_dup 3))
19877         (mem:BLK (match_dup 4)))
19878    (use (match_dup 5))]
19879   "TARGET_64BIT"
19880   "rep movsb"
19881   [(set_attr "type" "str")
19882    (set_attr "prefix_rep" "1")
19883    (set_attr "memory" "both")
19884    (set_attr "mode" "SI")])
19885
19886 (define_expand "setmemsi"
19887    [(use (match_operand:BLK 0 "memory_operand" ""))
19888     (use (match_operand:SI 1 "nonmemory_operand" ""))
19889     (use (match_operand 2 "const_int_operand" ""))
19890     (use (match_operand 3 "const_int_operand" ""))
19891     (use (match_operand:SI 4 "const_int_operand" ""))
19892     (use (match_operand:SI 5 "const_int_operand" ""))]
19893   ""
19894 {
19895  if (ix86_expand_setmem (operands[0], operands[1],
19896                          operands[2], operands[3],
19897                          operands[4], operands[5]))
19898    DONE;
19899  else
19900    FAIL;
19901 })
19902
19903 (define_expand "setmemdi"
19904    [(use (match_operand:BLK 0 "memory_operand" ""))
19905     (use (match_operand:DI 1 "nonmemory_operand" ""))
19906     (use (match_operand 2 "const_int_operand" ""))
19907     (use (match_operand 3 "const_int_operand" ""))
19908     (use (match_operand 4 "const_int_operand" ""))
19909     (use (match_operand 5 "const_int_operand" ""))]
19910   "TARGET_64BIT"
19911 {
19912  if (ix86_expand_setmem (operands[0], operands[1],
19913                          operands[2], operands[3],
19914                          operands[4], operands[5]))
19915    DONE;
19916  else
19917    FAIL;
19918 })
19919
19920 ;; Most CPUs don't like single string operations
19921 ;; Handle this case here to simplify previous expander.
19922
19923 (define_expand "strset"
19924   [(set (match_operand 1 "memory_operand" "")
19925         (match_operand 2 "register_operand" ""))
19926    (parallel [(set (match_operand 0 "register_operand" "")
19927                    (match_dup 3))
19928               (clobber (reg:CC FLAGS_REG))])]
19929   ""
19930 {
19931   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19932     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19933
19934   /* If .md ever supports :P for Pmode, this can be directly
19935      in the pattern above.  */
19936   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19937                               GEN_INT (GET_MODE_SIZE (GET_MODE
19938                                                       (operands[2]))));
19939   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19940     {
19941       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19942                                       operands[3]));
19943       DONE;
19944     }
19945 })
19946
19947 (define_expand "strset_singleop"
19948   [(parallel [(set (match_operand 1 "memory_operand" "")
19949                    (match_operand 2 "register_operand" ""))
19950               (set (match_operand 0 "register_operand" "")
19951                    (match_operand 3 "" ""))])]
19952   ""
19953   "ix86_current_function_needs_cld = 1;")
19954
19955 (define_insn "*strsetdi_rex_1"
19956   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19957         (match_operand:DI 2 "register_operand" "a"))
19958    (set (match_operand:DI 0 "register_operand" "=D")
19959         (plus:DI (match_dup 1)
19960                  (const_int 8)))]
19961   "TARGET_64BIT"
19962   "stosq"
19963   [(set_attr "type" "str")
19964    (set_attr "memory" "store")
19965    (set_attr "mode" "DI")])
19966
19967 (define_insn "*strsetsi_1"
19968   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19969         (match_operand:SI 2 "register_operand" "a"))
19970    (set (match_operand:SI 0 "register_operand" "=D")
19971         (plus:SI (match_dup 1)
19972                  (const_int 4)))]
19973   "!TARGET_64BIT"
19974   "stos{l|d}"
19975   [(set_attr "type" "str")
19976    (set_attr "memory" "store")
19977    (set_attr "mode" "SI")])
19978
19979 (define_insn "*strsetsi_rex_1"
19980   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19981         (match_operand:SI 2 "register_operand" "a"))
19982    (set (match_operand:DI 0 "register_operand" "=D")
19983         (plus:DI (match_dup 1)
19984                  (const_int 4)))]
19985   "TARGET_64BIT"
19986   "stos{l|d}"
19987   [(set_attr "type" "str")
19988    (set_attr "memory" "store")
19989    (set_attr "mode" "SI")])
19990
19991 (define_insn "*strsethi_1"
19992   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19993         (match_operand:HI 2 "register_operand" "a"))
19994    (set (match_operand:SI 0 "register_operand" "=D")
19995         (plus:SI (match_dup 1)
19996                  (const_int 2)))]
19997   "!TARGET_64BIT"
19998   "stosw"
19999   [(set_attr "type" "str")
20000    (set_attr "memory" "store")
20001    (set_attr "mode" "HI")])
20002
20003 (define_insn "*strsethi_rex_1"
20004   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
20005         (match_operand:HI 2 "register_operand" "a"))
20006    (set (match_operand:DI 0 "register_operand" "=D")
20007         (plus:DI (match_dup 1)
20008                  (const_int 2)))]
20009   "TARGET_64BIT"
20010   "stosw"
20011   [(set_attr "type" "str")
20012    (set_attr "memory" "store")
20013    (set_attr "mode" "HI")])
20014
20015 (define_insn "*strsetqi_1"
20016   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
20017         (match_operand:QI 2 "register_operand" "a"))
20018    (set (match_operand:SI 0 "register_operand" "=D")
20019         (plus:SI (match_dup 1)
20020                  (const_int 1)))]
20021   "!TARGET_64BIT"
20022   "stosb"
20023   [(set_attr "type" "str")
20024    (set_attr "memory" "store")
20025    (set_attr "mode" "QI")])
20026
20027 (define_insn "*strsetqi_rex_1"
20028   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
20029         (match_operand:QI 2 "register_operand" "a"))
20030    (set (match_operand:DI 0 "register_operand" "=D")
20031         (plus:DI (match_dup 1)
20032                  (const_int 1)))]
20033   "TARGET_64BIT"
20034   "stosb"
20035   [(set_attr "type" "str")
20036    (set_attr "memory" "store")
20037    (set_attr "prefix_rex" "0")
20038    (set_attr "mode" "QI")])
20039
20040 (define_expand "rep_stos"
20041   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
20042               (set (match_operand 0 "register_operand" "")
20043                    (match_operand 4 "" ""))
20044               (set (match_operand 2 "memory_operand" "") (const_int 0))
20045               (use (match_operand 3 "register_operand" ""))
20046               (use (match_dup 1))])]
20047   ""
20048   "ix86_current_function_needs_cld = 1;")
20049
20050 (define_insn "*rep_stosdi_rex64"
20051   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20052    (set (match_operand:DI 0 "register_operand" "=D")
20053         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20054                             (const_int 3))
20055                  (match_operand:DI 3 "register_operand" "0")))
20056    (set (mem:BLK (match_dup 3))
20057         (const_int 0))
20058    (use (match_operand:DI 2 "register_operand" "a"))
20059    (use (match_dup 4))]
20060   "TARGET_64BIT"
20061   "rep stosq"
20062   [(set_attr "type" "str")
20063    (set_attr "prefix_rep" "1")
20064    (set_attr "memory" "store")
20065    (set_attr "mode" "DI")])
20066
20067 (define_insn "*rep_stossi"
20068   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20069    (set (match_operand:SI 0 "register_operand" "=D")
20070         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
20071                             (const_int 2))
20072                  (match_operand:SI 3 "register_operand" "0")))
20073    (set (mem:BLK (match_dup 3))
20074         (const_int 0))
20075    (use (match_operand:SI 2 "register_operand" "a"))
20076    (use (match_dup 4))]
20077   "!TARGET_64BIT"
20078   "rep stos{l|d}"
20079   [(set_attr "type" "str")
20080    (set_attr "prefix_rep" "1")
20081    (set_attr "memory" "store")
20082    (set_attr "mode" "SI")])
20083
20084 (define_insn "*rep_stossi_rex64"
20085   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20086    (set (match_operand:DI 0 "register_operand" "=D")
20087         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20088                             (const_int 2))
20089                  (match_operand:DI 3 "register_operand" "0")))
20090    (set (mem:BLK (match_dup 3))
20091         (const_int 0))
20092    (use (match_operand:SI 2 "register_operand" "a"))
20093    (use (match_dup 4))]
20094   "TARGET_64BIT"
20095   "rep stos{l|d}"
20096   [(set_attr "type" "str")
20097    (set_attr "prefix_rep" "1")
20098    (set_attr "memory" "store")
20099    (set_attr "mode" "SI")])
20100
20101 (define_insn "*rep_stosqi"
20102   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20103    (set (match_operand:SI 0 "register_operand" "=D")
20104         (plus:SI (match_operand:SI 3 "register_operand" "0")
20105                  (match_operand:SI 4 "register_operand" "1")))
20106    (set (mem:BLK (match_dup 3))
20107         (const_int 0))
20108    (use (match_operand:QI 2 "register_operand" "a"))
20109    (use (match_dup 4))]
20110   "!TARGET_64BIT"
20111   "rep stosb"
20112   [(set_attr "type" "str")
20113    (set_attr "prefix_rep" "1")
20114    (set_attr "memory" "store")
20115    (set_attr "mode" "QI")])
20116
20117 (define_insn "*rep_stosqi_rex64"
20118   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20119    (set (match_operand:DI 0 "register_operand" "=D")
20120         (plus:DI (match_operand:DI 3 "register_operand" "0")
20121                  (match_operand:DI 4 "register_operand" "1")))
20122    (set (mem:BLK (match_dup 3))
20123         (const_int 0))
20124    (use (match_operand:QI 2 "register_operand" "a"))
20125    (use (match_dup 4))]
20126   "TARGET_64BIT"
20127   "rep stosb"
20128   [(set_attr "type" "str")
20129    (set_attr "prefix_rep" "1")
20130    (set_attr "memory" "store")
20131    (set_attr "prefix_rex" "0")
20132    (set_attr "mode" "QI")])
20133
20134 (define_expand "cmpstrnsi"
20135   [(set (match_operand:SI 0 "register_operand" "")
20136         (compare:SI (match_operand:BLK 1 "general_operand" "")
20137                     (match_operand:BLK 2 "general_operand" "")))
20138    (use (match_operand 3 "general_operand" ""))
20139    (use (match_operand 4 "immediate_operand" ""))]
20140   ""
20141 {
20142   rtx addr1, addr2, out, outlow, count, countreg, align;
20143
20144   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20145     FAIL;
20146
20147   /* Can't use this if the user has appropriated esi or edi.  */
20148   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
20149     FAIL;
20150
20151   out = operands[0];
20152   if (!REG_P (out))
20153     out = gen_reg_rtx (SImode);
20154
20155   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20156   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
20157   if (addr1 != XEXP (operands[1], 0))
20158     operands[1] = replace_equiv_address_nv (operands[1], addr1);
20159   if (addr2 != XEXP (operands[2], 0))
20160     operands[2] = replace_equiv_address_nv (operands[2], addr2);
20161
20162   count = operands[3];
20163   countreg = ix86_zero_extend_to_Pmode (count);
20164
20165   /* %%% Iff we are testing strict equality, we can use known alignment
20166      to good advantage.  This may be possible with combine, particularly
20167      once cc0 is dead.  */
20168   align = operands[4];
20169
20170   if (CONST_INT_P (count))
20171     {
20172       if (INTVAL (count) == 0)
20173         {
20174           emit_move_insn (operands[0], const0_rtx);
20175           DONE;
20176         }
20177       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20178                                      operands[1], operands[2]));
20179     }
20180   else
20181     {
20182       if (TARGET_64BIT)
20183         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
20184       else
20185         emit_insn (gen_cmpsi_1 (countreg, countreg));
20186       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20187                                   operands[1], operands[2]));
20188     }
20189
20190   outlow = gen_lowpart (QImode, out);
20191   emit_insn (gen_cmpintqi (outlow));
20192   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
20193
20194   if (operands[0] != out)
20195     emit_move_insn (operands[0], out);
20196
20197   DONE;
20198 })
20199
20200 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20201
20202 (define_expand "cmpintqi"
20203   [(set (match_dup 1)
20204         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20205    (set (match_dup 2)
20206         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20207    (parallel [(set (match_operand:QI 0 "register_operand" "")
20208                    (minus:QI (match_dup 1)
20209                              (match_dup 2)))
20210               (clobber (reg:CC FLAGS_REG))])]
20211   ""
20212   "operands[1] = gen_reg_rtx (QImode);
20213    operands[2] = gen_reg_rtx (QImode);")
20214
20215 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
20216 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
20217
20218 (define_expand "cmpstrnqi_nz_1"
20219   [(parallel [(set (reg:CC FLAGS_REG)
20220                    (compare:CC (match_operand 4 "memory_operand" "")
20221                                (match_operand 5 "memory_operand" "")))
20222               (use (match_operand 2 "register_operand" ""))
20223               (use (match_operand:SI 3 "immediate_operand" ""))
20224               (clobber (match_operand 0 "register_operand" ""))
20225               (clobber (match_operand 1 "register_operand" ""))
20226               (clobber (match_dup 2))])]
20227   ""
20228   "ix86_current_function_needs_cld = 1;")
20229
20230 (define_insn "*cmpstrnqi_nz_1"
20231   [(set (reg:CC FLAGS_REG)
20232         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20233                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20234    (use (match_operand:SI 6 "register_operand" "2"))
20235    (use (match_operand:SI 3 "immediate_operand" "i"))
20236    (clobber (match_operand:SI 0 "register_operand" "=S"))
20237    (clobber (match_operand:SI 1 "register_operand" "=D"))
20238    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20239   "!TARGET_64BIT"
20240   "repz cmpsb"
20241   [(set_attr "type" "str")
20242    (set_attr "mode" "QI")
20243    (set_attr "prefix_rep" "1")])
20244
20245 (define_insn "*cmpstrnqi_nz_rex_1"
20246   [(set (reg:CC FLAGS_REG)
20247         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20248                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20249    (use (match_operand:DI 6 "register_operand" "2"))
20250    (use (match_operand:SI 3 "immediate_operand" "i"))
20251    (clobber (match_operand:DI 0 "register_operand" "=S"))
20252    (clobber (match_operand:DI 1 "register_operand" "=D"))
20253    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20254   "TARGET_64BIT"
20255   "repz cmpsb"
20256   [(set_attr "type" "str")
20257    (set_attr "mode" "QI")
20258    (set_attr "prefix_rex" "0")
20259    (set_attr "prefix_rep" "1")])
20260
20261 ;; The same, but the count is not known to not be zero.
20262
20263 (define_expand "cmpstrnqi_1"
20264   [(parallel [(set (reg:CC FLAGS_REG)
20265                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20266                                      (const_int 0))
20267                   (compare:CC (match_operand 4 "memory_operand" "")
20268                               (match_operand 5 "memory_operand" ""))
20269                   (const_int 0)))
20270               (use (match_operand:SI 3 "immediate_operand" ""))
20271               (use (reg:CC FLAGS_REG))
20272               (clobber (match_operand 0 "register_operand" ""))
20273               (clobber (match_operand 1 "register_operand" ""))
20274               (clobber (match_dup 2))])]
20275   ""
20276   "ix86_current_function_needs_cld = 1;")
20277
20278 (define_insn "*cmpstrnqi_1"
20279   [(set (reg:CC FLAGS_REG)
20280         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
20281                              (const_int 0))
20282           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20283                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
20284           (const_int 0)))
20285    (use (match_operand:SI 3 "immediate_operand" "i"))
20286    (use (reg:CC FLAGS_REG))
20287    (clobber (match_operand:SI 0 "register_operand" "=S"))
20288    (clobber (match_operand:SI 1 "register_operand" "=D"))
20289    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20290   "!TARGET_64BIT"
20291   "repz cmpsb"
20292   [(set_attr "type" "str")
20293    (set_attr "mode" "QI")
20294    (set_attr "prefix_rep" "1")])
20295
20296 (define_insn "*cmpstrnqi_rex_1"
20297   [(set (reg:CC FLAGS_REG)
20298         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20299                              (const_int 0))
20300           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20301                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20302           (const_int 0)))
20303    (use (match_operand:SI 3 "immediate_operand" "i"))
20304    (use (reg:CC FLAGS_REG))
20305    (clobber (match_operand:DI 0 "register_operand" "=S"))
20306    (clobber (match_operand:DI 1 "register_operand" "=D"))
20307    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20308   "TARGET_64BIT"
20309   "repz cmpsb"
20310   [(set_attr "type" "str")
20311    (set_attr "mode" "QI")
20312    (set_attr "prefix_rex" "0")
20313    (set_attr "prefix_rep" "1")])
20314
20315 (define_expand "strlensi"
20316   [(set (match_operand:SI 0 "register_operand" "")
20317         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20318                     (match_operand:QI 2 "immediate_operand" "")
20319                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20320   ""
20321 {
20322  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20323    DONE;
20324  else
20325    FAIL;
20326 })
20327
20328 (define_expand "strlendi"
20329   [(set (match_operand:DI 0 "register_operand" "")
20330         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20331                     (match_operand:QI 2 "immediate_operand" "")
20332                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20333   ""
20334 {
20335  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20336    DONE;
20337  else
20338    FAIL;
20339 })
20340
20341 (define_expand "strlenqi_1"
20342   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
20343               (clobber (match_operand 1 "register_operand" ""))
20344               (clobber (reg:CC FLAGS_REG))])]
20345   ""
20346   "ix86_current_function_needs_cld = 1;")
20347
20348 (define_insn "*strlenqi_1"
20349   [(set (match_operand:SI 0 "register_operand" "=&c")
20350         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
20351                     (match_operand:QI 2 "register_operand" "a")
20352                     (match_operand:SI 3 "immediate_operand" "i")
20353                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
20354    (clobber (match_operand:SI 1 "register_operand" "=D"))
20355    (clobber (reg:CC FLAGS_REG))]
20356   "!TARGET_64BIT"
20357   "repnz scasb"
20358   [(set_attr "type" "str")
20359    (set_attr "mode" "QI")
20360    (set_attr "prefix_rep" "1")])
20361
20362 (define_insn "*strlenqi_rex_1"
20363   [(set (match_operand:DI 0 "register_operand" "=&c")
20364         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20365                     (match_operand:QI 2 "register_operand" "a")
20366                     (match_operand:DI 3 "immediate_operand" "i")
20367                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
20368    (clobber (match_operand:DI 1 "register_operand" "=D"))
20369    (clobber (reg:CC FLAGS_REG))]
20370   "TARGET_64BIT"
20371   "repnz scasb"
20372   [(set_attr "type" "str")
20373    (set_attr "mode" "QI")
20374    (set_attr "prefix_rex" "0")
20375    (set_attr "prefix_rep" "1")])
20376
20377 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
20378 ;; handled in combine, but it is not currently up to the task.
20379 ;; When used for their truth value, the cmpstrn* expanders generate
20380 ;; code like this:
20381 ;;
20382 ;;   repz cmpsb
20383 ;;   seta       %al
20384 ;;   setb       %dl
20385 ;;   cmpb       %al, %dl
20386 ;;   jcc        label
20387 ;;
20388 ;; The intermediate three instructions are unnecessary.
20389
20390 ;; This one handles cmpstrn*_nz_1...
20391 (define_peephole2
20392   [(parallel[
20393      (set (reg:CC FLAGS_REG)
20394           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20395                       (mem:BLK (match_operand 5 "register_operand" ""))))
20396      (use (match_operand 6 "register_operand" ""))
20397      (use (match_operand:SI 3 "immediate_operand" ""))
20398      (clobber (match_operand 0 "register_operand" ""))
20399      (clobber (match_operand 1 "register_operand" ""))
20400      (clobber (match_operand 2 "register_operand" ""))])
20401    (set (match_operand:QI 7 "register_operand" "")
20402         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20403    (set (match_operand:QI 8 "register_operand" "")
20404         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20405    (set (reg FLAGS_REG)
20406         (compare (match_dup 7) (match_dup 8)))
20407   ]
20408   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20409   [(parallel[
20410      (set (reg:CC FLAGS_REG)
20411           (compare:CC (mem:BLK (match_dup 4))
20412                       (mem:BLK (match_dup 5))))
20413      (use (match_dup 6))
20414      (use (match_dup 3))
20415      (clobber (match_dup 0))
20416      (clobber (match_dup 1))
20417      (clobber (match_dup 2))])]
20418   "")
20419
20420 ;; ...and this one handles cmpstrn*_1.
20421 (define_peephole2
20422   [(parallel[
20423      (set (reg:CC FLAGS_REG)
20424           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20425                                (const_int 0))
20426             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20427                         (mem:BLK (match_operand 5 "register_operand" "")))
20428             (const_int 0)))
20429      (use (match_operand:SI 3 "immediate_operand" ""))
20430      (use (reg:CC FLAGS_REG))
20431      (clobber (match_operand 0 "register_operand" ""))
20432      (clobber (match_operand 1 "register_operand" ""))
20433      (clobber (match_operand 2 "register_operand" ""))])
20434    (set (match_operand:QI 7 "register_operand" "")
20435         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20436    (set (match_operand:QI 8 "register_operand" "")
20437         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20438    (set (reg FLAGS_REG)
20439         (compare (match_dup 7) (match_dup 8)))
20440   ]
20441   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20442   [(parallel[
20443      (set (reg:CC FLAGS_REG)
20444           (if_then_else:CC (ne (match_dup 6)
20445                                (const_int 0))
20446             (compare:CC (mem:BLK (match_dup 4))
20447                         (mem:BLK (match_dup 5)))
20448             (const_int 0)))
20449      (use (match_dup 3))
20450      (use (reg:CC FLAGS_REG))
20451      (clobber (match_dup 0))
20452      (clobber (match_dup 1))
20453      (clobber (match_dup 2))])]
20454   "")
20455
20456
20457 \f
20458 ;; Conditional move instructions.
20459
20460 (define_expand "movdicc"
20461   [(set (match_operand:DI 0 "register_operand" "")
20462         (if_then_else:DI (match_operand 1 "comparison_operator" "")
20463                          (match_operand:DI 2 "general_operand" "")
20464                          (match_operand:DI 3 "general_operand" "")))]
20465   "TARGET_64BIT"
20466   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20467
20468 (define_insn "x86_movdicc_0_m1_rex64"
20469   [(set (match_operand:DI 0 "register_operand" "=r")
20470         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20471           (const_int -1)
20472           (const_int 0)))
20473    (clobber (reg:CC FLAGS_REG))]
20474   "TARGET_64BIT"
20475   "sbb{q}\t%0, %0"
20476   ; Since we don't have the proper number of operands for an alu insn,
20477   ; fill in all the blanks.
20478   [(set_attr "type" "alu")
20479    (set_attr "use_carry" "1")
20480    (set_attr "pent_pair" "pu")
20481    (set_attr "memory" "none")
20482    (set_attr "imm_disp" "false")
20483    (set_attr "mode" "DI")
20484    (set_attr "length_immediate" "0")])
20485
20486 (define_insn "*x86_movdicc_0_m1_se"
20487   [(set (match_operand:DI 0 "register_operand" "=r")
20488         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20489                          (const_int 1)
20490                          (const_int 0)))
20491    (clobber (reg:CC FLAGS_REG))]
20492   ""
20493   "sbb{q}\t%0, %0"
20494   [(set_attr "type" "alu")
20495    (set_attr "use_carry" "1")
20496    (set_attr "pent_pair" "pu")
20497    (set_attr "memory" "none")
20498    (set_attr "imm_disp" "false")
20499    (set_attr "mode" "DI")
20500    (set_attr "length_immediate" "0")])
20501
20502 (define_insn "*movdicc_c_rex64"
20503   [(set (match_operand:DI 0 "register_operand" "=r,r")
20504         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20505                                 [(reg FLAGS_REG) (const_int 0)])
20506                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20507                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20508   "TARGET_64BIT && TARGET_CMOVE
20509    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20510   "@
20511    cmov%O2%C1\t{%2, %0|%0, %2}
20512    cmov%O2%c1\t{%3, %0|%0, %3}"
20513   [(set_attr "type" "icmov")
20514    (set_attr "mode" "DI")])
20515
20516 (define_expand "movsicc"
20517   [(set (match_operand:SI 0 "register_operand" "")
20518         (if_then_else:SI (match_operand 1 "comparison_operator" "")
20519                          (match_operand:SI 2 "general_operand" "")
20520                          (match_operand:SI 3 "general_operand" "")))]
20521   ""
20522   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20523
20524 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20525 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20526 ;; So just document what we're doing explicitly.
20527
20528 (define_insn "x86_movsicc_0_m1"
20529   [(set (match_operand:SI 0 "register_operand" "=r")
20530         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20531           (const_int -1)
20532           (const_int 0)))
20533    (clobber (reg:CC FLAGS_REG))]
20534   ""
20535   "sbb{l}\t%0, %0"
20536   ; Since we don't have the proper number of operands for an alu insn,
20537   ; fill in all the blanks.
20538   [(set_attr "type" "alu")
20539    (set_attr "use_carry" "1")
20540    (set_attr "pent_pair" "pu")
20541    (set_attr "memory" "none")
20542    (set_attr "imm_disp" "false")
20543    (set_attr "mode" "SI")
20544    (set_attr "length_immediate" "0")])
20545
20546 (define_insn "*x86_movsicc_0_m1_se"
20547   [(set (match_operand:SI 0 "register_operand" "=r")
20548         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20549                          (const_int 1)
20550                          (const_int 0)))
20551    (clobber (reg:CC FLAGS_REG))]
20552   ""
20553   "sbb{l}\t%0, %0"
20554   [(set_attr "type" "alu")
20555    (set_attr "use_carry" "1")
20556    (set_attr "pent_pair" "pu")
20557    (set_attr "memory" "none")
20558    (set_attr "imm_disp" "false")
20559    (set_attr "mode" "SI")
20560    (set_attr "length_immediate" "0")])
20561
20562 (define_insn "*movsicc_noc"
20563   [(set (match_operand:SI 0 "register_operand" "=r,r")
20564         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20565                                 [(reg FLAGS_REG) (const_int 0)])
20566                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20567                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20568   "TARGET_CMOVE
20569    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20570   "@
20571    cmov%O2%C1\t{%2, %0|%0, %2}
20572    cmov%O2%c1\t{%3, %0|%0, %3}"
20573   [(set_attr "type" "icmov")
20574    (set_attr "mode" "SI")])
20575
20576 (define_expand "movhicc"
20577   [(set (match_operand:HI 0 "register_operand" "")
20578         (if_then_else:HI (match_operand 1 "comparison_operator" "")
20579                          (match_operand:HI 2 "general_operand" "")
20580                          (match_operand:HI 3 "general_operand" "")))]
20581   "TARGET_HIMODE_MATH"
20582   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20583
20584 (define_insn "*movhicc_noc"
20585   [(set (match_operand:HI 0 "register_operand" "=r,r")
20586         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20587                                 [(reg FLAGS_REG) (const_int 0)])
20588                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20589                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20590   "TARGET_CMOVE
20591    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20592   "@
20593    cmov%O2%C1\t{%2, %0|%0, %2}
20594    cmov%O2%c1\t{%3, %0|%0, %3}"
20595   [(set_attr "type" "icmov")
20596    (set_attr "mode" "HI")])
20597
20598 (define_expand "movqicc"
20599   [(set (match_operand:QI 0 "register_operand" "")
20600         (if_then_else:QI (match_operand 1 "comparison_operator" "")
20601                          (match_operand:QI 2 "general_operand" "")
20602                          (match_operand:QI 3 "general_operand" "")))]
20603   "TARGET_QIMODE_MATH"
20604   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20605
20606 (define_insn_and_split "*movqicc_noc"
20607   [(set (match_operand:QI 0 "register_operand" "=r,r")
20608         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20609                                 [(match_operand 4 "flags_reg_operand" "")
20610                                  (const_int 0)])
20611                       (match_operand:QI 2 "register_operand" "r,0")
20612                       (match_operand:QI 3 "register_operand" "0,r")))]
20613   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20614   "#"
20615   "&& reload_completed"
20616   [(set (match_dup 0)
20617         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20618                       (match_dup 2)
20619                       (match_dup 3)))]
20620   "operands[0] = gen_lowpart (SImode, operands[0]);
20621    operands[2] = gen_lowpart (SImode, operands[2]);
20622    operands[3] = gen_lowpart (SImode, operands[3]);"
20623   [(set_attr "type" "icmov")
20624    (set_attr "mode" "SI")])
20625
20626 (define_expand "mov<mode>cc"
20627   [(set (match_operand:X87MODEF 0 "register_operand" "")
20628         (if_then_else:X87MODEF
20629           (match_operand 1 "comparison_operator" "")
20630           (match_operand:X87MODEF 2 "register_operand" "")
20631           (match_operand:X87MODEF 3 "register_operand" "")))]
20632   "(TARGET_80387 && TARGET_CMOVE)
20633    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20634   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20635
20636 (define_insn "*movsfcc_1_387"
20637   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20638         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20639                                 [(reg FLAGS_REG) (const_int 0)])
20640                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20641                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20642   "TARGET_80387 && TARGET_CMOVE
20643    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20644   "@
20645    fcmov%F1\t{%2, %0|%0, %2}
20646    fcmov%f1\t{%3, %0|%0, %3}
20647    cmov%O2%C1\t{%2, %0|%0, %2}
20648    cmov%O2%c1\t{%3, %0|%0, %3}"
20649   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20650    (set_attr "mode" "SF,SF,SI,SI")])
20651
20652 (define_insn "*movdfcc_1"
20653   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20654         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20655                                 [(reg FLAGS_REG) (const_int 0)])
20656                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20657                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20658   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20659    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20660   "@
20661    fcmov%F1\t{%2, %0|%0, %2}
20662    fcmov%f1\t{%3, %0|%0, %3}
20663    #
20664    #"
20665   [(set_attr "type" "fcmov,fcmov,multi,multi")
20666    (set_attr "mode" "DF")])
20667
20668 (define_insn "*movdfcc_1_rex64"
20669   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20670         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20671                                 [(reg FLAGS_REG) (const_int 0)])
20672                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20673                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20674   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20675    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20676   "@
20677    fcmov%F1\t{%2, %0|%0, %2}
20678    fcmov%f1\t{%3, %0|%0, %3}
20679    cmov%O2%C1\t{%2, %0|%0, %2}
20680    cmov%O2%c1\t{%3, %0|%0, %3}"
20681   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20682    (set_attr "mode" "DF")])
20683
20684 (define_split
20685   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20686         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20687                                 [(match_operand 4 "flags_reg_operand" "")
20688                                  (const_int 0)])
20689                       (match_operand:DF 2 "nonimmediate_operand" "")
20690                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20691   "!TARGET_64BIT && reload_completed"
20692   [(set (match_dup 2)
20693         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20694                       (match_dup 5)
20695                       (match_dup 6)))
20696    (set (match_dup 3)
20697         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20698                       (match_dup 7)
20699                       (match_dup 8)))]
20700   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20701    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20702
20703 (define_insn "*movxfcc_1"
20704   [(set (match_operand:XF 0 "register_operand" "=f,f")
20705         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20706                                 [(reg FLAGS_REG) (const_int 0)])
20707                       (match_operand:XF 2 "register_operand" "f,0")
20708                       (match_operand:XF 3 "register_operand" "0,f")))]
20709   "TARGET_80387 && TARGET_CMOVE"
20710   "@
20711    fcmov%F1\t{%2, %0|%0, %2}
20712    fcmov%f1\t{%3, %0|%0, %3}"
20713   [(set_attr "type" "fcmov")
20714    (set_attr "mode" "XF")])
20715
20716 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20717 ;; the scalar versions to have only XMM registers as operands.
20718
20719 ;; SSE5 conditional move
20720 (define_insn "*sse5_pcmov_<mode>"
20721   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20722         (if_then_else:MODEF
20723           (match_operand:MODEF 1 "register_operand" "x,0")
20724           (match_operand:MODEF 2 "register_operand" "0,x")
20725           (match_operand:MODEF 3 "register_operand" "x,x")))]
20726   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20727   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20728   [(set_attr "type" "sse4arg")])
20729
20730 ;; These versions of the min/max patterns are intentionally ignorant of
20731 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20732 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20733 ;; are undefined in this condition, we're certain this is correct.
20734
20735 (define_insn "*avx_<code><mode>3"
20736   [(set (match_operand:MODEF 0 "register_operand" "=x")
20737         (smaxmin:MODEF
20738           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20739           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20740   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20741   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20742   [(set_attr "type" "sseadd")
20743    (set_attr "prefix" "vex")
20744    (set_attr "mode" "<MODE>")])
20745
20746 (define_insn "<code><mode>3"
20747   [(set (match_operand:MODEF 0 "register_operand" "=x")
20748         (smaxmin:MODEF
20749           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20750           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20751   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20752   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20753   [(set_attr "type" "sseadd")
20754    (set_attr "mode" "<MODE>")])
20755
20756 ;; These versions of the min/max patterns implement exactly the operations
20757 ;;   min = (op1 < op2 ? op1 : op2)
20758 ;;   max = (!(op1 < op2) ? op1 : op2)
20759 ;; Their operands are not commutative, and thus they may be used in the
20760 ;; presence of -0.0 and NaN.
20761
20762 (define_insn "*avx_ieee_smin<mode>3"
20763   [(set (match_operand:MODEF 0 "register_operand" "=x")
20764         (unspec:MODEF
20765           [(match_operand:MODEF 1 "register_operand" "x")
20766            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20767          UNSPEC_IEEE_MIN))]
20768   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20769   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20770   [(set_attr "type" "sseadd")
20771    (set_attr "prefix" "vex")
20772    (set_attr "mode" "<MODE>")])
20773
20774 (define_insn "*ieee_smin<mode>3"
20775   [(set (match_operand:MODEF 0 "register_operand" "=x")
20776         (unspec:MODEF
20777           [(match_operand:MODEF 1 "register_operand" "0")
20778            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20779          UNSPEC_IEEE_MIN))]
20780   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20781   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20782   [(set_attr "type" "sseadd")
20783    (set_attr "mode" "<MODE>")])
20784
20785 (define_insn "*avx_ieee_smax<mode>3"
20786   [(set (match_operand:MODEF 0 "register_operand" "=x")
20787         (unspec:MODEF
20788           [(match_operand:MODEF 1 "register_operand" "0")
20789            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20790          UNSPEC_IEEE_MAX))]
20791   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20792   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20793   [(set_attr "type" "sseadd")
20794    (set_attr "prefix" "vex")
20795    (set_attr "mode" "<MODE>")])
20796
20797 (define_insn "*ieee_smax<mode>3"
20798   [(set (match_operand:MODEF 0 "register_operand" "=x")
20799         (unspec:MODEF
20800           [(match_operand:MODEF 1 "register_operand" "0")
20801            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20802          UNSPEC_IEEE_MAX))]
20803   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20804   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20805   [(set_attr "type" "sseadd")
20806    (set_attr "mode" "<MODE>")])
20807
20808 ;; Make two stack loads independent:
20809 ;;   fld aa              fld aa
20810 ;;   fld %st(0)     ->   fld bb
20811 ;;   fmul bb             fmul %st(1), %st
20812 ;;
20813 ;; Actually we only match the last two instructions for simplicity.
20814 (define_peephole2
20815   [(set (match_operand 0 "fp_register_operand" "")
20816         (match_operand 1 "fp_register_operand" ""))
20817    (set (match_dup 0)
20818         (match_operator 2 "binary_fp_operator"
20819            [(match_dup 0)
20820             (match_operand 3 "memory_operand" "")]))]
20821   "REGNO (operands[0]) != REGNO (operands[1])"
20822   [(set (match_dup 0) (match_dup 3))
20823    (set (match_dup 0) (match_dup 4))]
20824
20825   ;; The % modifier is not operational anymore in peephole2's, so we have to
20826   ;; swap the operands manually in the case of addition and multiplication.
20827   "if (COMMUTATIVE_ARITH_P (operands[2]))
20828      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20829                                  operands[0], operands[1]);
20830    else
20831      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20832                                  operands[1], operands[0]);")
20833
20834 ;; Conditional addition patterns
20835 (define_expand "add<mode>cc"
20836   [(match_operand:SWI 0 "register_operand" "")
20837    (match_operand 1 "comparison_operator" "")
20838    (match_operand:SWI 2 "register_operand" "")
20839    (match_operand:SWI 3 "const_int_operand" "")]
20840   ""
20841   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20842
20843 \f
20844 ;; Misc patterns (?)
20845
20846 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20847 ;; Otherwise there will be nothing to keep
20848 ;;
20849 ;; [(set (reg ebp) (reg esp))]
20850 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20851 ;;  (clobber (eflags)]
20852 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20853 ;;
20854 ;; in proper program order.
20855 (define_insn "pro_epilogue_adjust_stack_1"
20856   [(set (match_operand:SI 0 "register_operand" "=r,r")
20857         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20858                  (match_operand:SI 2 "immediate_operand" "i,i")))
20859    (clobber (reg:CC FLAGS_REG))
20860    (clobber (mem:BLK (scratch)))]
20861   "!TARGET_64BIT"
20862 {
20863   switch (get_attr_type (insn))
20864     {
20865     case TYPE_IMOV:
20866       return "mov{l}\t{%1, %0|%0, %1}";
20867
20868     case TYPE_ALU:
20869       if (CONST_INT_P (operands[2])
20870           && (INTVAL (operands[2]) == 128
20871               || (INTVAL (operands[2]) < 0
20872                   && INTVAL (operands[2]) != -128)))
20873         {
20874           operands[2] = GEN_INT (-INTVAL (operands[2]));
20875           return "sub{l}\t{%2, %0|%0, %2}";
20876         }
20877       return "add{l}\t{%2, %0|%0, %2}";
20878
20879     case TYPE_LEA:
20880       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20881       return "lea{l}\t{%a2, %0|%0, %a2}";
20882
20883     default:
20884       gcc_unreachable ();
20885     }
20886 }
20887   [(set (attr "type")
20888         (cond [(and (eq_attr "alternative" "0") 
20889                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20890                  (const_string "alu")
20891                (match_operand:SI 2 "const0_operand" "")
20892                  (const_string "imov")
20893               ]
20894               (const_string "lea")))
20895    (set (attr "length_immediate")
20896         (cond [(eq_attr "type" "imov")
20897                  (const_string "0")
20898                (and (eq_attr "type" "alu")
20899                     (match_operand 2 "const128_operand" ""))
20900                  (const_string "1")
20901               ]
20902               (const_string "*")))
20903    (set_attr "mode" "SI")])
20904
20905 (define_insn "pro_epilogue_adjust_stack_rex64"
20906   [(set (match_operand:DI 0 "register_operand" "=r,r")
20907         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20908                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20909    (clobber (reg:CC FLAGS_REG))
20910    (clobber (mem:BLK (scratch)))]
20911   "TARGET_64BIT"
20912 {
20913   switch (get_attr_type (insn))
20914     {
20915     case TYPE_IMOV:
20916       return "mov{q}\t{%1, %0|%0, %1}";
20917
20918     case TYPE_ALU:
20919       if (CONST_INT_P (operands[2])
20920           /* Avoid overflows.  */
20921           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20922           && (INTVAL (operands[2]) == 128
20923               || (INTVAL (operands[2]) < 0
20924                   && INTVAL (operands[2]) != -128)))
20925         {
20926           operands[2] = GEN_INT (-INTVAL (operands[2]));
20927           return "sub{q}\t{%2, %0|%0, %2}";
20928         }
20929       return "add{q}\t{%2, %0|%0, %2}";
20930
20931     case TYPE_LEA:
20932       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20933       return "lea{q}\t{%a2, %0|%0, %a2}";
20934
20935     default:
20936       gcc_unreachable ();
20937     }
20938 }
20939   [(set (attr "type")
20940         (cond [(and (eq_attr "alternative" "0")
20941                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20942                  (const_string "alu")
20943                (match_operand:DI 2 "const0_operand" "")
20944                  (const_string "imov")
20945               ]
20946               (const_string "lea")))
20947    (set (attr "length_immediate")
20948         (cond [(eq_attr "type" "imov")
20949                  (const_string "0")
20950                (and (eq_attr "type" "alu")
20951                     (match_operand 2 "const128_operand" ""))
20952                  (const_string "1")
20953               ]
20954               (const_string "*")))
20955    (set_attr "mode" "DI")])
20956
20957 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20958   [(set (match_operand:DI 0 "register_operand" "=r,r")
20959         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20960                  (match_operand:DI 3 "immediate_operand" "i,i")))
20961    (use (match_operand:DI 2 "register_operand" "r,r"))
20962    (clobber (reg:CC FLAGS_REG))
20963    (clobber (mem:BLK (scratch)))]
20964   "TARGET_64BIT"
20965 {
20966   switch (get_attr_type (insn))
20967     {
20968     case TYPE_ALU:
20969       return "add{q}\t{%2, %0|%0, %2}";
20970
20971     case TYPE_LEA:
20972       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20973       return "lea{q}\t{%a2, %0|%0, %a2}";
20974
20975     default:
20976       gcc_unreachable ();
20977     }
20978 }
20979   [(set_attr "type" "alu,lea")
20980    (set_attr "mode" "DI")])
20981
20982 (define_insn "allocate_stack_worker_32"
20983   [(set (match_operand:SI 0 "register_operand" "=a")
20984         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20985                             UNSPECV_STACK_PROBE))
20986    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20987    (clobber (reg:CC FLAGS_REG))]
20988   "!TARGET_64BIT && TARGET_STACK_PROBE"
20989   "call\t___chkstk"
20990   [(set_attr "type" "multi")
20991    (set_attr "length" "5")])
20992
20993 (define_insn "allocate_stack_worker_64"
20994   [(set (match_operand:DI 0 "register_operand" "=a")
20995         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20996                             UNSPECV_STACK_PROBE))
20997    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20998    (clobber (reg:DI R10_REG))
20999    (clobber (reg:DI R11_REG))
21000    (clobber (reg:CC FLAGS_REG))]
21001   "TARGET_64BIT && TARGET_STACK_PROBE"
21002   "call\t___chkstk"
21003   [(set_attr "type" "multi")
21004    (set_attr "length" "5")])
21005
21006 (define_expand "allocate_stack"
21007   [(match_operand 0 "register_operand" "")
21008    (match_operand 1 "general_operand" "")]
21009   "TARGET_STACK_PROBE"
21010 {
21011   rtx x;
21012
21013 #ifndef CHECK_STACK_LIMIT
21014 #define CHECK_STACK_LIMIT 0
21015 #endif
21016
21017   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
21018       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
21019     {
21020       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
21021                                stack_pointer_rtx, 0, OPTAB_DIRECT);
21022       if (x != stack_pointer_rtx)
21023         emit_move_insn (stack_pointer_rtx, x);
21024     }
21025   else
21026     {
21027       x = copy_to_mode_reg (Pmode, operands[1]);
21028       if (TARGET_64BIT)
21029         x = gen_allocate_stack_worker_64 (x, x);
21030       else
21031         x = gen_allocate_stack_worker_32 (x, x);
21032       emit_insn (x);
21033     }
21034
21035   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
21036   DONE;
21037 })
21038
21039 (define_expand "builtin_setjmp_receiver"
21040   [(label_ref (match_operand 0 "" ""))]
21041   "!TARGET_64BIT && flag_pic"
21042 {
21043 #if TARGET_MACHO
21044   if (TARGET_MACHO)
21045     {
21046       rtx xops[3];
21047       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
21048       rtx label_rtx = gen_label_rtx ();
21049       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
21050       xops[0] = xops[1] = picreg;
21051       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
21052       ix86_expand_binary_operator (MINUS, SImode, xops);
21053     }
21054   else
21055 #endif
21056     emit_insn (gen_set_got (pic_offset_table_rtx));
21057   DONE;
21058 })
21059 \f
21060 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
21061
21062 (define_split
21063   [(set (match_operand 0 "register_operand" "")
21064         (match_operator 3 "promotable_binary_operator"
21065            [(match_operand 1 "register_operand" "")
21066             (match_operand 2 "aligned_operand" "")]))
21067    (clobber (reg:CC FLAGS_REG))]
21068   "! TARGET_PARTIAL_REG_STALL && reload_completed
21069    && ((GET_MODE (operands[0]) == HImode
21070         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
21071             /* ??? next two lines just !satisfies_constraint_K (...) */
21072             || !CONST_INT_P (operands[2])
21073             || satisfies_constraint_K (operands[2])))
21074        || (GET_MODE (operands[0]) == QImode
21075            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
21076   [(parallel [(set (match_dup 0)
21077                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21078               (clobber (reg:CC FLAGS_REG))])]
21079   "operands[0] = gen_lowpart (SImode, operands[0]);
21080    operands[1] = gen_lowpart (SImode, operands[1]);
21081    if (GET_CODE (operands[3]) != ASHIFT)
21082      operands[2] = gen_lowpart (SImode, operands[2]);
21083    PUT_MODE (operands[3], SImode);")
21084
21085 ; Promote the QImode tests, as i386 has encoding of the AND
21086 ; instruction with 32-bit sign-extended immediate and thus the
21087 ; instruction size is unchanged, except in the %eax case for
21088 ; which it is increased by one byte, hence the ! optimize_size.
21089 (define_split
21090   [(set (match_operand 0 "flags_reg_operand" "")
21091         (match_operator 2 "compare_operator"
21092           [(and (match_operand 3 "aligned_operand" "")
21093                 (match_operand 4 "const_int_operand" ""))
21094            (const_int 0)]))
21095    (set (match_operand 1 "register_operand" "")
21096         (and (match_dup 3) (match_dup 4)))]
21097   "! TARGET_PARTIAL_REG_STALL && reload_completed
21098    && optimize_insn_for_speed_p ()
21099    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
21100        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21101    /* Ensure that the operand will remain sign-extended immediate.  */
21102    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
21103   [(parallel [(set (match_dup 0)
21104                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21105                                     (const_int 0)]))
21106               (set (match_dup 1)
21107                    (and:SI (match_dup 3) (match_dup 4)))])]
21108 {
21109   operands[4]
21110     = gen_int_mode (INTVAL (operands[4])
21111                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21112   operands[1] = gen_lowpart (SImode, operands[1]);
21113   operands[3] = gen_lowpart (SImode, operands[3]);
21114 })
21115
21116 ; Don't promote the QImode tests, as i386 doesn't have encoding of
21117 ; the TEST instruction with 32-bit sign-extended immediate and thus
21118 ; the instruction size would at least double, which is not what we
21119 ; want even with ! optimize_size.
21120 (define_split
21121   [(set (match_operand 0 "flags_reg_operand" "")
21122         (match_operator 1 "compare_operator"
21123           [(and (match_operand:HI 2 "aligned_operand" "")
21124                 (match_operand:HI 3 "const_int_operand" ""))
21125            (const_int 0)]))]
21126   "! TARGET_PARTIAL_REG_STALL && reload_completed
21127    && ! TARGET_FAST_PREFIX
21128    && optimize_insn_for_speed_p ()
21129    /* Ensure that the operand will remain sign-extended immediate.  */
21130    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
21131   [(set (match_dup 0)
21132         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21133                          (const_int 0)]))]
21134 {
21135   operands[3]
21136     = gen_int_mode (INTVAL (operands[3])
21137                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21138   operands[2] = gen_lowpart (SImode, operands[2]);
21139 })
21140
21141 (define_split
21142   [(set (match_operand 0 "register_operand" "")
21143         (neg (match_operand 1 "register_operand" "")))
21144    (clobber (reg:CC FLAGS_REG))]
21145   "! TARGET_PARTIAL_REG_STALL && reload_completed
21146    && (GET_MODE (operands[0]) == HImode
21147        || (GET_MODE (operands[0]) == QImode
21148            && (TARGET_PROMOTE_QImode
21149                || optimize_insn_for_size_p ())))"
21150   [(parallel [(set (match_dup 0)
21151                    (neg:SI (match_dup 1)))
21152               (clobber (reg:CC FLAGS_REG))])]
21153   "operands[0] = gen_lowpart (SImode, operands[0]);
21154    operands[1] = gen_lowpart (SImode, operands[1]);")
21155
21156 (define_split
21157   [(set (match_operand 0 "register_operand" "")
21158         (not (match_operand 1 "register_operand" "")))]
21159   "! TARGET_PARTIAL_REG_STALL && reload_completed
21160    && (GET_MODE (operands[0]) == HImode
21161        || (GET_MODE (operands[0]) == QImode
21162            && (TARGET_PROMOTE_QImode
21163                || optimize_insn_for_size_p ())))"
21164   [(set (match_dup 0)
21165         (not:SI (match_dup 1)))]
21166   "operands[0] = gen_lowpart (SImode, operands[0]);
21167    operands[1] = gen_lowpart (SImode, operands[1]);")
21168
21169 (define_split
21170   [(set (match_operand 0 "register_operand" "")
21171         (if_then_else (match_operator 1 "comparison_operator"
21172                                 [(reg FLAGS_REG) (const_int 0)])
21173                       (match_operand 2 "register_operand" "")
21174                       (match_operand 3 "register_operand" "")))]
21175   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21176    && (GET_MODE (operands[0]) == HImode
21177        || (GET_MODE (operands[0]) == QImode
21178            && (TARGET_PROMOTE_QImode
21179                || optimize_insn_for_size_p ())))"
21180   [(set (match_dup 0)
21181         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21182   "operands[0] = gen_lowpart (SImode, operands[0]);
21183    operands[2] = gen_lowpart (SImode, operands[2]);
21184    operands[3] = gen_lowpart (SImode, operands[3]);")
21185
21186 \f
21187 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
21188 ;; transform a complex memory operation into two memory to register operations.
21189
21190 ;; Don't push memory operands
21191 (define_peephole2
21192   [(set (match_operand:SI 0 "push_operand" "")
21193         (match_operand:SI 1 "memory_operand" ""))
21194    (match_scratch:SI 2 "r")]
21195   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21196    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21197   [(set (match_dup 2) (match_dup 1))
21198    (set (match_dup 0) (match_dup 2))]
21199   "")
21200
21201 (define_peephole2
21202   [(set (match_operand:DI 0 "push_operand" "")
21203         (match_operand:DI 1 "memory_operand" ""))
21204    (match_scratch:DI 2 "r")]
21205   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21206    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21207   [(set (match_dup 2) (match_dup 1))
21208    (set (match_dup 0) (match_dup 2))]
21209   "")
21210
21211 ;; We need to handle SFmode only, because DFmode and XFmode is split to
21212 ;; SImode pushes.
21213 (define_peephole2
21214   [(set (match_operand:SF 0 "push_operand" "")
21215         (match_operand:SF 1 "memory_operand" ""))
21216    (match_scratch:SF 2 "r")]
21217   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21218    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21219   [(set (match_dup 2) (match_dup 1))
21220    (set (match_dup 0) (match_dup 2))]
21221   "")
21222
21223 (define_peephole2
21224   [(set (match_operand:HI 0 "push_operand" "")
21225         (match_operand:HI 1 "memory_operand" ""))
21226    (match_scratch:HI 2 "r")]
21227   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21228    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21229   [(set (match_dup 2) (match_dup 1))
21230    (set (match_dup 0) (match_dup 2))]
21231   "")
21232
21233 (define_peephole2
21234   [(set (match_operand:QI 0 "push_operand" "")
21235         (match_operand:QI 1 "memory_operand" ""))
21236    (match_scratch:QI 2 "q")]
21237   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21238    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21239   [(set (match_dup 2) (match_dup 1))
21240    (set (match_dup 0) (match_dup 2))]
21241   "")
21242
21243 ;; Don't move an immediate directly to memory when the instruction
21244 ;; gets too big.
21245 (define_peephole2
21246   [(match_scratch:SI 1 "r")
21247    (set (match_operand:SI 0 "memory_operand" "")
21248         (const_int 0))]
21249   "optimize_insn_for_speed_p ()
21250    && ! TARGET_USE_MOV0
21251    && TARGET_SPLIT_LONG_MOVES
21252    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21253    && peep2_regno_dead_p (0, FLAGS_REG)"
21254   [(parallel [(set (match_dup 1) (const_int 0))
21255               (clobber (reg:CC FLAGS_REG))])
21256    (set (match_dup 0) (match_dup 1))]
21257   "")
21258
21259 (define_peephole2
21260   [(match_scratch:HI 1 "r")
21261    (set (match_operand:HI 0 "memory_operand" "")
21262         (const_int 0))]
21263   "optimize_insn_for_speed_p ()
21264    && ! TARGET_USE_MOV0
21265    && TARGET_SPLIT_LONG_MOVES
21266    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21267    && peep2_regno_dead_p (0, FLAGS_REG)"
21268   [(parallel [(set (match_dup 2) (const_int 0))
21269               (clobber (reg:CC FLAGS_REG))])
21270    (set (match_dup 0) (match_dup 1))]
21271   "operands[2] = gen_lowpart (SImode, operands[1]);")
21272
21273 (define_peephole2
21274   [(match_scratch:QI 1 "q")
21275    (set (match_operand:QI 0 "memory_operand" "")
21276         (const_int 0))]
21277   "optimize_insn_for_speed_p ()
21278    && ! TARGET_USE_MOV0
21279    && TARGET_SPLIT_LONG_MOVES
21280    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21281    && peep2_regno_dead_p (0, FLAGS_REG)"
21282   [(parallel [(set (match_dup 2) (const_int 0))
21283               (clobber (reg:CC FLAGS_REG))])
21284    (set (match_dup 0) (match_dup 1))]
21285   "operands[2] = gen_lowpart (SImode, operands[1]);")
21286
21287 (define_peephole2
21288   [(match_scratch:SI 2 "r")
21289    (set (match_operand:SI 0 "memory_operand" "")
21290         (match_operand:SI 1 "immediate_operand" ""))]
21291   "optimize_insn_for_speed_p ()
21292    && TARGET_SPLIT_LONG_MOVES
21293    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21294   [(set (match_dup 2) (match_dup 1))
21295    (set (match_dup 0) (match_dup 2))]
21296   "")
21297
21298 (define_peephole2
21299   [(match_scratch:HI 2 "r")
21300    (set (match_operand:HI 0 "memory_operand" "")
21301         (match_operand:HI 1 "immediate_operand" ""))]
21302   "optimize_insn_for_speed_p ()
21303    && TARGET_SPLIT_LONG_MOVES
21304    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21305   [(set (match_dup 2) (match_dup 1))
21306    (set (match_dup 0) (match_dup 2))]
21307   "")
21308
21309 (define_peephole2
21310   [(match_scratch:QI 2 "q")
21311    (set (match_operand:QI 0 "memory_operand" "")
21312         (match_operand:QI 1 "immediate_operand" ""))]
21313   "optimize_insn_for_speed_p ()
21314    && TARGET_SPLIT_LONG_MOVES
21315    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21316   [(set (match_dup 2) (match_dup 1))
21317    (set (match_dup 0) (match_dup 2))]
21318   "")
21319
21320 ;; Don't compare memory with zero, load and use a test instead.
21321 (define_peephole2
21322   [(set (match_operand 0 "flags_reg_operand" "")
21323         (match_operator 1 "compare_operator"
21324           [(match_operand:SI 2 "memory_operand" "")
21325            (const_int 0)]))
21326    (match_scratch:SI 3 "r")]
21327   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
21328   [(set (match_dup 3) (match_dup 2))
21329    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
21330   "")
21331
21332 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
21333 ;; Don't split NOTs with a displacement operand, because resulting XOR
21334 ;; will not be pairable anyway.
21335 ;;
21336 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
21337 ;; represented using a modRM byte.  The XOR replacement is long decoded,
21338 ;; so this split helps here as well.
21339 ;;
21340 ;; Note: Can't do this as a regular split because we can't get proper
21341 ;; lifetime information then.
21342
21343 (define_peephole2
21344   [(set (match_operand:SI 0 "nonimmediate_operand" "")
21345         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
21346   "optimize_insn_for_speed_p ()
21347    && ((TARGET_NOT_UNPAIRABLE
21348         && (!MEM_P (operands[0])
21349             || !memory_displacement_operand (operands[0], SImode)))
21350        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21351    && peep2_regno_dead_p (0, FLAGS_REG)"
21352   [(parallel [(set (match_dup 0)
21353                    (xor:SI (match_dup 1) (const_int -1)))
21354               (clobber (reg:CC FLAGS_REG))])]
21355   "")
21356
21357 (define_peephole2
21358   [(set (match_operand:HI 0 "nonimmediate_operand" "")
21359         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
21360   "optimize_insn_for_speed_p ()
21361    && ((TARGET_NOT_UNPAIRABLE
21362         && (!MEM_P (operands[0])
21363             || !memory_displacement_operand (operands[0], HImode)))
21364        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21365    && peep2_regno_dead_p (0, FLAGS_REG)"
21366   [(parallel [(set (match_dup 0)
21367                    (xor:HI (match_dup 1) (const_int -1)))
21368               (clobber (reg:CC FLAGS_REG))])]
21369   "")
21370
21371 (define_peephole2
21372   [(set (match_operand:QI 0 "nonimmediate_operand" "")
21373         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
21374   "optimize_insn_for_speed_p ()
21375    && ((TARGET_NOT_UNPAIRABLE
21376         && (!MEM_P (operands[0])
21377             || !memory_displacement_operand (operands[0], QImode)))
21378        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21379    && peep2_regno_dead_p (0, FLAGS_REG)"
21380   [(parallel [(set (match_dup 0)
21381                    (xor:QI (match_dup 1) (const_int -1)))
21382               (clobber (reg:CC FLAGS_REG))])]
21383   "")
21384
21385 ;; Non pairable "test imm, reg" instructions can be translated to
21386 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
21387 ;; byte opcode instead of two, have a short form for byte operands),
21388 ;; so do it for other CPUs as well.  Given that the value was dead,
21389 ;; this should not create any new dependencies.  Pass on the sub-word
21390 ;; versions if we're concerned about partial register stalls.
21391
21392 (define_peephole2
21393   [(set (match_operand 0 "flags_reg_operand" "")
21394         (match_operator 1 "compare_operator"
21395           [(and:SI (match_operand:SI 2 "register_operand" "")
21396                    (match_operand:SI 3 "immediate_operand" ""))
21397            (const_int 0)]))]
21398   "ix86_match_ccmode (insn, CCNOmode)
21399    && (true_regnum (operands[2]) != AX_REG
21400        || satisfies_constraint_K (operands[3]))
21401    && peep2_reg_dead_p (1, operands[2])"
21402   [(parallel
21403      [(set (match_dup 0)
21404            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21405                             (const_int 0)]))
21406       (set (match_dup 2)
21407            (and:SI (match_dup 2) (match_dup 3)))])]
21408   "")
21409
21410 ;; We don't need to handle HImode case, because it will be promoted to SImode
21411 ;; on ! TARGET_PARTIAL_REG_STALL
21412
21413 (define_peephole2
21414   [(set (match_operand 0 "flags_reg_operand" "")
21415         (match_operator 1 "compare_operator"
21416           [(and:QI (match_operand:QI 2 "register_operand" "")
21417                    (match_operand:QI 3 "immediate_operand" ""))
21418            (const_int 0)]))]
21419   "! TARGET_PARTIAL_REG_STALL
21420    && ix86_match_ccmode (insn, CCNOmode)
21421    && true_regnum (operands[2]) != AX_REG
21422    && peep2_reg_dead_p (1, operands[2])"
21423   [(parallel
21424      [(set (match_dup 0)
21425            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21426                             (const_int 0)]))
21427       (set (match_dup 2)
21428            (and:QI (match_dup 2) (match_dup 3)))])]
21429   "")
21430
21431 (define_peephole2
21432   [(set (match_operand 0 "flags_reg_operand" "")
21433         (match_operator 1 "compare_operator"
21434           [(and:SI
21435              (zero_extract:SI
21436                (match_operand 2 "ext_register_operand" "")
21437                (const_int 8)
21438                (const_int 8))
21439              (match_operand 3 "const_int_operand" ""))
21440            (const_int 0)]))]
21441   "! TARGET_PARTIAL_REG_STALL
21442    && ix86_match_ccmode (insn, CCNOmode)
21443    && true_regnum (operands[2]) != AX_REG
21444    && peep2_reg_dead_p (1, operands[2])"
21445   [(parallel [(set (match_dup 0)
21446                    (match_op_dup 1
21447                      [(and:SI
21448                         (zero_extract:SI
21449                           (match_dup 2)
21450                           (const_int 8)
21451                           (const_int 8))
21452                         (match_dup 3))
21453                       (const_int 0)]))
21454               (set (zero_extract:SI (match_dup 2)
21455                                     (const_int 8)
21456                                     (const_int 8))
21457                    (and:SI
21458                      (zero_extract:SI
21459                        (match_dup 2)
21460                        (const_int 8)
21461                        (const_int 8))
21462                      (match_dup 3)))])]
21463   "")
21464
21465 ;; Don't do logical operations with memory inputs.
21466 (define_peephole2
21467   [(match_scratch:SI 2 "r")
21468    (parallel [(set (match_operand:SI 0 "register_operand" "")
21469                    (match_operator:SI 3 "arith_or_logical_operator"
21470                      [(match_dup 0)
21471                       (match_operand:SI 1 "memory_operand" "")]))
21472               (clobber (reg:CC FLAGS_REG))])]
21473   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21474   [(set (match_dup 2) (match_dup 1))
21475    (parallel [(set (match_dup 0)
21476                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21477               (clobber (reg:CC FLAGS_REG))])]
21478   "")
21479
21480 (define_peephole2
21481   [(match_scratch:SI 2 "r")
21482    (parallel [(set (match_operand:SI 0 "register_operand" "")
21483                    (match_operator:SI 3 "arith_or_logical_operator"
21484                      [(match_operand:SI 1 "memory_operand" "")
21485                       (match_dup 0)]))
21486               (clobber (reg:CC FLAGS_REG))])]
21487   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21488   [(set (match_dup 2) (match_dup 1))
21489    (parallel [(set (match_dup 0)
21490                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21491               (clobber (reg:CC FLAGS_REG))])]
21492   "")
21493
21494 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
21495 ;; refers to the destination of the load!
21496
21497 (define_peephole2
21498   [(set (match_operand:SI 0 "register_operand" "")
21499         (match_operand:SI 1 "register_operand" ""))
21500    (parallel [(set (match_dup 0)
21501                    (match_operator:SI 3 "commutative_operator"
21502                      [(match_dup 0)
21503                       (match_operand:SI 2 "memory_operand" "")]))
21504               (clobber (reg:CC FLAGS_REG))])]
21505   "REGNO (operands[0]) != REGNO (operands[1])
21506    && GENERAL_REGNO_P (REGNO (operands[0]))
21507    && GENERAL_REGNO_P (REGNO (operands[1]))"
21508   [(set (match_dup 0) (match_dup 4))
21509    (parallel [(set (match_dup 0)
21510                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21511               (clobber (reg:CC FLAGS_REG))])]
21512   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21513
21514 (define_peephole2
21515   [(set (match_operand 0 "register_operand" "")
21516         (match_operand 1 "register_operand" ""))
21517    (set (match_dup 0)
21518                    (match_operator 3 "commutative_operator"
21519                      [(match_dup 0)
21520                       (match_operand 2 "memory_operand" "")]))]
21521   "REGNO (operands[0]) != REGNO (operands[1])
21522    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
21523        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21524   [(set (match_dup 0) (match_dup 2))
21525    (set (match_dup 0)
21526         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21527   "")
21528
21529 ; Don't do logical operations with memory outputs
21530 ;
21531 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21532 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
21533 ; the same decoder scheduling characteristics as the original.
21534
21535 (define_peephole2
21536   [(match_scratch:SI 2 "r")
21537    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21538                    (match_operator:SI 3 "arith_or_logical_operator"
21539                      [(match_dup 0)
21540                       (match_operand:SI 1 "nonmemory_operand" "")]))
21541               (clobber (reg:CC FLAGS_REG))])]
21542   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21543   [(set (match_dup 2) (match_dup 0))
21544    (parallel [(set (match_dup 2)
21545                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21546               (clobber (reg:CC FLAGS_REG))])
21547    (set (match_dup 0) (match_dup 2))]
21548   "")
21549
21550 (define_peephole2
21551   [(match_scratch:SI 2 "r")
21552    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21553                    (match_operator:SI 3 "arith_or_logical_operator"
21554                      [(match_operand:SI 1 "nonmemory_operand" "")
21555                       (match_dup 0)]))
21556               (clobber (reg:CC FLAGS_REG))])]
21557   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21558   [(set (match_dup 2) (match_dup 0))
21559    (parallel [(set (match_dup 2)
21560                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21561               (clobber (reg:CC FLAGS_REG))])
21562    (set (match_dup 0) (match_dup 2))]
21563   "")
21564
21565 ;; Attempt to always use XOR for zeroing registers.
21566 (define_peephole2
21567   [(set (match_operand 0 "register_operand" "")
21568         (match_operand 1 "const0_operand" ""))]
21569   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21570    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21571    && GENERAL_REG_P (operands[0])
21572    && peep2_regno_dead_p (0, FLAGS_REG)"
21573   [(parallel [(set (match_dup 0) (const_int 0))
21574               (clobber (reg:CC FLAGS_REG))])]
21575 {
21576   operands[0] = gen_lowpart (word_mode, operands[0]);
21577 })
21578
21579 (define_peephole2
21580   [(set (strict_low_part (match_operand 0 "register_operand" ""))
21581         (const_int 0))]
21582   "(GET_MODE (operands[0]) == QImode
21583     || GET_MODE (operands[0]) == HImode)
21584    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21585    && peep2_regno_dead_p (0, FLAGS_REG)"
21586   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21587               (clobber (reg:CC FLAGS_REG))])])
21588
21589 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21590 (define_peephole2
21591   [(set (match_operand 0 "register_operand" "")
21592         (const_int -1))]
21593   "(GET_MODE (operands[0]) == HImode
21594     || GET_MODE (operands[0]) == SImode
21595     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21596    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21597    && peep2_regno_dead_p (0, FLAGS_REG)"
21598   [(parallel [(set (match_dup 0) (const_int -1))
21599               (clobber (reg:CC FLAGS_REG))])]
21600   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21601                               operands[0]);")
21602
21603 ;; Attempt to convert simple leas to adds. These can be created by
21604 ;; move expanders.
21605 (define_peephole2
21606   [(set (match_operand:SI 0 "register_operand" "")
21607         (plus:SI (match_dup 0)
21608                  (match_operand:SI 1 "nonmemory_operand" "")))]
21609   "peep2_regno_dead_p (0, FLAGS_REG)"
21610   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21611               (clobber (reg:CC FLAGS_REG))])]
21612   "")
21613
21614 (define_peephole2
21615   [(set (match_operand:SI 0 "register_operand" "")
21616         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21617                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21618   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21619   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21620               (clobber (reg:CC FLAGS_REG))])]
21621   "operands[2] = gen_lowpart (SImode, operands[2]);")
21622
21623 (define_peephole2
21624   [(set (match_operand:DI 0 "register_operand" "")
21625         (plus:DI (match_dup 0)
21626                  (match_operand:DI 1 "x86_64_general_operand" "")))]
21627   "peep2_regno_dead_p (0, FLAGS_REG)"
21628   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21629               (clobber (reg:CC FLAGS_REG))])]
21630   "")
21631
21632 (define_peephole2
21633   [(set (match_operand:SI 0 "register_operand" "")
21634         (mult:SI (match_dup 0)
21635                  (match_operand:SI 1 "const_int_operand" "")))]
21636   "exact_log2 (INTVAL (operands[1])) >= 0
21637    && peep2_regno_dead_p (0, FLAGS_REG)"
21638   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21639               (clobber (reg:CC FLAGS_REG))])]
21640   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21641
21642 (define_peephole2
21643   [(set (match_operand:DI 0 "register_operand" "")
21644         (mult:DI (match_dup 0)
21645                  (match_operand:DI 1 "const_int_operand" "")))]
21646   "exact_log2 (INTVAL (operands[1])) >= 0
21647    && peep2_regno_dead_p (0, FLAGS_REG)"
21648   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21649               (clobber (reg:CC FLAGS_REG))])]
21650   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21651
21652 (define_peephole2
21653   [(set (match_operand:SI 0 "register_operand" "")
21654         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21655                    (match_operand:DI 2 "const_int_operand" "")) 0))]
21656   "exact_log2 (INTVAL (operands[2])) >= 0
21657    && REGNO (operands[0]) == REGNO (operands[1])
21658    && peep2_regno_dead_p (0, FLAGS_REG)"
21659   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21660               (clobber (reg:CC FLAGS_REG))])]
21661   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21662
21663 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21664 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21665 ;; many CPUs it is also faster, since special hardware to avoid esp
21666 ;; dependencies is present.
21667
21668 ;; While some of these conversions may be done using splitters, we use peepholes
21669 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21670
21671 ;; Convert prologue esp subtractions to push.
21672 ;; We need register to push.  In order to keep verify_flow_info happy we have
21673 ;; two choices
21674 ;; - use scratch and clobber it in order to avoid dependencies
21675 ;; - use already live register
21676 ;; We can't use the second way right now, since there is no reliable way how to
21677 ;; verify that given register is live.  First choice will also most likely in
21678 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21679 ;; call clobbered registers are dead.  We may want to use base pointer as an
21680 ;; alternative when no register is available later.
21681
21682 (define_peephole2
21683   [(match_scratch:SI 0 "r")
21684    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21685               (clobber (reg:CC FLAGS_REG))
21686               (clobber (mem:BLK (scratch)))])]
21687   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21688   [(clobber (match_dup 0))
21689    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21690               (clobber (mem:BLK (scratch)))])])
21691
21692 (define_peephole2
21693   [(match_scratch:SI 0 "r")
21694    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21695               (clobber (reg:CC FLAGS_REG))
21696               (clobber (mem:BLK (scratch)))])]
21697   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21698   [(clobber (match_dup 0))
21699    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21700    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21701               (clobber (mem:BLK (scratch)))])])
21702
21703 ;; Convert esp subtractions to push.
21704 (define_peephole2
21705   [(match_scratch:SI 0 "r")
21706    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21707               (clobber (reg:CC FLAGS_REG))])]
21708   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21709   [(clobber (match_dup 0))
21710    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21711
21712 (define_peephole2
21713   [(match_scratch:SI 0 "r")
21714    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21715               (clobber (reg:CC FLAGS_REG))])]
21716   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21717   [(clobber (match_dup 0))
21718    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21719    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21720
21721 ;; Convert epilogue deallocator to pop.
21722 (define_peephole2
21723   [(match_scratch:SI 0 "r")
21724    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21725               (clobber (reg:CC FLAGS_REG))
21726               (clobber (mem:BLK (scratch)))])]
21727   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21728   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21729               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21730               (clobber (mem:BLK (scratch)))])]
21731   "")
21732
21733 ;; Two pops case is tricky, since pop causes dependency on destination register.
21734 ;; We use two registers if available.
21735 (define_peephole2
21736   [(match_scratch:SI 0 "r")
21737    (match_scratch:SI 1 "r")
21738    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21739               (clobber (reg:CC FLAGS_REG))
21740               (clobber (mem:BLK (scratch)))])]
21741   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21742   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21743               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21744               (clobber (mem:BLK (scratch)))])
21745    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21746               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21747   "")
21748
21749 (define_peephole2
21750   [(match_scratch:SI 0 "r")
21751    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21752               (clobber (reg:CC FLAGS_REG))
21753               (clobber (mem:BLK (scratch)))])]
21754   "optimize_insn_for_size_p ()"
21755   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21756               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21757               (clobber (mem:BLK (scratch)))])
21758    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21759               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21760   "")
21761
21762 ;; Convert esp additions to pop.
21763 (define_peephole2
21764   [(match_scratch:SI 0 "r")
21765    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21766               (clobber (reg:CC FLAGS_REG))])]
21767   ""
21768   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21769               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21770   "")
21771
21772 ;; Two pops case is tricky, since pop causes dependency on destination register.
21773 ;; We use two registers if available.
21774 (define_peephole2
21775   [(match_scratch:SI 0 "r")
21776    (match_scratch:SI 1 "r")
21777    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21778               (clobber (reg:CC FLAGS_REG))])]
21779   ""
21780   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21781               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21782    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21783               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21784   "")
21785
21786 (define_peephole2
21787   [(match_scratch:SI 0 "r")
21788    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21789               (clobber (reg:CC FLAGS_REG))])]
21790   "optimize_insn_for_size_p ()"
21791   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21792               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21793    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21794               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21795   "")
21796 \f
21797 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21798 ;; required and register dies.  Similarly for 128 to -128.
21799 (define_peephole2
21800   [(set (match_operand 0 "flags_reg_operand" "")
21801         (match_operator 1 "compare_operator"
21802           [(match_operand 2 "register_operand" "")
21803            (match_operand 3 "const_int_operand" "")]))]
21804   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21805      && incdec_operand (operands[3], GET_MODE (operands[3])))
21806     || (!TARGET_FUSE_CMP_AND_BRANCH
21807         && INTVAL (operands[3]) == 128))
21808    && ix86_match_ccmode (insn, CCGCmode)
21809    && peep2_reg_dead_p (1, operands[2])"
21810   [(parallel [(set (match_dup 0)
21811                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21812               (clobber (match_dup 2))])]
21813   "")
21814 \f
21815 (define_peephole2
21816   [(match_scratch:DI 0 "r")
21817    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21818               (clobber (reg:CC FLAGS_REG))
21819               (clobber (mem:BLK (scratch)))])]
21820   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21821   [(clobber (match_dup 0))
21822    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21823               (clobber (mem:BLK (scratch)))])])
21824
21825 (define_peephole2
21826   [(match_scratch:DI 0 "r")
21827    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21828               (clobber (reg:CC FLAGS_REG))
21829               (clobber (mem:BLK (scratch)))])]
21830   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21831   [(clobber (match_dup 0))
21832    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21833    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21834               (clobber (mem:BLK (scratch)))])])
21835
21836 ;; Convert esp subtractions to push.
21837 (define_peephole2
21838   [(match_scratch:DI 0 "r")
21839    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21840               (clobber (reg:CC FLAGS_REG))])]
21841   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21842   [(clobber (match_dup 0))
21843    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21844
21845 (define_peephole2
21846   [(match_scratch:DI 0 "r")
21847    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21848               (clobber (reg:CC FLAGS_REG))])]
21849   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21850   [(clobber (match_dup 0))
21851    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21852    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21853
21854 ;; Convert epilogue deallocator to pop.
21855 (define_peephole2
21856   [(match_scratch:DI 0 "r")
21857    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21858               (clobber (reg:CC FLAGS_REG))
21859               (clobber (mem:BLK (scratch)))])]
21860   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21861   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21862               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21863               (clobber (mem:BLK (scratch)))])]
21864   "")
21865
21866 ;; Two pops case is tricky, since pop causes dependency on destination register.
21867 ;; We use two registers if available.
21868 (define_peephole2
21869   [(match_scratch:DI 0 "r")
21870    (match_scratch:DI 1 "r")
21871    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21872               (clobber (reg:CC FLAGS_REG))
21873               (clobber (mem:BLK (scratch)))])]
21874   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21875   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21876               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21877               (clobber (mem:BLK (scratch)))])
21878    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21879               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21880   "")
21881
21882 (define_peephole2
21883   [(match_scratch:DI 0 "r")
21884    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21885               (clobber (reg:CC FLAGS_REG))
21886               (clobber (mem:BLK (scratch)))])]
21887   "optimize_insn_for_size_p ()"
21888   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21889               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21890               (clobber (mem:BLK (scratch)))])
21891    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21892               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21893   "")
21894
21895 ;; Convert esp additions to pop.
21896 (define_peephole2
21897   [(match_scratch:DI 0 "r")
21898    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21899               (clobber (reg:CC FLAGS_REG))])]
21900   ""
21901   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21902               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21903   "")
21904
21905 ;; Two pops case is tricky, since pop causes dependency on destination register.
21906 ;; We use two registers if available.
21907 (define_peephole2
21908   [(match_scratch:DI 0 "r")
21909    (match_scratch:DI 1 "r")
21910    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21911               (clobber (reg:CC FLAGS_REG))])]
21912   ""
21913   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21914               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21915    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21916               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21917   "")
21918
21919 (define_peephole2
21920   [(match_scratch:DI 0 "r")
21921    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21922               (clobber (reg:CC FLAGS_REG))])]
21923   "optimize_insn_for_size_p ()"
21924   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21925               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21926    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21927               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21928   "")
21929 \f
21930 ;; Convert imul by three, five and nine into lea
21931 (define_peephole2
21932   [(parallel
21933     [(set (match_operand:SI 0 "register_operand" "")
21934           (mult:SI (match_operand:SI 1 "register_operand" "")
21935                    (match_operand:SI 2 "const_int_operand" "")))
21936      (clobber (reg:CC FLAGS_REG))])]
21937   "INTVAL (operands[2]) == 3
21938    || INTVAL (operands[2]) == 5
21939    || INTVAL (operands[2]) == 9"
21940   [(set (match_dup 0)
21941         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21942                  (match_dup 1)))]
21943   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21944
21945 (define_peephole2
21946   [(parallel
21947     [(set (match_operand:SI 0 "register_operand" "")
21948           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21949                    (match_operand:SI 2 "const_int_operand" "")))
21950      (clobber (reg:CC FLAGS_REG))])]
21951   "optimize_insn_for_speed_p ()
21952    && (INTVAL (operands[2]) == 3
21953        || INTVAL (operands[2]) == 5
21954        || INTVAL (operands[2]) == 9)"
21955   [(set (match_dup 0) (match_dup 1))
21956    (set (match_dup 0)
21957         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21958                  (match_dup 0)))]
21959   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21960
21961 (define_peephole2
21962   [(parallel
21963     [(set (match_operand:DI 0 "register_operand" "")
21964           (mult:DI (match_operand:DI 1 "register_operand" "")
21965                    (match_operand:DI 2 "const_int_operand" "")))
21966      (clobber (reg:CC FLAGS_REG))])]
21967   "TARGET_64BIT
21968    && (INTVAL (operands[2]) == 3
21969        || INTVAL (operands[2]) == 5
21970        || INTVAL (operands[2]) == 9)"
21971   [(set (match_dup 0)
21972         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21973                  (match_dup 1)))]
21974   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21975
21976 (define_peephole2
21977   [(parallel
21978     [(set (match_operand:DI 0 "register_operand" "")
21979           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21980                    (match_operand:DI 2 "const_int_operand" "")))
21981      (clobber (reg:CC FLAGS_REG))])]
21982   "TARGET_64BIT
21983    && optimize_insn_for_speed_p ()
21984    && (INTVAL (operands[2]) == 3
21985        || INTVAL (operands[2]) == 5
21986        || INTVAL (operands[2]) == 9)"
21987   [(set (match_dup 0) (match_dup 1))
21988    (set (match_dup 0)
21989         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21990                  (match_dup 0)))]
21991   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21992
21993 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21994 ;; imul $32bit_imm, reg, reg is direct decoded.
21995 (define_peephole2
21996   [(match_scratch:DI 3 "r")
21997    (parallel [(set (match_operand:DI 0 "register_operand" "")
21998                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21999                             (match_operand:DI 2 "immediate_operand" "")))
22000               (clobber (reg:CC FLAGS_REG))])]
22001   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
22002    && !satisfies_constraint_K (operands[2])"
22003   [(set (match_dup 3) (match_dup 1))
22004    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
22005               (clobber (reg:CC FLAGS_REG))])]
22006 "")
22007
22008 (define_peephole2
22009   [(match_scratch:SI 3 "r")
22010    (parallel [(set (match_operand:SI 0 "register_operand" "")
22011                    (mult:SI (match_operand:SI 1 "memory_operand" "")
22012                             (match_operand:SI 2 "immediate_operand" "")))
22013               (clobber (reg:CC FLAGS_REG))])]
22014   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
22015    && !satisfies_constraint_K (operands[2])"
22016   [(set (match_dup 3) (match_dup 1))
22017    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
22018               (clobber (reg:CC FLAGS_REG))])]
22019 "")
22020
22021 (define_peephole2
22022   [(match_scratch:SI 3 "r")
22023    (parallel [(set (match_operand:DI 0 "register_operand" "")
22024                    (zero_extend:DI
22025                      (mult:SI (match_operand:SI 1 "memory_operand" "")
22026                               (match_operand:SI 2 "immediate_operand" ""))))
22027               (clobber (reg:CC FLAGS_REG))])]
22028   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
22029    && !satisfies_constraint_K (operands[2])"
22030   [(set (match_dup 3) (match_dup 1))
22031    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
22032               (clobber (reg:CC FLAGS_REG))])]
22033 "")
22034
22035 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
22036 ;; Convert it into imul reg, reg
22037 ;; It would be better to force assembler to encode instruction using long
22038 ;; immediate, but there is apparently no way to do so.
22039 (define_peephole2
22040   [(parallel [(set (match_operand:DI 0 "register_operand" "")
22041                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
22042                             (match_operand:DI 2 "const_int_operand" "")))
22043               (clobber (reg:CC FLAGS_REG))])
22044    (match_scratch:DI 3 "r")]
22045   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
22046    && satisfies_constraint_K (operands[2])"
22047   [(set (match_dup 3) (match_dup 2))
22048    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
22049               (clobber (reg:CC FLAGS_REG))])]
22050 {
22051   if (!rtx_equal_p (operands[0], operands[1]))
22052     emit_move_insn (operands[0], operands[1]);
22053 })
22054
22055 (define_peephole2
22056   [(parallel [(set (match_operand:SI 0 "register_operand" "")
22057                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
22058                             (match_operand:SI 2 "const_int_operand" "")))
22059               (clobber (reg:CC FLAGS_REG))])
22060    (match_scratch:SI 3 "r")]
22061   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
22062    && satisfies_constraint_K (operands[2])"
22063   [(set (match_dup 3) (match_dup 2))
22064    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
22065               (clobber (reg:CC FLAGS_REG))])]
22066 {
22067   if (!rtx_equal_p (operands[0], operands[1]))
22068     emit_move_insn (operands[0], operands[1]);
22069 })
22070
22071 (define_peephole2
22072   [(parallel [(set (match_operand:HI 0 "register_operand" "")
22073                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22074                             (match_operand:HI 2 "immediate_operand" "")))
22075               (clobber (reg:CC FLAGS_REG))])
22076    (match_scratch:HI 3 "r")]
22077   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
22078   [(set (match_dup 3) (match_dup 2))
22079    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
22080               (clobber (reg:CC FLAGS_REG))])]
22081 {
22082   if (!rtx_equal_p (operands[0], operands[1]))
22083     emit_move_insn (operands[0], operands[1]);
22084 })
22085
22086 ;; After splitting up read-modify operations, array accesses with memory
22087 ;; operands might end up in form:
22088 ;;  sall    $2, %eax
22089 ;;  movl    4(%esp), %edx
22090 ;;  addl    %edx, %eax
22091 ;; instead of pre-splitting:
22092 ;;  sall    $2, %eax
22093 ;;  addl    4(%esp), %eax
22094 ;; Turn it into:
22095 ;;  movl    4(%esp), %edx
22096 ;;  leal    (%edx,%eax,4), %eax
22097
22098 (define_peephole2
22099   [(parallel [(set (match_operand 0 "register_operand" "")
22100                    (ashift (match_operand 1 "register_operand" "")
22101                            (match_operand 2 "const_int_operand" "")))
22102                (clobber (reg:CC FLAGS_REG))])
22103    (set (match_operand 3 "register_operand")
22104         (match_operand 4 "x86_64_general_operand" ""))
22105    (parallel [(set (match_operand 5 "register_operand" "")
22106                    (plus (match_operand 6 "register_operand" "")
22107                          (match_operand 7 "register_operand" "")))
22108                    (clobber (reg:CC FLAGS_REG))])]
22109   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22110    /* Validate MODE for lea.  */
22111    && ((!TARGET_PARTIAL_REG_STALL
22112         && (GET_MODE (operands[0]) == QImode
22113             || GET_MODE (operands[0]) == HImode))
22114        || GET_MODE (operands[0]) == SImode
22115        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22116    /* We reorder load and the shift.  */
22117    && !rtx_equal_p (operands[1], operands[3])
22118    && !reg_overlap_mentioned_p (operands[0], operands[4])
22119    /* Last PLUS must consist of operand 0 and 3.  */
22120    && !rtx_equal_p (operands[0], operands[3])
22121    && (rtx_equal_p (operands[3], operands[6])
22122        || rtx_equal_p (operands[3], operands[7]))
22123    && (rtx_equal_p (operands[0], operands[6])
22124        || rtx_equal_p (operands[0], operands[7]))
22125    /* The intermediate operand 0 must die or be same as output.  */
22126    && (rtx_equal_p (operands[0], operands[5])
22127        || peep2_reg_dead_p (3, operands[0]))"
22128   [(set (match_dup 3) (match_dup 4))
22129    (set (match_dup 0) (match_dup 1))]
22130 {
22131   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22132   int scale = 1 << INTVAL (operands[2]);
22133   rtx index = gen_lowpart (Pmode, operands[1]);
22134   rtx base = gen_lowpart (Pmode, operands[3]);
22135   rtx dest = gen_lowpart (mode, operands[5]);
22136
22137   operands[1] = gen_rtx_PLUS (Pmode, base,
22138                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22139   if (mode != Pmode)
22140     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22141   operands[0] = dest;
22142 })
22143 \f
22144 ;; Call-value patterns last so that the wildcard operand does not
22145 ;; disrupt insn-recog's switch tables.
22146
22147 (define_insn "*call_value_pop_0"
22148   [(set (match_operand 0 "" "")
22149         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22150               (match_operand:SI 2 "" "")))
22151    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22152                             (match_operand:SI 3 "immediate_operand" "")))]
22153   "!TARGET_64BIT"
22154 {
22155   if (SIBLING_CALL_P (insn))
22156     return "jmp\t%P1";
22157   else
22158     return "call\t%P1";
22159 }
22160   [(set_attr "type" "callv")])
22161
22162 (define_insn "*call_value_pop_1"
22163   [(set (match_operand 0 "" "")
22164         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22165               (match_operand:SI 2 "" "")))
22166    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22167                             (match_operand:SI 3 "immediate_operand" "i")))]
22168   "!TARGET_64BIT"
22169 {
22170   if (constant_call_address_operand (operands[1], Pmode))
22171     {
22172       if (SIBLING_CALL_P (insn))
22173         return "jmp\t%P1";
22174       else
22175         return "call\t%P1";
22176     }
22177   if (SIBLING_CALL_P (insn))
22178     return "jmp\t%A1";
22179   else
22180     return "call\t%A1";
22181 }
22182   [(set_attr "type" "callv")])
22183
22184 (define_insn "*call_value_0"
22185   [(set (match_operand 0 "" "")
22186         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22187               (match_operand:SI 2 "" "")))]
22188   "!TARGET_64BIT"
22189 {
22190   if (SIBLING_CALL_P (insn))
22191     return "jmp\t%P1";
22192   else
22193     return "call\t%P1";
22194 }
22195   [(set_attr "type" "callv")])
22196
22197 (define_insn "*call_value_0_rex64"
22198   [(set (match_operand 0 "" "")
22199         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22200               (match_operand:DI 2 "const_int_operand" "")))]
22201   "TARGET_64BIT"
22202 {
22203   if (SIBLING_CALL_P (insn))
22204     return "jmp\t%P1";
22205   else
22206     return "call\t%P1";
22207 }
22208   [(set_attr "type" "callv")])
22209
22210 (define_insn "*call_value_0_rex64_ms_sysv"
22211   [(set (match_operand 0 "" "")
22212         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22213               (match_operand:DI 2 "const_int_operand" "")))
22214    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22215    (clobber (reg:TI XMM6_REG))
22216    (clobber (reg:TI XMM7_REG))
22217    (clobber (reg:TI XMM8_REG))
22218    (clobber (reg:TI XMM9_REG))
22219    (clobber (reg:TI XMM10_REG))
22220    (clobber (reg:TI XMM11_REG))
22221    (clobber (reg:TI XMM12_REG))
22222    (clobber (reg:TI XMM13_REG))
22223    (clobber (reg:TI XMM14_REG))
22224    (clobber (reg:TI XMM15_REG))
22225    (clobber (reg:DI SI_REG))
22226    (clobber (reg:DI DI_REG))]
22227   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22228 {
22229   if (SIBLING_CALL_P (insn))
22230     return "jmp\t%P1";
22231   else
22232     return "call\t%P1";
22233 }
22234   [(set_attr "type" "callv")])
22235
22236 (define_insn "*call_value_1"
22237   [(set (match_operand 0 "" "")
22238         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22239               (match_operand:SI 2 "" "")))]
22240   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
22241 {
22242   if (constant_call_address_operand (operands[1], Pmode))
22243     return "call\t%P1";
22244   return "call\t%A1";
22245 }
22246   [(set_attr "type" "callv")])
22247
22248 (define_insn "*sibcall_value_1"
22249   [(set (match_operand 0 "" "")
22250         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
22251               (match_operand:SI 2 "" "")))]
22252   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22253 {
22254   if (constant_call_address_operand (operands[1], Pmode))
22255     return "jmp\t%P1";
22256   return "jmp\t%A1";
22257 }
22258   [(set_attr "type" "callv")])
22259
22260 (define_insn "*call_value_1_rex64"
22261   [(set (match_operand 0 "" "")
22262         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22263               (match_operand:DI 2 "" "")))]
22264   "!SIBLING_CALL_P (insn) && TARGET_64BIT
22265    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
22266 {
22267   if (constant_call_address_operand (operands[1], Pmode))
22268     return "call\t%P1";
22269   return "call\t%A1";
22270 }
22271   [(set_attr "type" "callv")])
22272
22273 (define_insn "*call_value_1_rex64_ms_sysv"
22274   [(set (match_operand 0 "" "")
22275         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22276               (match_operand:DI 2 "" "")))
22277    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22278    (clobber (reg:TI 27))
22279    (clobber (reg:TI 28))
22280    (clobber (reg:TI 45))
22281    (clobber (reg:TI 46))
22282    (clobber (reg:TI 47))
22283    (clobber (reg:TI 48))
22284    (clobber (reg:TI 49))
22285    (clobber (reg:TI 50))
22286    (clobber (reg:TI 51))
22287    (clobber (reg:TI 52))
22288    (clobber (reg:DI SI_REG))
22289    (clobber (reg:DI DI_REG))]
22290   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22291 {
22292   if (constant_call_address_operand (operands[1], Pmode))
22293     return "call\t%P1";
22294   return "call\t%A1";
22295 }
22296   [(set_attr "type" "callv")])
22297
22298 (define_insn "*call_value_1_rex64_large"
22299   [(set (match_operand 0 "" "")
22300         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22301               (match_operand:DI 2 "" "")))]
22302   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22303   "call\t%A1"
22304   [(set_attr "type" "callv")])
22305
22306 (define_insn "*sibcall_value_1_rex64"
22307   [(set (match_operand 0 "" "")
22308         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22309               (match_operand:DI 2 "" "")))]
22310   "SIBLING_CALL_P (insn) && TARGET_64BIT"
22311   "jmp\t%P1"
22312   [(set_attr "type" "callv")])
22313
22314 (define_insn "*sibcall_value_1_rex64_v"
22315   [(set (match_operand 0 "" "")
22316         (call (mem:QI (reg:DI R11_REG))
22317               (match_operand:DI 1 "" "")))]
22318   "SIBLING_CALL_P (insn) && TARGET_64BIT"
22319   "jmp\t{*%%}r11"
22320   [(set_attr "type" "callv")])
22321 \f
22322 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
22323 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
22324 ;; caught for use by garbage collectors and the like.  Using an insn that
22325 ;; maps to SIGILL makes it more likely the program will rightfully die.
22326 ;; Keeping with tradition, "6" is in honor of #UD.
22327 (define_insn "trap"
22328   [(trap_if (const_int 1) (const_int 6))]
22329   ""
22330   { return ASM_SHORT "0x0b0f"; }
22331   [(set_attr "length" "2")])
22332
22333 (define_expand "sse_prologue_save"
22334   [(parallel [(set (match_operand:BLK 0 "" "")
22335                    (unspec:BLK [(reg:DI 21)
22336                                 (reg:DI 22)
22337                                 (reg:DI 23)
22338                                 (reg:DI 24)
22339                                 (reg:DI 25)
22340                                 (reg:DI 26)
22341                                 (reg:DI 27)
22342                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22343               (use (match_operand:DI 1 "register_operand" ""))
22344               (use (match_operand:DI 2 "immediate_operand" ""))
22345               (use (label_ref:DI (match_operand 3 "" "")))])]
22346   "TARGET_64BIT"
22347   "")
22348
22349 (define_insn "*sse_prologue_save_insn"
22350   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22351                           (match_operand:DI 4 "const_int_operand" "n")))
22352         (unspec:BLK [(reg:DI 21)
22353                      (reg:DI 22)
22354                      (reg:DI 23)
22355                      (reg:DI 24)
22356                      (reg:DI 25)
22357                      (reg:DI 26)
22358                      (reg:DI 27)
22359                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22360    (use (match_operand:DI 1 "register_operand" "r"))
22361    (use (match_operand:DI 2 "const_int_operand" "i"))
22362    (use (label_ref:DI (match_operand 3 "" "X")))]
22363   "TARGET_64BIT
22364    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
22365    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22366 {
22367   int i;
22368   operands[0] = gen_rtx_MEM (Pmode,
22369                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22370   /* VEX instruction with a REX prefix will #UD.  */
22371   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22372     gcc_unreachable ();
22373
22374   output_asm_insn ("jmp\t%A1", operands);
22375   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22376     {
22377       operands[4] = adjust_address (operands[0], DImode, i*16);
22378       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22379       PUT_MODE (operands[4], TImode);
22380       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22381         output_asm_insn ("rex", operands);
22382       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
22383     }
22384   (*targetm.asm_out.internal_label) (asm_out_file, "L",
22385                                      CODE_LABEL_NUMBER (operands[3]));
22386   return "";
22387 }
22388   [(set_attr "type" "other")
22389    (set_attr "length_immediate" "0")
22390    (set_attr "length_address" "0")
22391    (set (attr "length")
22392      (if_then_else
22393        (eq (symbol_ref "TARGET_AVX") (const_int 0))
22394        (const_string "34")
22395        (const_string "42")))
22396    (set_attr "memory" "store")
22397    (set_attr "modrm" "0")
22398    (set_attr "prefix" "maybe_vex")
22399    (set_attr "mode" "DI")])
22400
22401 (define_expand "prefetch"
22402   [(prefetch (match_operand 0 "address_operand" "")
22403              (match_operand:SI 1 "const_int_operand" "")
22404              (match_operand:SI 2 "const_int_operand" ""))]
22405   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22406 {
22407   int rw = INTVAL (operands[1]);
22408   int locality = INTVAL (operands[2]);
22409
22410   gcc_assert (rw == 0 || rw == 1);
22411   gcc_assert (locality >= 0 && locality <= 3);
22412   gcc_assert (GET_MODE (operands[0]) == Pmode
22413               || GET_MODE (operands[0]) == VOIDmode);
22414
22415   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22416      supported by SSE counterpart or the SSE prefetch is not available
22417      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22418      of locality.  */
22419   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22420     operands[2] = GEN_INT (3);
22421   else
22422     operands[1] = const0_rtx;
22423 })
22424
22425 (define_insn "*prefetch_sse"
22426   [(prefetch (match_operand:SI 0 "address_operand" "p")
22427              (const_int 0)
22428              (match_operand:SI 1 "const_int_operand" ""))]
22429   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22430 {
22431   static const char * const patterns[4] = {
22432    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22433   };
22434
22435   int locality = INTVAL (operands[1]);
22436   gcc_assert (locality >= 0 && locality <= 3);
22437
22438   return patterns[locality];
22439 }
22440   [(set_attr "type" "sse")
22441    (set_attr "atom_sse_attr" "prefetch")
22442    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22443    (set_attr "memory" "none")])
22444
22445 (define_insn "*prefetch_sse_rex"
22446   [(prefetch (match_operand:DI 0 "address_operand" "p")
22447              (const_int 0)
22448              (match_operand:SI 1 "const_int_operand" ""))]
22449   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22450 {
22451   static const char * const patterns[4] = {
22452    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22453   };
22454
22455   int locality = INTVAL (operands[1]);
22456   gcc_assert (locality >= 0 && locality <= 3);
22457
22458   return patterns[locality];
22459 }
22460   [(set_attr "type" "sse")
22461    (set_attr "atom_sse_attr" "prefetch")
22462    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22463    (set_attr "memory" "none")])
22464
22465 (define_insn "*prefetch_3dnow"
22466   [(prefetch (match_operand:SI 0 "address_operand" "p")
22467              (match_operand:SI 1 "const_int_operand" "n")
22468              (const_int 3))]
22469   "TARGET_3DNOW && !TARGET_64BIT"
22470 {
22471   if (INTVAL (operands[1]) == 0)
22472     return "prefetch\t%a0";
22473   else
22474     return "prefetchw\t%a0";
22475 }
22476   [(set_attr "type" "mmx")
22477    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22478    (set_attr "memory" "none")])
22479
22480 (define_insn "*prefetch_3dnow_rex"
22481   [(prefetch (match_operand:DI 0 "address_operand" "p")
22482              (match_operand:SI 1 "const_int_operand" "n")
22483              (const_int 3))]
22484   "TARGET_3DNOW && TARGET_64BIT"
22485 {
22486   if (INTVAL (operands[1]) == 0)
22487     return "prefetch\t%a0";
22488   else
22489     return "prefetchw\t%a0";
22490 }
22491   [(set_attr "type" "mmx")
22492    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22493    (set_attr "memory" "none")])
22494
22495 (define_expand "stack_protect_set"
22496   [(match_operand 0 "memory_operand" "")
22497    (match_operand 1 "memory_operand" "")]
22498   ""
22499 {
22500 #ifdef TARGET_THREAD_SSP_OFFSET
22501   if (TARGET_64BIT)
22502     emit_insn (gen_stack_tls_protect_set_di (operands[0],
22503                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22504   else
22505     emit_insn (gen_stack_tls_protect_set_si (operands[0],
22506                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22507 #else
22508   if (TARGET_64BIT)
22509     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22510   else
22511     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22512 #endif
22513   DONE;
22514 })
22515
22516 (define_insn "stack_protect_set_si"
22517   [(set (match_operand:SI 0 "memory_operand" "=m")
22518         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22519    (set (match_scratch:SI 2 "=&r") (const_int 0))
22520    (clobber (reg:CC FLAGS_REG))]
22521   ""
22522   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22523   [(set_attr "type" "multi")])
22524
22525 (define_insn "stack_protect_set_di"
22526   [(set (match_operand:DI 0 "memory_operand" "=m")
22527         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22528    (set (match_scratch:DI 2 "=&r") (const_int 0))
22529    (clobber (reg:CC FLAGS_REG))]
22530   "TARGET_64BIT"
22531   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22532   [(set_attr "type" "multi")])
22533
22534 (define_insn "stack_tls_protect_set_si"
22535   [(set (match_operand:SI 0 "memory_operand" "=m")
22536         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22537    (set (match_scratch:SI 2 "=&r") (const_int 0))
22538    (clobber (reg:CC FLAGS_REG))]
22539   ""
22540   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22541   [(set_attr "type" "multi")])
22542
22543 (define_insn "stack_tls_protect_set_di"
22544   [(set (match_operand:DI 0 "memory_operand" "=m")
22545         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22546    (set (match_scratch:DI 2 "=&r") (const_int 0))
22547    (clobber (reg:CC FLAGS_REG))]
22548   "TARGET_64BIT"
22549   {
22550      /* The kernel uses a different segment register for performance reasons; a
22551         system call would not have to trash the userspace segment register,
22552         which would be expensive */
22553      if (ix86_cmodel != CM_KERNEL)
22554         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22555      else
22556         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22557   }
22558   [(set_attr "type" "multi")])
22559
22560 (define_expand "stack_protect_test"
22561   [(match_operand 0 "memory_operand" "")
22562    (match_operand 1 "memory_operand" "")
22563    (match_operand 2 "" "")]
22564   ""
22565 {
22566   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22567
22568 #ifdef TARGET_THREAD_SSP_OFFSET
22569   if (TARGET_64BIT)
22570     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22571                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22572   else
22573     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22574                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22575 #else
22576   if (TARGET_64BIT)
22577     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22578   else
22579     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22580 #endif
22581
22582   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22583                                   flags, const0_rtx, operands[2]));
22584   DONE;
22585 })
22586
22587 (define_insn "stack_protect_test_si"
22588   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22589         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22590                      (match_operand:SI 2 "memory_operand" "m")]
22591                     UNSPEC_SP_TEST))
22592    (clobber (match_scratch:SI 3 "=&r"))]
22593   ""
22594   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22595   [(set_attr "type" "multi")])
22596
22597 (define_insn "stack_protect_test_di"
22598   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22599         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22600                      (match_operand:DI 2 "memory_operand" "m")]
22601                     UNSPEC_SP_TEST))
22602    (clobber (match_scratch:DI 3 "=&r"))]
22603   "TARGET_64BIT"
22604   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22605   [(set_attr "type" "multi")])
22606
22607 (define_insn "stack_tls_protect_test_si"
22608   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22609         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22610                      (match_operand:SI 2 "const_int_operand" "i")]
22611                     UNSPEC_SP_TLS_TEST))
22612    (clobber (match_scratch:SI 3 "=r"))]
22613   ""
22614   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22615   [(set_attr "type" "multi")])
22616
22617 (define_insn "stack_tls_protect_test_di"
22618   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22619         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22620                      (match_operand:DI 2 "const_int_operand" "i")]
22621                     UNSPEC_SP_TLS_TEST))
22622    (clobber (match_scratch:DI 3 "=r"))]
22623   "TARGET_64BIT"
22624   {
22625      /* The kernel uses a different segment register for performance reasons; a
22626         system call would not have to trash the userspace segment register,
22627         which would be expensive */
22628      if (ix86_cmodel != CM_KERNEL)
22629         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22630      else
22631         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22632   }
22633   [(set_attr "type" "multi")])
22634
22635 (define_mode_iterator CRC32MODE [QI HI SI])
22636 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22637 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22638
22639 (define_insn "sse4_2_crc32<mode>"
22640   [(set (match_operand:SI 0 "register_operand" "=r")
22641         (unspec:SI
22642           [(match_operand:SI 1 "register_operand" "0")
22643            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22644           UNSPEC_CRC32))]
22645   "TARGET_SSE4_2 || TARGET_CRC32"
22646   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22647   [(set_attr "type" "sselog1")
22648    (set_attr "prefix_rep" "1")
22649    (set_attr "prefix_extra" "1")
22650    (set (attr "prefix_data16")
22651      (if_then_else (match_operand:HI 2 "" "")
22652        (const_string "1")
22653        (const_string "*")))
22654    (set (attr "prefix_rex")
22655      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22656        (const_string "1")
22657        (const_string "*")))
22658    (set_attr "mode" "SI")])
22659
22660 (define_insn "sse4_2_crc32di"
22661   [(set (match_operand:DI 0 "register_operand" "=r")
22662         (unspec:DI
22663           [(match_operand:DI 1 "register_operand" "0")
22664            (match_operand:DI 2 "nonimmediate_operand" "rm")]
22665           UNSPEC_CRC32))]
22666   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
22667   "crc32q\t{%2, %0|%0, %2}"
22668   [(set_attr "type" "sselog1")
22669    (set_attr "prefix_rep" "1")
22670    (set_attr "prefix_extra" "1")
22671    (set_attr "mode" "DI")])
22672
22673 (include "mmx.md")
22674 (include "sse.md")
22675 (include "sync.md")