OSDN Git Service

d24f7ecb778aeb9a39637b4ee20a352d7d3a8a3f
[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 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_constants
66   [; Relocation specifiers
67    (UNSPEC_GOT                  0)
68    (UNSPEC_GOTOFF               1)
69    (UNSPEC_GOTPCREL             2)
70    (UNSPEC_GOTTPOFF             3)
71    (UNSPEC_TPOFF                4)
72    (UNSPEC_NTPOFF               5)
73    (UNSPEC_DTPOFF               6)
74    (UNSPEC_GOTNTPOFF            7)
75    (UNSPEC_INDNTPOFF            8)
76    (UNSPEC_PLTOFF               9)
77    (UNSPEC_MACHOPIC_OFFSET      10)
78
79    ; Prologue support
80    (UNSPEC_STACK_ALLOC          11)
81    (UNSPEC_SET_GOT              12)
82    (UNSPEC_SSE_PROLOGUE_SAVE    13)
83    (UNSPEC_REG_SAVE             14)
84    (UNSPEC_DEF_CFA              15)
85    (UNSPEC_SET_RIP              16)
86    (UNSPEC_SET_GOT_OFFSET       17)
87    (UNSPEC_MEMORY_BLOCKAGE      18)
88
89    ; TLS support
90    (UNSPEC_TP                   20)
91    (UNSPEC_TLS_GD               21)
92    (UNSPEC_TLS_LD_BASE          22)
93    (UNSPEC_TLSDESC              23)
94
95    ; Other random patterns
96    (UNSPEC_SCAS                 30)
97    (UNSPEC_FNSTSW               31)
98    (UNSPEC_SAHF                 32)
99    (UNSPEC_FSTCW                33)
100    (UNSPEC_ADD_CARRY            34)
101    (UNSPEC_FLDCW                35)
102    (UNSPEC_REP                  36)
103    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
104    (UNSPEC_TRUNC_NOOP           39)
105
106    ; For SSE/MMX support:
107    (UNSPEC_FIX_NOTRUNC          40)
108    (UNSPEC_MASKMOV              41)
109    (UNSPEC_MOVMSK               42)
110    (UNSPEC_MOVNT                43)
111    (UNSPEC_MOVU                 44)
112    (UNSPEC_RCP                  45)
113    (UNSPEC_RSQRT                46)
114    (UNSPEC_SFENCE               47)
115    (UNSPEC_PFRCP                49)
116    (UNSPEC_PFRCPIT1             40)
117    (UNSPEC_PFRCPIT2             41)
118    (UNSPEC_PFRSQRT              42)
119    (UNSPEC_PFRSQIT1             43)
120    (UNSPEC_MFENCE               44)
121    (UNSPEC_LFENCE               45)
122    (UNSPEC_PSADBW               46)
123    (UNSPEC_LDDQU                47)
124    (UNSPEC_MS_TO_SYSV_CALL      48)
125
126    ; Generic math support
127    (UNSPEC_COPYSIGN             50)
128    (UNSPEC_IEEE_MIN             51)     ; not commutative
129    (UNSPEC_IEEE_MAX             52)     ; not commutative
130
131    ; x87 Floating point
132    (UNSPEC_SIN                  60)
133    (UNSPEC_COS                  61)
134    (UNSPEC_FPATAN               62)
135    (UNSPEC_FYL2X                63)
136    (UNSPEC_FYL2XP1              64)
137    (UNSPEC_FRNDINT              65)
138    (UNSPEC_FIST                 66)
139    (UNSPEC_F2XM1                67)
140    (UNSPEC_TAN                  68)
141    (UNSPEC_FXAM                 69)
142
143    ; x87 Rounding
144    (UNSPEC_FRNDINT_FLOOR        70)
145    (UNSPEC_FRNDINT_CEIL         71)
146    (UNSPEC_FRNDINT_TRUNC        72)
147    (UNSPEC_FRNDINT_MASK_PM      73)
148    (UNSPEC_FIST_FLOOR           74)
149    (UNSPEC_FIST_CEIL            75)
150
151    ; x87 Double output FP
152    (UNSPEC_SINCOS_COS           80)
153    (UNSPEC_SINCOS_SIN           81)
154    (UNSPEC_XTRACT_FRACT         84)
155    (UNSPEC_XTRACT_EXP           85)
156    (UNSPEC_FSCALE_FRACT         86)
157    (UNSPEC_FSCALE_EXP           87)
158    (UNSPEC_FPREM_F              88)
159    (UNSPEC_FPREM_U              89)
160    (UNSPEC_FPREM1_F             90)
161    (UNSPEC_FPREM1_U             91)
162
163    (UNSPEC_C2_FLAG              95)
164    (UNSPEC_FXAM_MEM             96)
165
166    ; SSP patterns
167    (UNSPEC_SP_SET               100)
168    (UNSPEC_SP_TEST              101)
169    (UNSPEC_SP_TLS_SET           102)
170    (UNSPEC_SP_TLS_TEST          103)
171
172    ; SSSE3
173    (UNSPEC_PSHUFB               120)
174    (UNSPEC_PSIGN                121)
175    (UNSPEC_PALIGNR              122)
176
177    ; For SSE4A support
178    (UNSPEC_EXTRQI               130)
179    (UNSPEC_EXTRQ                131)
180    (UNSPEC_INSERTQI             132)
181    (UNSPEC_INSERTQ              133)
182
183    ; For SSE4.1 support
184    (UNSPEC_BLENDV               134)
185    (UNSPEC_INSERTPS             135)
186    (UNSPEC_DP                   136)
187    (UNSPEC_MOVNTDQA             137)
188    (UNSPEC_MPSADBW              138)
189    (UNSPEC_PHMINPOSUW           139)
190    (UNSPEC_PTEST                140)
191    (UNSPEC_ROUND                141)
192
193    ; For SSE4.2 support
194    (UNSPEC_CRC32                143)
195    (UNSPEC_PCMPESTR             144)
196    (UNSPEC_PCMPISTR             145)
197
198    ; For FMA4 support
199    (UNSPEC_FMA4_INTRINSIC       150)
200    (UNSPEC_FMA4_FMADDSUB        151)
201    (UNSPEC_FMA4_FMSUBADD        152)
202    ; For AES support
203    (UNSPEC_AESENC               159)
204    (UNSPEC_AESENCLAST           160)
205    (UNSPEC_AESDEC               161)
206    (UNSPEC_AESDECLAST           162)
207    (UNSPEC_AESIMC               163)
208    (UNSPEC_AESKEYGENASSIST      164)
209
210    ; For PCLMUL support
211    (UNSPEC_PCLMUL               165)
212
213    ; For AVX support
214    (UNSPEC_PCMP                 166)
215    (UNSPEC_VPERMIL              167)
216    (UNSPEC_VPERMIL2F128         168)
217    (UNSPEC_MASKLOAD             169)
218    (UNSPEC_MASKSTORE            170)
219    (UNSPEC_CAST                 171)
220    (UNSPEC_VTESTP               172)
221   ])
222
223 (define_constants
224   [(UNSPECV_BLOCKAGE            0)
225    (UNSPECV_STACK_PROBE         1)
226    (UNSPECV_EMMS                2)
227    (UNSPECV_LDMXCSR             3)
228    (UNSPECV_STMXCSR             4)
229    (UNSPECV_FEMMS               5)
230    (UNSPECV_CLFLUSH             6)
231    (UNSPECV_ALIGN               7)
232    (UNSPECV_MONITOR             8)
233    (UNSPECV_MWAIT               9)
234    (UNSPECV_CMPXCHG             10)
235    (UNSPECV_XCHG                12)
236    (UNSPECV_LOCK                13)
237    (UNSPECV_PROLOGUE_USE        14)
238    (UNSPECV_CLD                 15)
239    (UNSPECV_VZEROALL            16)
240    (UNSPECV_VZEROUPPER          17)
241    (UNSPECV_RDTSC               18)
242    (UNSPECV_RDTSCP              19)
243    (UNSPECV_RDPMC               20)
244   ])
245
246 ;; Constants to represent pcomtrue/pcomfalse variants
247 (define_constants
248   [(PCOM_FALSE                  0)
249    (PCOM_TRUE                   1)
250    (COM_FALSE_S                 2)
251    (COM_FALSE_P                 3)
252    (COM_TRUE_S                  4)
253    (COM_TRUE_P                  5)
254   ])
255
256 ;; Registers by name.
257 (define_constants
258   [(AX_REG                       0)
259    (DX_REG                       1)
260    (CX_REG                       2)
261    (BX_REG                       3)
262    (SI_REG                       4)
263    (DI_REG                       5)
264    (BP_REG                       6)
265    (SP_REG                       7)
266    (ST0_REG                      8)
267    (ST1_REG                      9)
268    (ST2_REG                     10)
269    (ST3_REG                     11)
270    (ST4_REG                     12)
271    (ST5_REG                     13)
272    (ST6_REG                     14)
273    (ST7_REG                     15)
274    (FLAGS_REG                   17)
275    (FPSR_REG                    18)
276    (FPCR_REG                    19)
277    (XMM0_REG                    21)
278    (XMM1_REG                    22)
279    (XMM2_REG                    23)
280    (XMM3_REG                    24)
281    (XMM4_REG                    25)
282    (XMM5_REG                    26)
283    (XMM6_REG                    27)
284    (XMM7_REG                    28)
285    (MM0_REG                     29)
286    (MM1_REG                     30)
287    (MM2_REG                     31)
288    (MM3_REG                     32)
289    (MM4_REG                     33)
290    (MM5_REG                     34)
291    (MM6_REG                     35)
292    (MM7_REG                     36)
293    (R8_REG                      37)
294    (R9_REG                      38)
295    (R10_REG                     39)
296    (R11_REG                     40)
297    (R12_REG                     41)
298    (R13_REG                     42)
299    (XMM8_REG                    45)
300    (XMM9_REG                    46)
301    (XMM10_REG                   47)
302    (XMM11_REG                   48)
303    (XMM12_REG                   49)
304    (XMM13_REG                   50)
305    (XMM14_REG                   51)
306    (XMM15_REG                   52)
307   ])
308
309 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
310 ;; from i386.c.
311
312 ;; In C guard expressions, put expressions which may be compile-time
313 ;; constants first.  This allows for better optimization.  For
314 ;; example, write "TARGET_64BIT && reload_completed", not
315 ;; "reload_completed && TARGET_64BIT".
316
317 \f
318 ;; Processor type.
319 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
320                     generic64,amdfam10"
321   (const (symbol_ref "ix86_schedule")))
322
323 ;; A basic instruction type.  Refinements due to arguments to be
324 ;; provided in other attributes.
325 (define_attr "type"
326   "other,multi,
327    alu,alu1,negnot,imov,imovx,lea,
328    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
329    icmp,test,ibr,setcc,icmov,
330    push,pop,call,callv,leave,
331    str,bitmanip,
332    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
333    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
334    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
335    ssemuladd,sse4arg,
336    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
337   (const_string "other"))
338
339 ;; Main data type used by the insn
340 (define_attr "mode"
341   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
342   (const_string "unknown"))
343
344 ;; The CPU unit operations uses.
345 (define_attr "unit" "integer,i387,sse,mmx,unknown"
346   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
347            (const_string "i387")
348          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
349                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
350                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
351            (const_string "sse")
352          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
353            (const_string "mmx")
354          (eq_attr "type" "other")
355            (const_string "unknown")]
356          (const_string "integer")))
357
358 ;; The (bounding maximum) length of an instruction immediate.
359 (define_attr "length_immediate" ""
360   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
361                           bitmanip")
362            (const_int 0)
363          (eq_attr "unit" "i387,sse,mmx")
364            (const_int 0)
365          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
366                           imul,icmp,push,pop")
367            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
368          (eq_attr "type" "imov,test")
369            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
370          (eq_attr "type" "call")
371            (if_then_else (match_operand 0 "constant_call_address_operand" "")
372              (const_int 4)
373              (const_int 0))
374          (eq_attr "type" "callv")
375            (if_then_else (match_operand 1 "constant_call_address_operand" "")
376              (const_int 4)
377              (const_int 0))
378          ;; We don't know the size before shorten_branches.  Expect
379          ;; the instruction to fit for better scheduling.
380          (eq_attr "type" "ibr")
381            (const_int 1)
382          ]
383          (symbol_ref "/* Update immediate_length and other attributes! */
384                       gcc_unreachable (),1")))
385
386 ;; The (bounding maximum) length of an instruction address.
387 (define_attr "length_address" ""
388   (cond [(eq_attr "type" "str,other,multi,fxch")
389            (const_int 0)
390          (and (eq_attr "type" "call")
391               (match_operand 0 "constant_call_address_operand" ""))
392              (const_int 0)
393          (and (eq_attr "type" "callv")
394               (match_operand 1 "constant_call_address_operand" ""))
395              (const_int 0)
396          ]
397          (symbol_ref "ix86_attr_length_address_default (insn)")))
398
399 ;; Set when length prefix is used.
400 (define_attr "prefix_data16" ""
401   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
402            (const_int 0)
403          (eq_attr "mode" "HI")
404            (const_int 1)
405          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
406            (const_int 1)
407         ]
408         (const_int 0)))
409
410 ;; Set when string REP prefix is used.
411 (define_attr "prefix_rep" ""
412   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
413            (const_int 0)
414          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
415            (const_int 1)
416         ]
417         (const_int 0)))
418
419 ;; Set when 0f opcode prefix is used.
420 (define_attr "prefix_0f" ""
421   (if_then_else
422     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
423          (eq_attr "unit" "sse,mmx"))
424     (const_int 1)
425     (const_int 0)))
426
427 ;; Set when REX opcode prefix is used.
428 (define_attr "prefix_rex" ""
429   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
430            (const_int 0)
431          (and (eq_attr "mode" "DI")
432               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
433                    (eq_attr "unit" "!mmx")))
434            (const_int 1)
435          (and (eq_attr "mode" "QI")
436               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
437                   (const_int 0)))
438            (const_int 1)
439          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
440              (const_int 0))
441            (const_int 1)
442          (and (eq_attr "type" "imovx")
443               (match_operand:QI 1 "ext_QIreg_operand" ""))
444            (const_int 1)
445         ]
446         (const_int 0)))
447
448 ;; There are also additional prefixes in 3DNOW, SSSE3.
449 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
450 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
451 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
452 (define_attr "prefix_extra" ""
453   (cond [(eq_attr "type" "ssemuladd,sse4arg")
454            (const_int 2)
455          (eq_attr "type" "sseiadd1,ssecvt1")
456            (const_int 1)
457         ]
458         (const_int 0)))
459
460 ;; Prefix used: original, VEX or maybe VEX.
461 (define_attr "prefix" "orig,vex,maybe_vex"
462   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
463     (const_string "vex")
464     (const_string "orig")))
465
466 ;; VEX W bit is used.
467 (define_attr "prefix_vex_w" "" (const_int 0))
468
469 ;; The length of VEX prefix
470 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
471 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
472 ;; still prefix_0f 1, with prefix_extra 1.
473 (define_attr "length_vex" ""
474   (if_then_else (and (eq_attr "prefix_0f" "1")
475                      (eq_attr "prefix_extra" "0"))
476     (if_then_else (eq_attr "prefix_vex_w" "1")
477       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
478       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
479     (if_then_else (eq_attr "prefix_vex_w" "1")
480       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
481       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
482
483 ;; Set when modrm byte is used.
484 (define_attr "modrm" ""
485   (cond [(eq_attr "type" "str,leave")
486            (const_int 0)
487          (eq_attr "unit" "i387")
488            (const_int 0)
489          (and (eq_attr "type" "incdec")
490               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
491                    (ior (match_operand:SI 1 "register_operand" "")
492                         (match_operand:HI 1 "register_operand" ""))))
493            (const_int 0)
494          (and (eq_attr "type" "push")
495               (not (match_operand 1 "memory_operand" "")))
496            (const_int 0)
497          (and (eq_attr "type" "pop")
498               (not (match_operand 0 "memory_operand" "")))
499            (const_int 0)
500          (and (eq_attr "type" "imov")
501               (and (not (eq_attr "mode" "DI"))
502                    (ior (and (match_operand 0 "register_operand" "")
503                              (match_operand 1 "immediate_operand" ""))
504                         (ior (and (match_operand 0 "ax_reg_operand" "")
505                                   (match_operand 1 "memory_displacement_only_operand" ""))
506                              (and (match_operand 0 "memory_displacement_only_operand" "")
507                                   (match_operand 1 "ax_reg_operand" ""))))))
508            (const_int 0)
509          (and (eq_attr "type" "call")
510               (match_operand 0 "constant_call_address_operand" ""))
511              (const_int 0)
512          (and (eq_attr "type" "callv")
513               (match_operand 1 "constant_call_address_operand" ""))
514              (const_int 0)
515          (and (eq_attr "type" "alu,alu1,icmp,test")
516               (match_operand 0 "ax_reg_operand" ""))
517              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
518          ]
519          (const_int 1)))
520
521 ;; The (bounding maximum) length of an instruction in bytes.
522 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
523 ;; Later we may want to split them and compute proper length as for
524 ;; other insns.
525 (define_attr "length" ""
526   (cond [(eq_attr "type" "other,multi,fistp,frndint")
527            (const_int 16)
528          (eq_attr "type" "fcmp")
529            (const_int 4)
530          (eq_attr "unit" "i387")
531            (plus (const_int 2)
532                  (plus (attr "prefix_data16")
533                        (attr "length_address")))
534          (ior (eq_attr "prefix" "vex")
535               (and (eq_attr "prefix" "maybe_vex")
536                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
537            (plus (attr "length_vex")
538                  (plus (attr "length_immediate")
539                        (plus (attr "modrm")
540                              (attr "length_address"))))]
541          (plus (plus (attr "modrm")
542                      (plus (attr "prefix_0f")
543                            (plus (attr "prefix_rex")
544                                  (plus (attr "prefix_extra")
545                                        (const_int 1)))))
546                (plus (attr "prefix_rep")
547                      (plus (attr "prefix_data16")
548                            (plus (attr "length_immediate")
549                                  (attr "length_address")))))))
550
551 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
552 ;; `store' if there is a simple memory reference therein, or `unknown'
553 ;; if the instruction is complex.
554
555 (define_attr "memory" "none,load,store,both,unknown"
556   (cond [(eq_attr "type" "other,multi,str")
557            (const_string "unknown")
558          (eq_attr "type" "lea,fcmov,fpspc")
559            (const_string "none")
560          (eq_attr "type" "fistp,leave")
561            (const_string "both")
562          (eq_attr "type" "frndint")
563            (const_string "load")
564          (eq_attr "type" "push")
565            (if_then_else (match_operand 1 "memory_operand" "")
566              (const_string "both")
567              (const_string "store"))
568          (eq_attr "type" "pop")
569            (if_then_else (match_operand 0 "memory_operand" "")
570              (const_string "both")
571              (const_string "load"))
572          (eq_attr "type" "setcc")
573            (if_then_else (match_operand 0 "memory_operand" "")
574              (const_string "store")
575              (const_string "none"))
576          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
577            (if_then_else (ior (match_operand 0 "memory_operand" "")
578                               (match_operand 1 "memory_operand" ""))
579              (const_string "load")
580              (const_string "none"))
581          (eq_attr "type" "ibr")
582            (if_then_else (match_operand 0 "memory_operand" "")
583              (const_string "load")
584              (const_string "none"))
585          (eq_attr "type" "call")
586            (if_then_else (match_operand 0 "constant_call_address_operand" "")
587              (const_string "none")
588              (const_string "load"))
589          (eq_attr "type" "callv")
590            (if_then_else (match_operand 1 "constant_call_address_operand" "")
591              (const_string "none")
592              (const_string "load"))
593          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
594               (match_operand 1 "memory_operand" ""))
595            (const_string "both")
596          (and (match_operand 0 "memory_operand" "")
597               (match_operand 1 "memory_operand" ""))
598            (const_string "both")
599          (match_operand 0 "memory_operand" "")
600            (const_string "store")
601          (match_operand 1 "memory_operand" "")
602            (const_string "load")
603          (and (eq_attr "type"
604                  "!alu1,negnot,ishift1,
605                    imov,imovx,icmp,test,bitmanip,
606                    fmov,fcmp,fsgn,
607                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
608                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
609               (match_operand 2 "memory_operand" ""))
610            (const_string "load")
611          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
612               (match_operand 3 "memory_operand" ""))
613            (const_string "load")
614         ]
615         (const_string "none")))
616
617 ;; Indicates if an instruction has both an immediate and a displacement.
618
619 (define_attr "imm_disp" "false,true,unknown"
620   (cond [(eq_attr "type" "other,multi")
621            (const_string "unknown")
622          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
623               (and (match_operand 0 "memory_displacement_operand" "")
624                    (match_operand 1 "immediate_operand" "")))
625            (const_string "true")
626          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
627               (and (match_operand 0 "memory_displacement_operand" "")
628                    (match_operand 2 "immediate_operand" "")))
629            (const_string "true")
630         ]
631         (const_string "false")))
632
633 ;; Indicates if an FP operation has an integer source.
634
635 (define_attr "fp_int_src" "false,true"
636   (const_string "false"))
637
638 ;; Defines rounding mode of an FP operation.
639
640 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
641   (const_string "any"))
642
643 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
644 (define_attr "use_carry" "0,1" (const_string "0"))
645
646 ;; Define attribute to indicate unaligned ssemov insns
647 (define_attr "movu" "0,1" (const_string "0"))
648
649 ;; Describe a user's asm statement.
650 (define_asm_attributes
651   [(set_attr "length" "128")
652    (set_attr "type" "multi")])
653
654 ;; All integer comparison codes.
655 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
656
657 ;; All floating-point comparison codes.
658 (define_code_iterator fp_cond [unordered ordered
659                                uneq unge ungt unle unlt ltgt ])
660
661 (define_code_iterator plusminus [plus minus])
662
663 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
664
665 ;; Base name for define_insn
666 (define_code_attr plusminus_insn
667   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
668    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
669
670 ;; Base name for insn mnemonic.
671 (define_code_attr plusminus_mnemonic
672   [(plus "add") (ss_plus "adds") (us_plus "addus")
673    (minus "sub") (ss_minus "subs") (us_minus "subus")])
674
675 ;; Mark commutative operators as such in constraints.
676 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
677                         (minus "") (ss_minus "") (us_minus "")])
678
679 ;; Mapping of signed max and min
680 (define_code_iterator smaxmin [smax smin])
681
682 ;; Mapping of unsigned max and min
683 (define_code_iterator umaxmin [umax umin])
684
685 ;; Mapping of signed/unsigned max and min
686 (define_code_iterator maxmin [smax smin umax umin])
687
688 ;; Base name for integer and FP insn mnemonic
689 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
690                                  (umax "maxu") (umin "minu")])
691 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
692
693 ;; Mapping of parallel logic operators
694 (define_code_iterator plogic [and ior xor])
695
696 ;; Base name for insn mnemonic.
697 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
698
699 ;; Mapping of abs neg operators
700 (define_code_iterator absneg [abs neg])
701
702 ;; Base name for x87 insn mnemonic.
703 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
704
705 ;; All single word integer modes.
706 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
707
708 ;; Single word integer modes without QImode.
709 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
710
711 ;; Single word integer modes without QImode and HImode.
712 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
713
714 ;; All math-dependant single and double word integer modes.
715 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
716                              (HI "TARGET_HIMODE_MATH")
717                              SI DI (TI "TARGET_64BIT")])
718
719 ;; Math-dependant single word integer modes without QImode.
720 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
721                                SI (DI "TARGET_64BIT")])
722
723 ;; Double word integer modes.
724 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
725                            (TI "TARGET_64BIT")])
726
727 ;; Half mode for double word integer modes.
728 (define_mode_attr DWIH [(DI "SI") (TI "DI")])
729
730 ;; Instruction suffix for integer modes.
731 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
732
733 ;; Register class for integer modes.
734 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
735
736 ;; Immediate operand constraint for integer modes.
737 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
738
739 ;; General operand constraint for word modes.
740 (define_mode_attr g [(SI "g") (DI "rme")])
741
742 ;; Immediate operand constraint for double integer modes.
743 (define_mode_attr di [(DI "iF") (TI "e")])
744
745 ;; General operand predicate for integer modes.
746 (define_mode_attr general_operand
747         [(QI "general_operand")
748          (HI "general_operand")
749          (SI "general_operand")
750          (DI "x86_64_general_operand")
751          (TI "x86_64_general_operand")])
752
753 ;; General operand predicate for double integer modes.
754 (define_mode_attr doubleint_general_operand
755         [(DI "general_operand")
756          (TI "x86_64_general_operand")])
757
758 ;; SSE and x87 SFmode and DFmode floating point modes
759 (define_mode_iterator MODEF [SF DF])
760
761 ;; All x87 floating point modes
762 (define_mode_iterator X87MODEF [SF DF XF])
763
764 ;; All integer modes handled by x87 fisttp operator.
765 (define_mode_iterator X87MODEI [HI SI DI])
766
767 ;; All integer modes handled by integer x87 operators.
768 (define_mode_iterator X87MODEI12 [HI SI])
769
770 ;; All integer modes handled by SSE cvtts?2si* operators.
771 (define_mode_iterator SSEMODEI24 [SI DI])
772
773 ;; SSE asm suffix for floating point modes
774 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
775
776 ;; SSE vector mode corresponding to a scalar mode
777 (define_mode_attr ssevecmode
778   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
779
780 ;; Instruction suffix for REX 64bit operators.
781 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
782
783 ;; This mode iterator allows :P to be used for patterns that operate on
784 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
785 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
786
787 \f
788 ;; Scheduling descriptions
789
790 (include "pentium.md")
791 (include "ppro.md")
792 (include "k6.md")
793 (include "athlon.md")
794 (include "geode.md")
795 (include "atom.md")
796
797 \f
798 ;; Operand and operator predicates and constraints
799
800 (include "predicates.md")
801 (include "constraints.md")
802
803 \f
804 ;; Compare and branch/compare and store instructions.
805
806 (define_expand "cbranchti4"
807   [(set (reg:CC FLAGS_REG)
808         (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
809                     (match_operand:TI 2 "x86_64_general_operand" "")))
810    (set (pc) (if_then_else
811               (match_operator 0 "comparison_operator"
812                [(reg:CC FLAGS_REG)
813                 (const_int 0)])
814               (label_ref (match_operand 3 "" ""))
815               (pc)))]
816   "TARGET_64BIT"
817 {
818   if (MEM_P (operands[1]) && MEM_P (operands[2]))
819     operands[1] = force_reg (TImode, operands[1]);
820   ix86_compare_op0 = operands[1];
821   ix86_compare_op1 = operands[2];
822   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
823   DONE;
824 })
825
826 (define_expand "cbranchdi4"
827   [(set (reg:CC FLAGS_REG)
828         (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
829                     (match_operand:DI 2 "x86_64_general_operand" "")))
830    (set (pc) (if_then_else
831               (match_operator 0 "comparison_operator"
832                [(reg:CC FLAGS_REG)
833                 (const_int 0)])
834               (label_ref (match_operand 3 "" ""))
835               (pc)))]
836   ""
837 {
838   if (MEM_P (operands[1]) && MEM_P (operands[2]))
839     operands[1] = force_reg (DImode, operands[1]);
840   ix86_compare_op0 = operands[1];
841   ix86_compare_op1 = operands[2];
842   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
843   DONE;
844 })
845
846 (define_expand "cstoredi4"
847   [(set (reg:CC FLAGS_REG)
848         (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
849                     (match_operand:DI 3 "x86_64_general_operand" "")))
850    (set (match_operand:QI 0 "register_operand" "")
851               (match_operator 1 "comparison_operator"
852                [(reg:CC FLAGS_REG)
853                 (const_int 0)]))]
854   "TARGET_64BIT"
855 {
856   if (MEM_P (operands[2]) && MEM_P (operands[3]))
857     operands[2] = force_reg (DImode, operands[2]);
858   ix86_compare_op0 = operands[2];
859   ix86_compare_op1 = operands[3];
860   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
861   DONE;
862 })
863
864 (define_expand "cbranchsi4"
865   [(set (reg:CC FLAGS_REG)
866         (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
867                     (match_operand:SI 2 "general_operand" "")))
868    (set (pc) (if_then_else
869               (match_operator 0 "comparison_operator"
870                [(reg:CC FLAGS_REG)
871                 (const_int 0)])
872               (label_ref (match_operand 3 "" ""))
873               (pc)))]
874   ""
875 {
876   if (MEM_P (operands[1]) && MEM_P (operands[2]))
877     operands[1] = force_reg (SImode, operands[1]);
878   ix86_compare_op0 = operands[1];
879   ix86_compare_op1 = operands[2];
880   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
881   DONE;
882 })
883
884 (define_expand "cstoresi4"
885   [(set (reg:CC FLAGS_REG)
886         (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
887                     (match_operand:SI 3 "general_operand" "")))
888    (set (match_operand:QI 0 "register_operand" "")
889               (match_operator 1 "comparison_operator"
890                [(reg:CC FLAGS_REG)
891                 (const_int 0)]))]
892   ""
893 {
894   if (MEM_P (operands[2]) && MEM_P (operands[3]))
895     operands[2] = force_reg (SImode, operands[2]);
896   ix86_compare_op0 = operands[2];
897   ix86_compare_op1 = operands[3];
898   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
899   DONE;
900 })
901
902 (define_expand "cbranchhi4"
903   [(set (reg:CC FLAGS_REG)
904         (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
905                     (match_operand:HI 2 "general_operand" "")))
906    (set (pc) (if_then_else
907               (match_operator 0 "comparison_operator"
908                [(reg:CC FLAGS_REG)
909                 (const_int 0)])
910               (label_ref (match_operand 3 "" ""))
911               (pc)))]
912   ""
913 {
914   if (MEM_P (operands[1]) && MEM_P (operands[2]))
915     operands[1] = force_reg (HImode, operands[1]);
916   ix86_compare_op0 = operands[1];
917   ix86_compare_op1 = operands[2];
918   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
919   DONE;
920 })
921
922 (define_expand "cstorehi4"
923   [(set (reg:CC FLAGS_REG)
924         (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
925                     (match_operand:HI 3 "general_operand" "")))
926    (set (match_operand:QI 0 "register_operand" "")
927               (match_operator 1 "comparison_operator"
928                [(reg:CC FLAGS_REG)
929                 (const_int 0)]))]
930   ""
931 {
932   if (MEM_P (operands[2]) && MEM_P (operands[3]))
933     operands[2] = force_reg (HImode, operands[2]);
934   ix86_compare_op0 = operands[2];
935   ix86_compare_op1 = operands[3];
936   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
937   DONE;
938 })
939
940
941 (define_expand "cbranchqi4"
942   [(set (reg:CC FLAGS_REG)
943         (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
944                     (match_operand:QI 2 "general_operand" "")))
945    (set (pc) (if_then_else
946               (match_operator 0 "comparison_operator"
947                [(reg:CC FLAGS_REG)
948                 (const_int 0)])
949               (label_ref (match_operand 3 "" ""))
950               (pc)))]
951   ""
952 {
953   if (MEM_P (operands[1]) && MEM_P (operands[2]))
954     operands[1] = force_reg (QImode, operands[1]);
955   ix86_compare_op0 = operands[1];
956   ix86_compare_op1 = operands[2];
957   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
958   DONE;
959 })
960
961
962 (define_expand "cstoreqi4"
963   [(set (reg:CC FLAGS_REG)
964         (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
965                     (match_operand:QI 3 "general_operand" "")))
966    (set (match_operand:QI 0 "register_operand" "")
967               (match_operator 1 "comparison_operator"
968                [(reg:CC FLAGS_REG)
969                 (const_int 0)]))]
970   ""
971 {
972   if (MEM_P (operands[2]) && MEM_P (operands[3]))
973     operands[2] = force_reg (QImode, operands[2]);
974   ix86_compare_op0 = operands[2];
975   ix86_compare_op1 = operands[3];
976   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
977   DONE;
978 })
979
980
981 (define_insn "cmpdi_ccno_1_rex64"
982   [(set (reg FLAGS_REG)
983         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
984                  (match_operand:DI 1 "const0_operand" "")))]
985   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
986   "@
987    test{q}\t%0, %0
988    cmp{q}\t{%1, %0|%0, %1}"
989   [(set_attr "type" "test,icmp")
990    (set_attr "length_immediate" "0,1")
991    (set_attr "mode" "DI")])
992
993 (define_insn "*cmpdi_minus_1_rex64"
994   [(set (reg FLAGS_REG)
995         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
996                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
997                  (const_int 0)))]
998   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
999   "cmp{q}\t{%1, %0|%0, %1}"
1000   [(set_attr "type" "icmp")
1001    (set_attr "mode" "DI")])
1002
1003 (define_expand "cmpdi_1_rex64"
1004   [(set (reg:CC FLAGS_REG)
1005         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1006                     (match_operand:DI 1 "general_operand" "")))]
1007   "TARGET_64BIT"
1008   "")
1009
1010 (define_insn "cmpdi_1_insn_rex64"
1011   [(set (reg FLAGS_REG)
1012         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1013                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1014   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015   "cmp{q}\t{%1, %0|%0, %1}"
1016   [(set_attr "type" "icmp")
1017    (set_attr "mode" "DI")])
1018
1019
1020 (define_insn "*cmpsi_ccno_1"
1021   [(set (reg FLAGS_REG)
1022         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1023                  (match_operand:SI 1 "const0_operand" "")))]
1024   "ix86_match_ccmode (insn, CCNOmode)"
1025   "@
1026    test{l}\t%0, %0
1027    cmp{l}\t{%1, %0|%0, %1}"
1028   [(set_attr "type" "test,icmp")
1029    (set_attr "length_immediate" "0,1")
1030    (set_attr "mode" "SI")])
1031
1032 (define_insn "*cmpsi_minus_1"
1033   [(set (reg FLAGS_REG)
1034         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1035                            (match_operand:SI 1 "general_operand" "ri,mr"))
1036                  (const_int 0)))]
1037   "ix86_match_ccmode (insn, CCGOCmode)"
1038   "cmp{l}\t{%1, %0|%0, %1}"
1039   [(set_attr "type" "icmp")
1040    (set_attr "mode" "SI")])
1041
1042 (define_expand "cmpsi_1"
1043   [(set (reg:CC FLAGS_REG)
1044         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1045                     (match_operand:SI 1 "general_operand" "")))]
1046   ""
1047   "")
1048
1049 (define_insn "*cmpsi_1_insn"
1050   [(set (reg FLAGS_REG)
1051         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1052                  (match_operand:SI 1 "general_operand" "ri,mr")))]
1053   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1054     && ix86_match_ccmode (insn, CCmode)"
1055   "cmp{l}\t{%1, %0|%0, %1}"
1056   [(set_attr "type" "icmp")
1057    (set_attr "mode" "SI")])
1058
1059 (define_insn "*cmphi_ccno_1"
1060   [(set (reg FLAGS_REG)
1061         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1062                  (match_operand:HI 1 "const0_operand" "")))]
1063   "ix86_match_ccmode (insn, CCNOmode)"
1064   "@
1065    test{w}\t%0, %0
1066    cmp{w}\t{%1, %0|%0, %1}"
1067   [(set_attr "type" "test,icmp")
1068    (set_attr "length_immediate" "0,1")
1069    (set_attr "mode" "HI")])
1070
1071 (define_insn "*cmphi_minus_1"
1072   [(set (reg FLAGS_REG)
1073         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1074                            (match_operand:HI 1 "general_operand" "rn,mr"))
1075                  (const_int 0)))]
1076   "ix86_match_ccmode (insn, CCGOCmode)"
1077   "cmp{w}\t{%1, %0|%0, %1}"
1078   [(set_attr "type" "icmp")
1079    (set_attr "mode" "HI")])
1080
1081 (define_insn "*cmphi_1"
1082   [(set (reg FLAGS_REG)
1083         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1084                  (match_operand:HI 1 "general_operand" "rn,mr")))]
1085   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1086    && ix86_match_ccmode (insn, CCmode)"
1087   "cmp{w}\t{%1, %0|%0, %1}"
1088   [(set_attr "type" "icmp")
1089    (set_attr "mode" "HI")])
1090
1091 (define_insn "*cmpqi_ccno_1"
1092   [(set (reg FLAGS_REG)
1093         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1094                  (match_operand:QI 1 "const0_operand" "")))]
1095   "ix86_match_ccmode (insn, CCNOmode)"
1096   "@
1097    test{b}\t%0, %0
1098    cmp{b}\t{$0, %0|%0, 0}"
1099   [(set_attr "type" "test,icmp")
1100    (set_attr "length_immediate" "0,1")
1101    (set_attr "mode" "QI")])
1102
1103 (define_insn "*cmpqi_1"
1104   [(set (reg FLAGS_REG)
1105         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1106                  (match_operand:QI 1 "general_operand" "qn,mq")))]
1107   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1108     && ix86_match_ccmode (insn, CCmode)"
1109   "cmp{b}\t{%1, %0|%0, %1}"
1110   [(set_attr "type" "icmp")
1111    (set_attr "mode" "QI")])
1112
1113 (define_insn "*cmpqi_minus_1"
1114   [(set (reg FLAGS_REG)
1115         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1116                            (match_operand:QI 1 "general_operand" "qn,mq"))
1117                  (const_int 0)))]
1118   "ix86_match_ccmode (insn, CCGOCmode)"
1119   "cmp{b}\t{%1, %0|%0, %1}"
1120   [(set_attr "type" "icmp")
1121    (set_attr "mode" "QI")])
1122
1123 (define_insn "*cmpqi_ext_1"
1124   [(set (reg FLAGS_REG)
1125         (compare
1126           (match_operand:QI 0 "general_operand" "Qm")
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_1_rex64"
1138   [(set (reg FLAGS_REG)
1139         (compare
1140           (match_operand:QI 0 "register_operand" "Q")
1141           (subreg:QI
1142             (zero_extract:SI
1143               (match_operand 1 "ext_register_operand" "Q")
1144               (const_int 8)
1145               (const_int 8)) 0)))]
1146   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1147   "cmp{b}\t{%h1, %0|%0, %h1}"
1148   [(set_attr "type" "icmp")
1149    (set_attr "mode" "QI")])
1150
1151 (define_insn "*cmpqi_ext_2"
1152   [(set (reg FLAGS_REG)
1153         (compare
1154           (subreg:QI
1155             (zero_extract:SI
1156               (match_operand 0 "ext_register_operand" "Q")
1157               (const_int 8)
1158               (const_int 8)) 0)
1159           (match_operand:QI 1 "const0_operand" "")))]
1160   "ix86_match_ccmode (insn, CCNOmode)"
1161   "test{b}\t%h0, %h0"
1162   [(set_attr "type" "test")
1163    (set_attr "length_immediate" "0")
1164    (set_attr "mode" "QI")])
1165
1166 (define_expand "cmpqi_ext_3"
1167   [(set (reg:CC FLAGS_REG)
1168         (compare:CC
1169           (subreg:QI
1170             (zero_extract:SI
1171               (match_operand 0 "ext_register_operand" "")
1172               (const_int 8)
1173               (const_int 8)) 0)
1174           (match_operand:QI 1 "general_operand" "")))]
1175   ""
1176   "")
1177
1178 (define_insn "cmpqi_ext_3_insn"
1179   [(set (reg FLAGS_REG)
1180         (compare
1181           (subreg:QI
1182             (zero_extract:SI
1183               (match_operand 0 "ext_register_operand" "Q")
1184               (const_int 8)
1185               (const_int 8)) 0)
1186           (match_operand:QI 1 "general_operand" "Qmn")))]
1187   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1188   "cmp{b}\t{%1, %h0|%h0, %1}"
1189   [(set_attr "type" "icmp")
1190    (set_attr "modrm" "1")
1191    (set_attr "mode" "QI")])
1192
1193 (define_insn "cmpqi_ext_3_insn_rex64"
1194   [(set (reg FLAGS_REG)
1195         (compare
1196           (subreg:QI
1197             (zero_extract:SI
1198               (match_operand 0 "ext_register_operand" "Q")
1199               (const_int 8)
1200               (const_int 8)) 0)
1201           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1202   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1203   "cmp{b}\t{%1, %h0|%h0, %1}"
1204   [(set_attr "type" "icmp")
1205    (set_attr "modrm" "1")
1206    (set_attr "mode" "QI")])
1207
1208 (define_insn "*cmpqi_ext_4"
1209   [(set (reg FLAGS_REG)
1210         (compare
1211           (subreg:QI
1212             (zero_extract:SI
1213               (match_operand 0 "ext_register_operand" "Q")
1214               (const_int 8)
1215               (const_int 8)) 0)
1216           (subreg:QI
1217             (zero_extract:SI
1218               (match_operand 1 "ext_register_operand" "Q")
1219               (const_int 8)
1220               (const_int 8)) 0)))]
1221   "ix86_match_ccmode (insn, CCmode)"
1222   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1223   [(set_attr "type" "icmp")
1224    (set_attr "mode" "QI")])
1225
1226 ;; These implement float point compares.
1227 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1228 ;; which would allow mix and match FP modes on the compares.  Which is what
1229 ;; the old patterns did, but with many more of them.
1230
1231 (define_expand "cbranchxf4"
1232   [(set (reg:CC FLAGS_REG)
1233         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1234                     (match_operand:XF 2 "nonmemory_operand" "")))
1235    (set (pc) (if_then_else
1236               (match_operator 0 "ix86_fp_comparison_operator"
1237                [(reg:CC FLAGS_REG)
1238                 (const_int 0)])
1239               (label_ref (match_operand 3 "" ""))
1240               (pc)))]
1241   "TARGET_80387"
1242 {
1243   ix86_compare_op0 = operands[1];
1244   ix86_compare_op1 = operands[2];
1245   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1246   DONE;
1247 })
1248
1249 (define_expand "cstorexf4"
1250   [(set (reg:CC FLAGS_REG)
1251         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1252                     (match_operand:XF 3 "nonmemory_operand" "")))
1253    (set (match_operand:QI 0 "register_operand" "")
1254               (match_operator 1 "ix86_fp_comparison_operator"
1255                [(reg:CC FLAGS_REG)
1256                 (const_int 0)]))]
1257   "TARGET_80387"
1258 {
1259   ix86_compare_op0 = operands[2];
1260   ix86_compare_op1 = operands[3];
1261   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1262   DONE;
1263 })
1264
1265 (define_expand "cbranch<mode>4"
1266   [(set (reg:CC FLAGS_REG)
1267         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1268                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1269    (set (pc) (if_then_else
1270               (match_operator 0 "ix86_fp_comparison_operator"
1271                [(reg:CC FLAGS_REG)
1272                 (const_int 0)])
1273               (label_ref (match_operand 3 "" ""))
1274               (pc)))]
1275   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1276 {
1277   ix86_compare_op0 = operands[1];
1278   ix86_compare_op1 = operands[2];
1279   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1280   DONE;
1281 })
1282
1283 (define_expand "cstore<mode>4"
1284   [(set (reg:CC FLAGS_REG)
1285         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1286                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1287    (set (match_operand:QI 0 "register_operand" "")
1288               (match_operator 1 "ix86_fp_comparison_operator"
1289                [(reg:CC FLAGS_REG)
1290                 (const_int 0)]))]
1291   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1292 {
1293   ix86_compare_op0 = operands[2];
1294   ix86_compare_op1 = operands[3];
1295   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1296   DONE;
1297 })
1298
1299 (define_expand "cbranchcc4"
1300   [(set (pc) (if_then_else
1301               (match_operator 0 "comparison_operator"
1302                [(match_operand 1 "flags_reg_operand" "")
1303                 (match_operand 2 "const0_operand" "")])
1304               (label_ref (match_operand 3 "" ""))
1305               (pc)))]
1306   ""
1307 {
1308   ix86_compare_op0 = operands[1];
1309   ix86_compare_op1 = operands[2];
1310   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1311   DONE;
1312 })
1313
1314 (define_expand "cstorecc4"
1315   [(set (match_operand:QI 0 "register_operand" "")
1316               (match_operator 1 "comparison_operator"
1317                [(match_operand 2 "flags_reg_operand" "")
1318                 (match_operand 3 "const0_operand" "")]))]
1319   ""
1320 {
1321   ix86_compare_op0 = operands[2];
1322   ix86_compare_op1 = operands[3];
1323   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1324   DONE;
1325 })
1326
1327
1328 ;; FP compares, step 1:
1329 ;; Set the FP condition codes.
1330 ;;
1331 ;; CCFPmode     compare with exceptions
1332 ;; CCFPUmode    compare with no exceptions
1333
1334 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1335 ;; used to manage the reg stack popping would not be preserved.
1336
1337 (define_insn "*cmpfp_0"
1338   [(set (match_operand:HI 0 "register_operand" "=a")
1339         (unspec:HI
1340           [(compare:CCFP
1341              (match_operand 1 "register_operand" "f")
1342              (match_operand 2 "const0_operand" ""))]
1343         UNSPEC_FNSTSW))]
1344   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1345    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346   "* return output_fp_compare (insn, operands, 0, 0);"
1347   [(set_attr "type" "multi")
1348    (set_attr "unit" "i387")
1349    (set (attr "mode")
1350      (cond [(match_operand:SF 1 "" "")
1351               (const_string "SF")
1352             (match_operand:DF 1 "" "")
1353               (const_string "DF")
1354            ]
1355            (const_string "XF")))])
1356
1357 (define_insn_and_split "*cmpfp_0_cc"
1358   [(set (reg:CCFP FLAGS_REG)
1359         (compare:CCFP
1360           (match_operand 1 "register_operand" "f")
1361           (match_operand 2 "const0_operand" "")))
1362    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1363   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364    && TARGET_SAHF && !TARGET_CMOVE
1365    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1366   "#"
1367   "&& reload_completed"
1368   [(set (match_dup 0)
1369         (unspec:HI
1370           [(compare:CCFP (match_dup 1)(match_dup 2))]
1371         UNSPEC_FNSTSW))
1372    (set (reg:CC FLAGS_REG)
1373         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1374   ""
1375   [(set_attr "type" "multi")
1376    (set_attr "unit" "i387")
1377    (set (attr "mode")
1378      (cond [(match_operand:SF 1 "" "")
1379               (const_string "SF")
1380             (match_operand:DF 1 "" "")
1381               (const_string "DF")
1382            ]
1383            (const_string "XF")))])
1384
1385 (define_insn "*cmpfp_xf"
1386   [(set (match_operand:HI 0 "register_operand" "=a")
1387         (unspec:HI
1388           [(compare:CCFP
1389              (match_operand:XF 1 "register_operand" "f")
1390              (match_operand:XF 2 "register_operand" "f"))]
1391           UNSPEC_FNSTSW))]
1392   "TARGET_80387"
1393   "* return output_fp_compare (insn, operands, 0, 0);"
1394   [(set_attr "type" "multi")
1395    (set_attr "unit" "i387")
1396    (set_attr "mode" "XF")])
1397
1398 (define_insn_and_split "*cmpfp_xf_cc"
1399   [(set (reg:CCFP FLAGS_REG)
1400         (compare:CCFP
1401           (match_operand:XF 1 "register_operand" "f")
1402           (match_operand:XF 2 "register_operand" "f")))
1403    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1404   "TARGET_80387
1405    && TARGET_SAHF && !TARGET_CMOVE"
1406   "#"
1407   "&& reload_completed"
1408   [(set (match_dup 0)
1409         (unspec:HI
1410           [(compare:CCFP (match_dup 1)(match_dup 2))]
1411         UNSPEC_FNSTSW))
1412    (set (reg:CC FLAGS_REG)
1413         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1414   ""
1415   [(set_attr "type" "multi")
1416    (set_attr "unit" "i387")
1417    (set_attr "mode" "XF")])
1418
1419 (define_insn "*cmpfp_<mode>"
1420   [(set (match_operand:HI 0 "register_operand" "=a")
1421         (unspec:HI
1422           [(compare:CCFP
1423              (match_operand:MODEF 1 "register_operand" "f")
1424              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1425           UNSPEC_FNSTSW))]
1426   "TARGET_80387"
1427   "* return output_fp_compare (insn, operands, 0, 0);"
1428   [(set_attr "type" "multi")
1429    (set_attr "unit" "i387")
1430    (set_attr "mode" "<MODE>")])
1431
1432 (define_insn_and_split "*cmpfp_<mode>_cc"
1433   [(set (reg:CCFP FLAGS_REG)
1434         (compare:CCFP
1435           (match_operand:MODEF 1 "register_operand" "f")
1436           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1437    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1438   "TARGET_80387
1439    && TARGET_SAHF && !TARGET_CMOVE"
1440   "#"
1441   "&& reload_completed"
1442   [(set (match_dup 0)
1443         (unspec:HI
1444           [(compare:CCFP (match_dup 1)(match_dup 2))]
1445         UNSPEC_FNSTSW))
1446    (set (reg:CC FLAGS_REG)
1447         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1448   ""
1449   [(set_attr "type" "multi")
1450    (set_attr "unit" "i387")
1451    (set_attr "mode" "<MODE>")])
1452
1453 (define_insn "*cmpfp_u"
1454   [(set (match_operand:HI 0 "register_operand" "=a")
1455         (unspec:HI
1456           [(compare:CCFPU
1457              (match_operand 1 "register_operand" "f")
1458              (match_operand 2 "register_operand" "f"))]
1459           UNSPEC_FNSTSW))]
1460   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1461    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1462   "* return output_fp_compare (insn, operands, 0, 1);"
1463   [(set_attr "type" "multi")
1464    (set_attr "unit" "i387")
1465    (set (attr "mode")
1466      (cond [(match_operand:SF 1 "" "")
1467               (const_string "SF")
1468             (match_operand:DF 1 "" "")
1469               (const_string "DF")
1470            ]
1471            (const_string "XF")))])
1472
1473 (define_insn_and_split "*cmpfp_u_cc"
1474   [(set (reg:CCFPU FLAGS_REG)
1475         (compare:CCFPU
1476           (match_operand 1 "register_operand" "f")
1477           (match_operand 2 "register_operand" "f")))
1478    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1479   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1480    && TARGET_SAHF && !TARGET_CMOVE
1481    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1482   "#"
1483   "&& reload_completed"
1484   [(set (match_dup 0)
1485         (unspec:HI
1486           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1487         UNSPEC_FNSTSW))
1488    (set (reg:CC FLAGS_REG)
1489         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1490   ""
1491   [(set_attr "type" "multi")
1492    (set_attr "unit" "i387")
1493    (set (attr "mode")
1494      (cond [(match_operand:SF 1 "" "")
1495               (const_string "SF")
1496             (match_operand:DF 1 "" "")
1497               (const_string "DF")
1498            ]
1499            (const_string "XF")))])
1500
1501 (define_insn "*cmpfp_<mode>"
1502   [(set (match_operand:HI 0 "register_operand" "=a")
1503         (unspec:HI
1504           [(compare:CCFP
1505              (match_operand 1 "register_operand" "f")
1506              (match_operator 3 "float_operator"
1507                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1508           UNSPEC_FNSTSW))]
1509   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1510    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1511    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1512   "* return output_fp_compare (insn, operands, 0, 0);"
1513   [(set_attr "type" "multi")
1514    (set_attr "unit" "i387")
1515    (set_attr "fp_int_src" "true")
1516    (set_attr "mode" "<MODE>")])
1517
1518 (define_insn_and_split "*cmpfp_<mode>_cc"
1519   [(set (reg:CCFP FLAGS_REG)
1520         (compare:CCFP
1521           (match_operand 1 "register_operand" "f")
1522           (match_operator 3 "float_operator"
1523             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1524    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1525   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1526    && TARGET_SAHF && !TARGET_CMOVE
1527    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1528    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1529   "#"
1530   "&& reload_completed"
1531   [(set (match_dup 0)
1532         (unspec:HI
1533           [(compare:CCFP
1534              (match_dup 1)
1535              (match_op_dup 3 [(match_dup 2)]))]
1536         UNSPEC_FNSTSW))
1537    (set (reg:CC FLAGS_REG)
1538         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1539   ""
1540   [(set_attr "type" "multi")
1541    (set_attr "unit" "i387")
1542    (set_attr "fp_int_src" "true")
1543    (set_attr "mode" "<MODE>")])
1544
1545 ;; FP compares, step 2
1546 ;; Move the fpsw to ax.
1547
1548 (define_insn "x86_fnstsw_1"
1549   [(set (match_operand:HI 0 "register_operand" "=a")
1550         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1551   "TARGET_80387"
1552   "fnstsw\t%0"
1553   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1554    (set_attr "mode" "SI")
1555    (set_attr "unit" "i387")])
1556
1557 ;; FP compares, step 3
1558 ;; Get ax into flags, general case.
1559
1560 (define_insn "x86_sahf_1"
1561   [(set (reg:CC FLAGS_REG)
1562         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1563                    UNSPEC_SAHF))]
1564   "TARGET_SAHF"
1565 {
1566 #ifdef HAVE_AS_IX86_SAHF
1567   return "sahf";
1568 #else
1569   return ASM_BYTE "0x9e";
1570 #endif
1571 }
1572   [(set_attr "length" "1")
1573    (set_attr "athlon_decode" "vector")
1574    (set_attr "amdfam10_decode" "direct")
1575    (set_attr "mode" "SI")])
1576
1577 ;; Pentium Pro can do steps 1 through 3 in one go.
1578 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1579 (define_insn "*cmpfp_i_mixed"
1580   [(set (reg:CCFP FLAGS_REG)
1581         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1582                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1583   "TARGET_MIX_SSE_I387
1584    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1585    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1586   "* return output_fp_compare (insn, operands, 1, 0);"
1587   [(set_attr "type" "fcmp,ssecomi")
1588    (set_attr "prefix" "orig,maybe_vex")
1589    (set (attr "mode")
1590      (if_then_else (match_operand:SF 1 "" "")
1591         (const_string "SF")
1592         (const_string "DF")))
1593    (set (attr "prefix_rep")
1594         (if_then_else (eq_attr "type" "ssecomi")
1595                       (const_string "0")
1596                       (const_string "*")))
1597    (set (attr "prefix_data16")
1598         (cond [(eq_attr "type" "fcmp")
1599                  (const_string "*")
1600                (eq_attr "mode" "DF")
1601                  (const_string "1")
1602               ]
1603               (const_string "0")))
1604    (set_attr "athlon_decode" "vector")
1605    (set_attr "amdfam10_decode" "direct")])
1606
1607 (define_insn "*cmpfp_i_sse"
1608   [(set (reg:CCFP FLAGS_REG)
1609         (compare:CCFP (match_operand 0 "register_operand" "x")
1610                       (match_operand 1 "nonimmediate_operand" "xm")))]
1611   "TARGET_SSE_MATH
1612    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1613    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1614   "* return output_fp_compare (insn, operands, 1, 0);"
1615   [(set_attr "type" "ssecomi")
1616    (set_attr "prefix" "maybe_vex")
1617    (set (attr "mode")
1618      (if_then_else (match_operand:SF 1 "" "")
1619         (const_string "SF")
1620         (const_string "DF")))
1621    (set_attr "prefix_rep" "0")
1622    (set (attr "prefix_data16")
1623         (if_then_else (eq_attr "mode" "DF")
1624                       (const_string "1")
1625                       (const_string "0")))
1626    (set_attr "athlon_decode" "vector")
1627    (set_attr "amdfam10_decode" "direct")])
1628
1629 (define_insn "*cmpfp_i_i387"
1630   [(set (reg:CCFP FLAGS_REG)
1631         (compare:CCFP (match_operand 0 "register_operand" "f")
1632                       (match_operand 1 "register_operand" "f")))]
1633   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1634    && TARGET_CMOVE
1635    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1636    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1637   "* return output_fp_compare (insn, operands, 1, 0);"
1638   [(set_attr "type" "fcmp")
1639    (set (attr "mode")
1640      (cond [(match_operand:SF 1 "" "")
1641               (const_string "SF")
1642             (match_operand:DF 1 "" "")
1643               (const_string "DF")
1644            ]
1645            (const_string "XF")))
1646    (set_attr "athlon_decode" "vector")
1647    (set_attr "amdfam10_decode" "direct")])
1648
1649 (define_insn "*cmpfp_iu_mixed"
1650   [(set (reg:CCFPU FLAGS_REG)
1651         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1652                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1653   "TARGET_MIX_SSE_I387
1654    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1655    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1656   "* return output_fp_compare (insn, operands, 1, 1);"
1657   [(set_attr "type" "fcmp,ssecomi")
1658    (set_attr "prefix" "orig,maybe_vex")
1659    (set (attr "mode")
1660      (if_then_else (match_operand:SF 1 "" "")
1661         (const_string "SF")
1662         (const_string "DF")))
1663    (set (attr "prefix_rep")
1664         (if_then_else (eq_attr "type" "ssecomi")
1665                       (const_string "0")
1666                       (const_string "*")))
1667    (set (attr "prefix_data16")
1668         (cond [(eq_attr "type" "fcmp")
1669                  (const_string "*")
1670                (eq_attr "mode" "DF")
1671                  (const_string "1")
1672               ]
1673               (const_string "0")))
1674    (set_attr "athlon_decode" "vector")
1675    (set_attr "amdfam10_decode" "direct")])
1676
1677 (define_insn "*cmpfp_iu_sse"
1678   [(set (reg:CCFPU FLAGS_REG)
1679         (compare:CCFPU (match_operand 0 "register_operand" "x")
1680                        (match_operand 1 "nonimmediate_operand" "xm")))]
1681   "TARGET_SSE_MATH
1682    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1683    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1684   "* return output_fp_compare (insn, operands, 1, 1);"
1685   [(set_attr "type" "ssecomi")
1686    (set_attr "prefix" "maybe_vex")
1687    (set (attr "mode")
1688      (if_then_else (match_operand:SF 1 "" "")
1689         (const_string "SF")
1690         (const_string "DF")))
1691    (set_attr "prefix_rep" "0")
1692    (set (attr "prefix_data16")
1693         (if_then_else (eq_attr "mode" "DF")
1694                       (const_string "1")
1695                       (const_string "0")))
1696    (set_attr "athlon_decode" "vector")
1697    (set_attr "amdfam10_decode" "direct")])
1698
1699 (define_insn "*cmpfp_iu_387"
1700   [(set (reg:CCFPU FLAGS_REG)
1701         (compare:CCFPU (match_operand 0 "register_operand" "f")
1702                        (match_operand 1 "register_operand" "f")))]
1703   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1704    && TARGET_CMOVE
1705    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1706    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1707   "* return output_fp_compare (insn, operands, 1, 1);"
1708   [(set_attr "type" "fcmp")
1709    (set (attr "mode")
1710      (cond [(match_operand:SF 1 "" "")
1711               (const_string "SF")
1712             (match_operand:DF 1 "" "")
1713               (const_string "DF")
1714            ]
1715            (const_string "XF")))
1716    (set_attr "athlon_decode" "vector")
1717    (set_attr "amdfam10_decode" "direct")])
1718 \f
1719 ;; Move instructions.
1720
1721 ;; General case of fullword move.
1722
1723 (define_expand "movsi"
1724   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1725         (match_operand:SI 1 "general_operand" ""))]
1726   ""
1727   "ix86_expand_move (SImode, operands); DONE;")
1728
1729 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1730 ;; general_operand.
1731 ;;
1732 ;; %%% We don't use a post-inc memory reference because x86 is not a
1733 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1734 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1735 ;; targets without our curiosities, and it is just as easy to represent
1736 ;; this differently.
1737
1738 (define_insn "*pushsi2"
1739   [(set (match_operand:SI 0 "push_operand" "=<")
1740         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1741   "!TARGET_64BIT"
1742   "push{l}\t%1"
1743   [(set_attr "type" "push")
1744    (set_attr "mode" "SI")])
1745
1746 ;; For 64BIT abi we always round up to 8 bytes.
1747 (define_insn "*pushsi2_rex64"
1748   [(set (match_operand:SI 0 "push_operand" "=X")
1749         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1750   "TARGET_64BIT"
1751   "push{q}\t%q1"
1752   [(set_attr "type" "push")
1753    (set_attr "mode" "SI")])
1754
1755 (define_insn "*pushsi2_prologue"
1756   [(set (match_operand:SI 0 "push_operand" "=<")
1757         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1758    (clobber (mem:BLK (scratch)))]
1759   "!TARGET_64BIT"
1760   "push{l}\t%1"
1761   [(set_attr "type" "push")
1762    (set_attr "mode" "SI")])
1763
1764 (define_insn "*popsi1_epilogue"
1765   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1766         (mem:SI (reg:SI SP_REG)))
1767    (set (reg:SI SP_REG)
1768         (plus:SI (reg:SI SP_REG) (const_int 4)))
1769    (clobber (mem:BLK (scratch)))]
1770   "!TARGET_64BIT"
1771   "pop{l}\t%0"
1772   [(set_attr "type" "pop")
1773    (set_attr "mode" "SI")])
1774
1775 (define_insn "popsi1"
1776   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1777         (mem:SI (reg:SI SP_REG)))
1778    (set (reg:SI SP_REG)
1779         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1780   "!TARGET_64BIT"
1781   "pop{l}\t%0"
1782   [(set_attr "type" "pop")
1783    (set_attr "mode" "SI")])
1784
1785 (define_insn "*movsi_xor"
1786   [(set (match_operand:SI 0 "register_operand" "=r")
1787         (match_operand:SI 1 "const0_operand" ""))
1788    (clobber (reg:CC FLAGS_REG))]
1789   "reload_completed"
1790   "xor{l}\t%0, %0"
1791   [(set_attr "type" "alu1")
1792    (set_attr "mode" "SI")
1793    (set_attr "length_immediate" "0")])
1794
1795 (define_insn "*movsi_or"
1796   [(set (match_operand:SI 0 "register_operand" "=r")
1797         (match_operand:SI 1 "immediate_operand" "i"))
1798    (clobber (reg:CC FLAGS_REG))]
1799   "reload_completed
1800    && operands[1] == constm1_rtx"
1801 {
1802   operands[1] = constm1_rtx;
1803   return "or{l}\t{%1, %0|%0, %1}";
1804 }
1805   [(set_attr "type" "alu1")
1806    (set_attr "mode" "SI")
1807    (set_attr "length_immediate" "1")])
1808
1809 (define_insn "*movsi_1"
1810   [(set (match_operand:SI 0 "nonimmediate_operand"
1811                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1812         (match_operand:SI 1 "general_operand"
1813                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1814   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1815 {
1816   switch (get_attr_type (insn))
1817     {
1818     case TYPE_SSELOG1:
1819       if (get_attr_mode (insn) == MODE_TI)
1820         return "%vpxor\t%0, %d0";
1821       return "%vxorps\t%0, %d0";
1822
1823     case TYPE_SSEMOV:
1824       switch (get_attr_mode (insn))
1825         {
1826         case MODE_TI:
1827           return "%vmovdqa\t{%1, %0|%0, %1}";
1828         case MODE_V4SF:
1829           return "%vmovaps\t{%1, %0|%0, %1}";
1830         case MODE_SI:
1831           return "%vmovd\t{%1, %0|%0, %1}";
1832         case MODE_SF:
1833           return "%vmovss\t{%1, %0|%0, %1}";
1834         default:
1835           gcc_unreachable ();
1836         }
1837
1838     case TYPE_MMX:
1839       return "pxor\t%0, %0";
1840
1841     case TYPE_MMXMOV:
1842       if (get_attr_mode (insn) == MODE_DI)
1843         return "movq\t{%1, %0|%0, %1}";
1844       return "movd\t{%1, %0|%0, %1}";
1845
1846     case TYPE_LEA:
1847       return "lea{l}\t{%1, %0|%0, %1}";
1848
1849     default:
1850       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1851       return "mov{l}\t{%1, %0|%0, %1}";
1852     }
1853 }
1854   [(set (attr "type")
1855      (cond [(eq_attr "alternative" "2")
1856               (const_string "mmx")
1857             (eq_attr "alternative" "3,4,5")
1858               (const_string "mmxmov")
1859             (eq_attr "alternative" "6")
1860               (const_string "sselog1")
1861             (eq_attr "alternative" "7,8,9,10,11")
1862               (const_string "ssemov")
1863             (match_operand:DI 1 "pic_32bit_operand" "")
1864               (const_string "lea")
1865            ]
1866            (const_string "imov")))
1867    (set (attr "prefix")
1868      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1869        (const_string "orig")
1870        (const_string "maybe_vex")))
1871    (set (attr "prefix_data16")
1872      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1873        (const_string "1")
1874        (const_string "*")))
1875    (set (attr "mode")
1876      (cond [(eq_attr "alternative" "2,3")
1877               (const_string "DI")
1878             (eq_attr "alternative" "6,7")
1879               (if_then_else
1880                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1881                 (const_string "V4SF")
1882                 (const_string "TI"))
1883             (and (eq_attr "alternative" "8,9,10,11")
1884                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1885               (const_string "SF")
1886            ]
1887            (const_string "SI")))])
1888
1889 ;; Stores and loads of ax to arbitrary constant address.
1890 ;; We fake an second form of instruction to force reload to load address
1891 ;; into register when rax is not available
1892 (define_insn "*movabssi_1_rex64"
1893   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1894         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1895   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1896   "@
1897    movabs{l}\t{%1, %P0|%P0, %1}
1898    mov{l}\t{%1, %a0|%a0, %1}"
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" "store")
1904    (set_attr "mode" "SI")])
1905
1906 (define_insn "*movabssi_2_rex64"
1907   [(set (match_operand:SI 0 "register_operand" "=a,r")
1908         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1909   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1910   "@
1911    movabs{l}\t{%P1, %0|%0, %P1}
1912    mov{l}\t{%a1, %0|%0, %a1}"
1913   [(set_attr "type" "imov")
1914    (set_attr "modrm" "0,*")
1915    (set_attr "length_address" "8,0")
1916    (set_attr "length_immediate" "0")
1917    (set_attr "memory" "load")
1918    (set_attr "mode" "SI")])
1919
1920 (define_insn "*swapsi"
1921   [(set (match_operand:SI 0 "register_operand" "+r")
1922         (match_operand:SI 1 "register_operand" "+r"))
1923    (set (match_dup 1)
1924         (match_dup 0))]
1925   ""
1926   "xchg{l}\t%1, %0"
1927   [(set_attr "type" "imov")
1928    (set_attr "mode" "SI")
1929    (set_attr "pent_pair" "np")
1930    (set_attr "athlon_decode" "vector")
1931    (set_attr "amdfam10_decode" "double")])
1932
1933 (define_expand "movhi"
1934   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1935         (match_operand:HI 1 "general_operand" ""))]
1936   ""
1937   "ix86_expand_move (HImode, operands); DONE;")
1938
1939 (define_insn "*pushhi2"
1940   [(set (match_operand:HI 0 "push_operand" "=X")
1941         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1942   "!TARGET_64BIT"
1943   "push{l}\t%k1"
1944   [(set_attr "type" "push")
1945    (set_attr "mode" "SI")])
1946
1947 ;; For 64BIT abi we always round up to 8 bytes.
1948 (define_insn "*pushhi2_rex64"
1949   [(set (match_operand:HI 0 "push_operand" "=X")
1950         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1951   "TARGET_64BIT"
1952   "push{q}\t%q1"
1953   [(set_attr "type" "push")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movhi_1"
1957   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1958         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1959   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1960 {
1961   switch (get_attr_type (insn))
1962     {
1963     case TYPE_IMOVX:
1964       /* movzwl is faster than movw on p2 due to partial word stalls,
1965          though not as fast as an aligned movl.  */
1966       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1967     default:
1968       if (get_attr_mode (insn) == MODE_SI)
1969         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970       else
1971         return "mov{w}\t{%1, %0|%0, %1}";
1972     }
1973 }
1974   [(set (attr "type")
1975      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1976               (const_string "imov")
1977             (and (eq_attr "alternative" "0")
1978                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1979                           (const_int 0))
1980                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1981                           (const_int 0))))
1982               (const_string "imov")
1983             (and (eq_attr "alternative" "1,2")
1984                  (match_operand:HI 1 "aligned_operand" ""))
1985               (const_string "imov")
1986             (and (ne (symbol_ref "TARGET_MOVX")
1987                      (const_int 0))
1988                  (eq_attr "alternative" "0,2"))
1989               (const_string "imovx")
1990            ]
1991            (const_string "imov")))
1992     (set (attr "mode")
1993       (cond [(eq_attr "type" "imovx")
1994                (const_string "SI")
1995              (and (eq_attr "alternative" "1,2")
1996                   (match_operand:HI 1 "aligned_operand" ""))
1997                (const_string "SI")
1998              (and (eq_attr "alternative" "0")
1999                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2000                            (const_int 0))
2001                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2002                            (const_int 0))))
2003                (const_string "SI")
2004             ]
2005             (const_string "HI")))])
2006
2007 ;; Stores and loads of ax to arbitrary constant address.
2008 ;; We fake an second form of instruction to force reload to load address
2009 ;; into register when rax is not available
2010 (define_insn "*movabshi_1_rex64"
2011   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2012         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
2013   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2014   "@
2015    movabs{w}\t{%1, %P0|%P0, %1}
2016    mov{w}\t{%1, %a0|%a0, %1}"
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" "store")
2022    (set_attr "mode" "HI")])
2023
2024 (define_insn "*movabshi_2_rex64"
2025   [(set (match_operand:HI 0 "register_operand" "=a,r")
2026         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2027   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2028   "@
2029    movabs{w}\t{%P1, %0|%0, %P1}
2030    mov{w}\t{%a1, %0|%0, %a1}"
2031   [(set_attr "type" "imov")
2032    (set_attr "modrm" "0,*")
2033    (set_attr "length_address" "8,0")
2034    (set_attr "length_immediate" "0")
2035    (set_attr "memory" "load")
2036    (set_attr "mode" "HI")])
2037
2038 (define_insn "*swaphi_1"
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 || optimize_function_for_size_p (cfun)"
2044   "xchg{l}\t%k1, %k0"
2045   [(set_attr "type" "imov")
2046    (set_attr "mode" "SI")
2047    (set_attr "pent_pair" "np")
2048    (set_attr "athlon_decode" "vector")
2049    (set_attr "amdfam10_decode" "double")])
2050
2051 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2052 (define_insn "*swaphi_2"
2053   [(set (match_operand:HI 0 "register_operand" "+r")
2054         (match_operand:HI 1 "register_operand" "+r"))
2055    (set (match_dup 1)
2056         (match_dup 0))]
2057   "TARGET_PARTIAL_REG_STALL"
2058   "xchg{w}\t%1, %0"
2059   [(set_attr "type" "imov")
2060    (set_attr "mode" "HI")
2061    (set_attr "pent_pair" "np")
2062    (set_attr "athlon_decode" "vector")])
2063
2064 (define_expand "movstricthi"
2065   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2066         (match_operand:HI 1 "general_operand" ""))]
2067   ""
2068 {
2069   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2070     FAIL;
2071   /* Don't generate memory->memory moves, go through a register */
2072   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2073     operands[1] = force_reg (HImode, operands[1]);
2074 })
2075
2076 (define_insn "*movstricthi_1"
2077   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2078         (match_operand:HI 1 "general_operand" "rn,m"))]
2079   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2080    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2081   "mov{w}\t{%1, %0|%0, %1}"
2082   [(set_attr "type" "imov")
2083    (set_attr "mode" "HI")])
2084
2085 (define_insn "*movstricthi_xor"
2086   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2087         (match_operand:HI 1 "const0_operand" ""))
2088    (clobber (reg:CC FLAGS_REG))]
2089   "reload_completed"
2090   "xor{w}\t%0, %0"
2091   [(set_attr "type" "alu1")
2092    (set_attr "mode" "HI")
2093    (set_attr "length_immediate" "0")])
2094
2095 (define_expand "movqi"
2096   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2097         (match_operand:QI 1 "general_operand" ""))]
2098   ""
2099   "ix86_expand_move (QImode, operands); DONE;")
2100
2101 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2102 ;; "push a byte".  But actually we use pushl, which has the effect
2103 ;; of rounding the amount pushed up to a word.
2104
2105 (define_insn "*pushqi2"
2106   [(set (match_operand:QI 0 "push_operand" "=X")
2107         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2108   "!TARGET_64BIT"
2109   "push{l}\t%k1"
2110   [(set_attr "type" "push")
2111    (set_attr "mode" "SI")])
2112
2113 ;; For 64BIT abi we always round up to 8 bytes.
2114 (define_insn "*pushqi2_rex64"
2115   [(set (match_operand:QI 0 "push_operand" "=X")
2116         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2117   "TARGET_64BIT"
2118   "push{q}\t%q1"
2119   [(set_attr "type" "push")
2120    (set_attr "mode" "DI")])
2121
2122 ;; Situation is quite tricky about when to choose full sized (SImode) move
2123 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2124 ;; partial register dependency machines (such as AMD Athlon), where QImode
2125 ;; moves issue extra dependency and for partial register stalls machines
2126 ;; that don't use QImode patterns (and QImode move cause stall on the next
2127 ;; instruction).
2128 ;;
2129 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2130 ;; register stall machines with, where we use QImode instructions, since
2131 ;; partial register stall can be caused there.  Then we use movzx.
2132 (define_insn "*movqi_1"
2133   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2134         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2135   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2136 {
2137   switch (get_attr_type (insn))
2138     {
2139     case TYPE_IMOVX:
2140       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2141       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2142     default:
2143       if (get_attr_mode (insn) == MODE_SI)
2144         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2145       else
2146         return "mov{b}\t{%1, %0|%0, %1}";
2147     }
2148 }
2149   [(set (attr "type")
2150      (cond [(and (eq_attr "alternative" "5")
2151                  (not (match_operand:QI 1 "aligned_operand" "")))
2152               (const_string "imovx")
2153             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2154               (const_string "imov")
2155             (and (eq_attr "alternative" "3")
2156                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2157                           (const_int 0))
2158                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2159                           (const_int 0))))
2160               (const_string "imov")
2161             (eq_attr "alternative" "3,5")
2162               (const_string "imovx")
2163             (and (ne (symbol_ref "TARGET_MOVX")
2164                      (const_int 0))
2165                  (eq_attr "alternative" "2"))
2166               (const_string "imovx")
2167            ]
2168            (const_string "imov")))
2169    (set (attr "mode")
2170       (cond [(eq_attr "alternative" "3,4,5")
2171                (const_string "SI")
2172              (eq_attr "alternative" "6")
2173                (const_string "QI")
2174              (eq_attr "type" "imovx")
2175                (const_string "SI")
2176              (and (eq_attr "type" "imov")
2177                   (and (eq_attr "alternative" "0,1")
2178                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2179                                 (const_int 0))
2180                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2181                                      (const_int 0))
2182                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2183                                      (const_int 0))))))
2184                (const_string "SI")
2185              ;; Avoid partial register stalls when not using QImode arithmetic
2186              (and (eq_attr "type" "imov")
2187                   (and (eq_attr "alternative" "0,1")
2188                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2189                                 (const_int 0))
2190                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2191                                 (const_int 0)))))
2192                (const_string "SI")
2193            ]
2194            (const_string "QI")))])
2195
2196 (define_insn "*swapqi_1"
2197   [(set (match_operand:QI 0 "register_operand" "+r")
2198         (match_operand:QI 1 "register_operand" "+r"))
2199    (set (match_dup 1)
2200         (match_dup 0))]
2201   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2202   "xchg{l}\t%k1, %k0"
2203   [(set_attr "type" "imov")
2204    (set_attr "mode" "SI")
2205    (set_attr "pent_pair" "np")
2206    (set_attr "athlon_decode" "vector")
2207    (set_attr "amdfam10_decode" "vector")])
2208
2209 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2210 (define_insn "*swapqi_2"
2211   [(set (match_operand:QI 0 "register_operand" "+q")
2212         (match_operand:QI 1 "register_operand" "+q"))
2213    (set (match_dup 1)
2214         (match_dup 0))]
2215   "TARGET_PARTIAL_REG_STALL"
2216   "xchg{b}\t%1, %0"
2217   [(set_attr "type" "imov")
2218    (set_attr "mode" "QI")
2219    (set_attr "pent_pair" "np")
2220    (set_attr "athlon_decode" "vector")])
2221
2222 (define_expand "movstrictqi"
2223   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2224         (match_operand:QI 1 "general_operand" ""))]
2225   ""
2226 {
2227   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2228     FAIL;
2229   /* Don't generate memory->memory moves, go through a register.  */
2230   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2231     operands[1] = force_reg (QImode, operands[1]);
2232 })
2233
2234 (define_insn "*movstrictqi_1"
2235   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2236         (match_operand:QI 1 "general_operand" "*qn,m"))]
2237   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2238    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2239   "mov{b}\t{%1, %0|%0, %1}"
2240   [(set_attr "type" "imov")
2241    (set_attr "mode" "QI")])
2242
2243 (define_insn "*movstrictqi_xor"
2244   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2245         (match_operand:QI 1 "const0_operand" ""))
2246    (clobber (reg:CC FLAGS_REG))]
2247   "reload_completed"
2248   "xor{b}\t%0, %0"
2249   [(set_attr "type" "alu1")
2250    (set_attr "mode" "QI")
2251    (set_attr "length_immediate" "0")])
2252
2253 (define_insn "*movsi_extv_1"
2254   [(set (match_operand:SI 0 "register_operand" "=R")
2255         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2256                          (const_int 8)
2257                          (const_int 8)))]
2258   ""
2259   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2260   [(set_attr "type" "imovx")
2261    (set_attr "mode" "SI")])
2262
2263 (define_insn "*movhi_extv_1"
2264   [(set (match_operand:HI 0 "register_operand" "=R")
2265         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2266                          (const_int 8)
2267                          (const_int 8)))]
2268   ""
2269   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2270   [(set_attr "type" "imovx")
2271    (set_attr "mode" "SI")])
2272
2273 (define_insn "*movqi_extv_1"
2274   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2275         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2276                          (const_int 8)
2277                          (const_int 8)))]
2278   "!TARGET_64BIT"
2279 {
2280   switch (get_attr_type (insn))
2281     {
2282     case TYPE_IMOVX:
2283       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2284     default:
2285       return "mov{b}\t{%h1, %0|%0, %h1}";
2286     }
2287 }
2288   [(set (attr "type")
2289      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2290                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2291                              (ne (symbol_ref "TARGET_MOVX")
2292                                  (const_int 0))))
2293         (const_string "imovx")
2294         (const_string "imov")))
2295    (set (attr "mode")
2296      (if_then_else (eq_attr "type" "imovx")
2297         (const_string "SI")
2298         (const_string "QI")))])
2299
2300 (define_insn "*movqi_extv_1_rex64"
2301   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2302         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2303                          (const_int 8)
2304                          (const_int 8)))]
2305   "TARGET_64BIT"
2306 {
2307   switch (get_attr_type (insn))
2308     {
2309     case TYPE_IMOVX:
2310       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2311     default:
2312       return "mov{b}\t{%h1, %0|%0, %h1}";
2313     }
2314 }
2315   [(set (attr "type")
2316      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2317                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2318                              (ne (symbol_ref "TARGET_MOVX")
2319                                  (const_int 0))))
2320         (const_string "imovx")
2321         (const_string "imov")))
2322    (set (attr "mode")
2323      (if_then_else (eq_attr "type" "imovx")
2324         (const_string "SI")
2325         (const_string "QI")))])
2326
2327 ;; Stores and loads of ax to arbitrary constant address.
2328 ;; We fake an second form of instruction to force reload to load address
2329 ;; into register when rax is not available
2330 (define_insn "*movabsqi_1_rex64"
2331   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2332         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2333   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2334   "@
2335    movabs{b}\t{%1, %P0|%P0, %1}
2336    mov{b}\t{%1, %a0|%a0, %1}"
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" "store")
2342    (set_attr "mode" "QI")])
2343
2344 (define_insn "*movabsqi_2_rex64"
2345   [(set (match_operand:QI 0 "register_operand" "=a,r")
2346         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2347   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2348   "@
2349    movabs{b}\t{%P1, %0|%0, %P1}
2350    mov{b}\t{%a1, %0|%0, %a1}"
2351   [(set_attr "type" "imov")
2352    (set_attr "modrm" "0,*")
2353    (set_attr "length_address" "8,0")
2354    (set_attr "length_immediate" "0")
2355    (set_attr "memory" "load")
2356    (set_attr "mode" "QI")])
2357
2358 (define_insn "*movdi_extzv_1"
2359   [(set (match_operand:DI 0 "register_operand" "=R")
2360         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2361                          (const_int 8)
2362                          (const_int 8)))]
2363   "TARGET_64BIT"
2364   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2365   [(set_attr "type" "imovx")
2366    (set_attr "mode" "SI")])
2367
2368 (define_insn "*movsi_extzv_1"
2369   [(set (match_operand:SI 0 "register_operand" "=R")
2370         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2371                          (const_int 8)
2372                          (const_int 8)))]
2373   ""
2374   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2375   [(set_attr "type" "imovx")
2376    (set_attr "mode" "SI")])
2377
2378 (define_insn "*movqi_extzv_2"
2379   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2380         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2381                                     (const_int 8)
2382                                     (const_int 8)) 0))]
2383   "!TARGET_64BIT"
2384 {
2385   switch (get_attr_type (insn))
2386     {
2387     case TYPE_IMOVX:
2388       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2389     default:
2390       return "mov{b}\t{%h1, %0|%0, %h1}";
2391     }
2392 }
2393   [(set (attr "type")
2394      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2395                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2396                              (ne (symbol_ref "TARGET_MOVX")
2397                                  (const_int 0))))
2398         (const_string "imovx")
2399         (const_string "imov")))
2400    (set (attr "mode")
2401      (if_then_else (eq_attr "type" "imovx")
2402         (const_string "SI")
2403         (const_string "QI")))])
2404
2405 (define_insn "*movqi_extzv_2_rex64"
2406   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2407         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2408                                     (const_int 8)
2409                                     (const_int 8)) 0))]
2410   "TARGET_64BIT"
2411 {
2412   switch (get_attr_type (insn))
2413     {
2414     case TYPE_IMOVX:
2415       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2416     default:
2417       return "mov{b}\t{%h1, %0|%0, %h1}";
2418     }
2419 }
2420   [(set (attr "type")
2421      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2422                         (ne (symbol_ref "TARGET_MOVX")
2423                             (const_int 0)))
2424         (const_string "imovx")
2425         (const_string "imov")))
2426    (set (attr "mode")
2427      (if_then_else (eq_attr "type" "imovx")
2428         (const_string "SI")
2429         (const_string "QI")))])
2430
2431 (define_insn "movsi_insv_1"
2432   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2433                          (const_int 8)
2434                          (const_int 8))
2435         (match_operand:SI 1 "general_operand" "Qmn"))]
2436   "!TARGET_64BIT"
2437   "mov{b}\t{%b1, %h0|%h0, %b1}"
2438   [(set_attr "type" "imov")
2439    (set_attr "mode" "QI")])
2440
2441 (define_insn "*movsi_insv_1_rex64"
2442   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2443                          (const_int 8)
2444                          (const_int 8))
2445         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2446   "TARGET_64BIT"
2447   "mov{b}\t{%b1, %h0|%h0, %b1}"
2448   [(set_attr "type" "imov")
2449    (set_attr "mode" "QI")])
2450
2451 (define_insn "movdi_insv_1_rex64"
2452   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2453                          (const_int 8)
2454                          (const_int 8))
2455         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2456   "TARGET_64BIT"
2457   "mov{b}\t{%b1, %h0|%h0, %b1}"
2458   [(set_attr "type" "imov")
2459    (set_attr "mode" "QI")])
2460
2461 (define_insn "*movqi_insv_2"
2462   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2463                          (const_int 8)
2464                          (const_int 8))
2465         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2466                      (const_int 8)))]
2467   ""
2468   "mov{b}\t{%h1, %h0|%h0, %h1}"
2469   [(set_attr "type" "imov")
2470    (set_attr "mode" "QI")])
2471
2472 (define_expand "movdi"
2473   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2474         (match_operand:DI 1 "general_operand" ""))]
2475   ""
2476   "ix86_expand_move (DImode, operands); DONE;")
2477
2478 (define_insn "*pushdi"
2479   [(set (match_operand:DI 0 "push_operand" "=<")
2480         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2481   "!TARGET_64BIT"
2482   "#")
2483
2484 (define_insn "*pushdi2_rex64"
2485   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2486         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2487   "TARGET_64BIT"
2488   "@
2489    push{q}\t%1
2490    #"
2491   [(set_attr "type" "push,multi")
2492    (set_attr "mode" "DI")])
2493
2494 ;; Convert impossible pushes of immediate to existing instructions.
2495 ;; First try to get scratch register and go through it.  In case this
2496 ;; fails, push sign extended lower part first and then overwrite
2497 ;; upper part by 32bit move.
2498 (define_peephole2
2499   [(match_scratch:DI 2 "r")
2500    (set (match_operand:DI 0 "push_operand" "")
2501         (match_operand:DI 1 "immediate_operand" ""))]
2502   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2503    && !x86_64_immediate_operand (operands[1], DImode)"
2504   [(set (match_dup 2) (match_dup 1))
2505    (set (match_dup 0) (match_dup 2))]
2506   "")
2507
2508 ;; We need to define this as both peepholer and splitter for case
2509 ;; peephole2 pass is not run.
2510 ;; "&& 1" is needed to keep it from matching the previous pattern.
2511 (define_peephole2
2512   [(set (match_operand:DI 0 "push_operand" "")
2513         (match_operand:DI 1 "immediate_operand" ""))]
2514   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2515    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2516   [(set (match_dup 0) (match_dup 1))
2517    (set (match_dup 2) (match_dup 3))]
2518   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2519    operands[1] = gen_lowpart (DImode, operands[2]);
2520    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2521                                                     GEN_INT (4)));
2522   ")
2523
2524 (define_split
2525   [(set (match_operand:DI 0 "push_operand" "")
2526         (match_operand:DI 1 "immediate_operand" ""))]
2527   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2528                     ? epilogue_completed : reload_completed)
2529    && !symbolic_operand (operands[1], DImode)
2530    && !x86_64_immediate_operand (operands[1], DImode)"
2531   [(set (match_dup 0) (match_dup 1))
2532    (set (match_dup 2) (match_dup 3))]
2533   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2534    operands[1] = gen_lowpart (DImode, operands[2]);
2535    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2536                                                     GEN_INT (4)));
2537   ")
2538
2539 (define_insn "*pushdi2_prologue_rex64"
2540   [(set (match_operand:DI 0 "push_operand" "=<")
2541         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2542    (clobber (mem:BLK (scratch)))]
2543   "TARGET_64BIT"
2544   "push{q}\t%1"
2545   [(set_attr "type" "push")
2546    (set_attr "mode" "DI")])
2547
2548 (define_insn "*popdi1_epilogue_rex64"
2549   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2550         (mem:DI (reg:DI SP_REG)))
2551    (set (reg:DI SP_REG)
2552         (plus:DI (reg:DI SP_REG) (const_int 8)))
2553    (clobber (mem:BLK (scratch)))]
2554   "TARGET_64BIT"
2555   "pop{q}\t%0"
2556   [(set_attr "type" "pop")
2557    (set_attr "mode" "DI")])
2558
2559 (define_insn "popdi1"
2560   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2561         (mem:DI (reg:DI SP_REG)))
2562    (set (reg:DI SP_REG)
2563         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2564   "TARGET_64BIT"
2565   "pop{q}\t%0"
2566   [(set_attr "type" "pop")
2567    (set_attr "mode" "DI")])
2568
2569 (define_insn "*movdi_xor_rex64"
2570   [(set (match_operand:DI 0 "register_operand" "=r")
2571         (match_operand:DI 1 "const0_operand" ""))
2572    (clobber (reg:CC FLAGS_REG))]
2573   "TARGET_64BIT
2574    && reload_completed"
2575   "xor{l}\t%k0, %k0";
2576   [(set_attr "type" "alu1")
2577    (set_attr "mode" "SI")
2578    (set_attr "length_immediate" "0")])
2579
2580 (define_insn "*movdi_or_rex64"
2581   [(set (match_operand:DI 0 "register_operand" "=r")
2582         (match_operand:DI 1 "const_int_operand" "i"))
2583    (clobber (reg:CC FLAGS_REG))]
2584   "TARGET_64BIT
2585    && reload_completed
2586    && operands[1] == constm1_rtx"
2587 {
2588   operands[1] = constm1_rtx;
2589   return "or{q}\t{%1, %0|%0, %1}";
2590 }
2591   [(set_attr "type" "alu1")
2592    (set_attr "mode" "DI")
2593    (set_attr "length_immediate" "1")])
2594
2595 (define_insn "*movdi_2"
2596   [(set (match_operand:DI 0 "nonimmediate_operand"
2597                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2598         (match_operand:DI 1 "general_operand"
2599                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2600   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2601   "@
2602    #
2603    #
2604    pxor\t%0, %0
2605    movq\t{%1, %0|%0, %1}
2606    movq\t{%1, %0|%0, %1}
2607    %vpxor\t%0, %d0
2608    %vmovq\t{%1, %0|%0, %1}
2609    %vmovdqa\t{%1, %0|%0, %1}
2610    %vmovq\t{%1, %0|%0, %1}
2611    xorps\t%0, %0
2612    movlps\t{%1, %0|%0, %1}
2613    movaps\t{%1, %0|%0, %1}
2614    movlps\t{%1, %0|%0, %1}"
2615   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2616    (set (attr "prefix")
2617      (if_then_else (eq_attr "alternative" "5,6,7,8")
2618        (const_string "vex")
2619        (const_string "orig")))
2620    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2621
2622 (define_split
2623   [(set (match_operand:DI 0 "push_operand" "")
2624         (match_operand:DI 1 "general_operand" ""))]
2625   "!TARGET_64BIT && reload_completed
2626    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2627   [(const_int 0)]
2628   "ix86_split_long_move (operands); DONE;")
2629
2630 ;; %%% This multiword shite has got to go.
2631 (define_split
2632   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2633         (match_operand:DI 1 "general_operand" ""))]
2634   "!TARGET_64BIT && reload_completed
2635    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2636    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2637   [(const_int 0)]
2638   "ix86_split_long_move (operands); DONE;")
2639
2640 (define_insn "*movdi_1_rex64"
2641   [(set (match_operand:DI 0 "nonimmediate_operand"
2642           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2643         (match_operand:DI 1 "general_operand"
2644           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2645   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2646 {
2647   switch (get_attr_type (insn))
2648     {
2649     case TYPE_SSECVT:
2650       if (SSE_REG_P (operands[0]))
2651         return "movq2dq\t{%1, %0|%0, %1}";
2652       else
2653         return "movdq2q\t{%1, %0|%0, %1}";
2654
2655     case TYPE_SSEMOV:
2656       if (TARGET_AVX)
2657         {
2658           if (get_attr_mode (insn) == MODE_TI)
2659             return "vmovdqa\t{%1, %0|%0, %1}";
2660           else
2661             return "vmovq\t{%1, %0|%0, %1}";
2662         }
2663
2664       if (get_attr_mode (insn) == MODE_TI)
2665         return "movdqa\t{%1, %0|%0, %1}";
2666       /* FALLTHRU */
2667
2668     case TYPE_MMXMOV:
2669       /* Moves from and into integer register is done using movd
2670          opcode with REX prefix.  */
2671       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2672         return "movd\t{%1, %0|%0, %1}";
2673       return "movq\t{%1, %0|%0, %1}";
2674
2675     case TYPE_SSELOG1:
2676       return "%vpxor\t%0, %d0";
2677
2678     case TYPE_MMX:
2679       return "pxor\t%0, %0";
2680
2681     case TYPE_MULTI:
2682       return "#";
2683
2684     case TYPE_LEA:
2685       return "lea{q}\t{%a1, %0|%0, %a1}";
2686
2687     default:
2688       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2689       if (get_attr_mode (insn) == MODE_SI)
2690         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2691       else if (which_alternative == 2)
2692         return "movabs{q}\t{%1, %0|%0, %1}";
2693       else
2694         return "mov{q}\t{%1, %0|%0, %1}";
2695     }
2696 }
2697   [(set (attr "type")
2698      (cond [(eq_attr "alternative" "5")
2699               (const_string "mmx")
2700             (eq_attr "alternative" "6,7,8,9,10")
2701               (const_string "mmxmov")
2702             (eq_attr "alternative" "11")
2703               (const_string "sselog1")
2704             (eq_attr "alternative" "12,13,14,15,16")
2705               (const_string "ssemov")
2706             (eq_attr "alternative" "17,18")
2707               (const_string "ssecvt")
2708             (eq_attr "alternative" "4")
2709               (const_string "multi")
2710             (match_operand:DI 1 "pic_32bit_operand" "")
2711               (const_string "lea")
2712            ]
2713            (const_string "imov")))
2714    (set (attr "modrm")
2715      (if_then_else
2716        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2717          (const_string "0")
2718          (const_string "*")))
2719    (set (attr "length_immediate")
2720      (if_then_else
2721        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2722          (const_string "8")
2723          (const_string "*")))
2724    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2725    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2726    (set (attr "prefix")
2727      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2728        (const_string "maybe_vex")
2729        (const_string "orig")))
2730    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2731
2732 ;; Stores and loads of ax to arbitrary constant address.
2733 ;; We fake an second form of instruction to force reload to load address
2734 ;; into register when rax is not available
2735 (define_insn "*movabsdi_1_rex64"
2736   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2737         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2738   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2739   "@
2740    movabs{q}\t{%1, %P0|%P0, %1}
2741    mov{q}\t{%1, %a0|%a0, %1}"
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" "store")
2747    (set_attr "mode" "DI")])
2748
2749 (define_insn "*movabsdi_2_rex64"
2750   [(set (match_operand:DI 0 "register_operand" "=a,r")
2751         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2752   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2753   "@
2754    movabs{q}\t{%P1, %0|%0, %P1}
2755    mov{q}\t{%a1, %0|%0, %a1}"
2756   [(set_attr "type" "imov")
2757    (set_attr "modrm" "0,*")
2758    (set_attr "length_address" "8,0")
2759    (set_attr "length_immediate" "0")
2760    (set_attr "memory" "load")
2761    (set_attr "mode" "DI")])
2762
2763 ;; Convert impossible stores of immediate to existing instructions.
2764 ;; First try to get scratch register and go through it.  In case this
2765 ;; fails, move by 32bit parts.
2766 (define_peephole2
2767   [(match_scratch:DI 2 "r")
2768    (set (match_operand:DI 0 "memory_operand" "")
2769         (match_operand:DI 1 "immediate_operand" ""))]
2770   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2771    && !x86_64_immediate_operand (operands[1], DImode)"
2772   [(set (match_dup 2) (match_dup 1))
2773    (set (match_dup 0) (match_dup 2))]
2774   "")
2775
2776 ;; We need to define this as both peepholer and splitter for case
2777 ;; peephole2 pass is not run.
2778 ;; "&& 1" is needed to keep it from matching the previous pattern.
2779 (define_peephole2
2780   [(set (match_operand:DI 0 "memory_operand" "")
2781         (match_operand:DI 1 "immediate_operand" ""))]
2782   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2783    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2784   [(set (match_dup 2) (match_dup 3))
2785    (set (match_dup 4) (match_dup 5))]
2786   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2787
2788 (define_split
2789   [(set (match_operand:DI 0 "memory_operand" "")
2790         (match_operand:DI 1 "immediate_operand" ""))]
2791   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2792                     ? epilogue_completed : reload_completed)
2793    && !symbolic_operand (operands[1], DImode)
2794    && !x86_64_immediate_operand (operands[1], DImode)"
2795   [(set (match_dup 2) (match_dup 3))
2796    (set (match_dup 4) (match_dup 5))]
2797   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2798
2799 (define_insn "*swapdi_rex64"
2800   [(set (match_operand:DI 0 "register_operand" "+r")
2801         (match_operand:DI 1 "register_operand" "+r"))
2802    (set (match_dup 1)
2803         (match_dup 0))]
2804   "TARGET_64BIT"
2805   "xchg{q}\t%1, %0"
2806   [(set_attr "type" "imov")
2807    (set_attr "mode" "DI")
2808    (set_attr "pent_pair" "np")
2809    (set_attr "athlon_decode" "vector")
2810    (set_attr "amdfam10_decode" "double")])
2811
2812 (define_expand "movoi"
2813   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2814         (match_operand:OI 1 "general_operand" ""))]
2815   "TARGET_AVX"
2816   "ix86_expand_move (OImode, operands); DONE;")
2817
2818 (define_insn "*movoi_internal"
2819   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2820         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2821   "TARGET_AVX
2822    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2823 {
2824   switch (which_alternative)
2825     {
2826     case 0:
2827       return "vxorps\t%0, %0, %0";
2828     case 1:
2829     case 2:
2830       if (misaligned_operand (operands[0], OImode)
2831           || misaligned_operand (operands[1], OImode))
2832         return "vmovdqu\t{%1, %0|%0, %1}";
2833       else
2834         return "vmovdqa\t{%1, %0|%0, %1}";
2835     default:
2836       gcc_unreachable ();
2837     }
2838 }
2839   [(set_attr "type" "sselog1,ssemov,ssemov")
2840    (set_attr "prefix" "vex")
2841    (set_attr "mode" "OI")])
2842
2843 (define_expand "movti"
2844   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2845         (match_operand:TI 1 "nonimmediate_operand" ""))]
2846   "TARGET_SSE || TARGET_64BIT"
2847 {
2848   if (TARGET_64BIT)
2849     ix86_expand_move (TImode, operands);
2850   else if (push_operand (operands[0], TImode))
2851     ix86_expand_push (TImode, operands[1]);
2852   else
2853     ix86_expand_vector_move (TImode, operands);
2854   DONE;
2855 })
2856
2857 (define_insn "*movti_internal"
2858   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2859         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2860   "TARGET_SSE && !TARGET_64BIT
2861    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2862 {
2863   switch (which_alternative)
2864     {
2865     case 0:
2866       if (get_attr_mode (insn) == MODE_V4SF)
2867         return "%vxorps\t%0, %d0";
2868       else
2869         return "%vpxor\t%0, %d0";
2870     case 1:
2871     case 2:
2872       /* TDmode values are passed as TImode on the stack.  Moving them
2873          to stack may result in unaligned memory access.  */
2874       if (misaligned_operand (operands[0], TImode)
2875           || misaligned_operand (operands[1], TImode))
2876         {
2877           if (get_attr_mode (insn) == MODE_V4SF)
2878             return "%vmovups\t{%1, %0|%0, %1}";
2879          else
2880            return "%vmovdqu\t{%1, %0|%0, %1}";
2881         }
2882       else
2883         {
2884           if (get_attr_mode (insn) == MODE_V4SF)
2885             return "%vmovaps\t{%1, %0|%0, %1}";
2886          else
2887            return "%vmovdqa\t{%1, %0|%0, %1}";
2888         }
2889     default:
2890       gcc_unreachable ();
2891     }
2892 }
2893   [(set_attr "type" "sselog1,ssemov,ssemov")
2894    (set_attr "prefix" "maybe_vex")
2895    (set (attr "mode")
2896         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2897                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2898                  (const_string "V4SF")
2899                (and (eq_attr "alternative" "2")
2900                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2901                         (const_int 0)))
2902                  (const_string "V4SF")]
2903               (const_string "TI")))])
2904
2905 (define_insn "*movti_rex64"
2906   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2907         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2908   "TARGET_64BIT
2909    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2910 {
2911   switch (which_alternative)
2912     {
2913     case 0:
2914     case 1:
2915       return "#";
2916     case 2:
2917       if (get_attr_mode (insn) == MODE_V4SF)
2918         return "%vxorps\t%0, %d0";
2919       else
2920         return "%vpxor\t%0, %d0";
2921     case 3:
2922     case 4:
2923       /* TDmode values are passed as TImode on the stack.  Moving them
2924          to stack may result in unaligned memory access.  */
2925       if (misaligned_operand (operands[0], TImode)
2926           || misaligned_operand (operands[1], TImode))
2927         {
2928           if (get_attr_mode (insn) == MODE_V4SF)
2929             return "%vmovups\t{%1, %0|%0, %1}";
2930          else
2931            return "%vmovdqu\t{%1, %0|%0, %1}";
2932         }
2933       else
2934         {
2935           if (get_attr_mode (insn) == MODE_V4SF)
2936             return "%vmovaps\t{%1, %0|%0, %1}";
2937          else
2938            return "%vmovdqa\t{%1, %0|%0, %1}";
2939         }
2940     default:
2941       gcc_unreachable ();
2942     }
2943 }
2944   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2945    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2946    (set (attr "mode")
2947         (cond [(eq_attr "alternative" "2,3")
2948                  (if_then_else
2949                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2950                        (const_int 0))
2951                    (const_string "V4SF")
2952                    (const_string "TI"))
2953                (eq_attr "alternative" "4")
2954                  (if_then_else
2955                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2956                             (const_int 0))
2957                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2958                             (const_int 0)))
2959                    (const_string "V4SF")
2960                    (const_string "TI"))]
2961                (const_string "DI")))])
2962
2963 (define_split
2964   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2965         (match_operand:TI 1 "general_operand" ""))]
2966   "reload_completed && !SSE_REG_P (operands[0])
2967    && !SSE_REG_P (operands[1])"
2968   [(const_int 0)]
2969   "ix86_split_long_move (operands); DONE;")
2970
2971 ;; This expands to what emit_move_complex would generate if we didn't
2972 ;; have a movti pattern.  Having this avoids problems with reload on
2973 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2974 ;; to have around all the time.
2975 (define_expand "movcdi"
2976   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2977         (match_operand:CDI 1 "general_operand" ""))]
2978   ""
2979 {
2980   if (push_operand (operands[0], CDImode))
2981     emit_move_complex_push (CDImode, operands[0], operands[1]);
2982   else
2983     emit_move_complex_parts (operands[0], operands[1]);
2984   DONE;
2985 })
2986
2987 (define_expand "movsf"
2988   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2989         (match_operand:SF 1 "general_operand" ""))]
2990   ""
2991   "ix86_expand_move (SFmode, operands); DONE;")
2992
2993 (define_insn "*pushsf"
2994   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2995         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2996   "!TARGET_64BIT"
2997 {
2998   /* Anything else should be already split before reg-stack.  */
2999   gcc_assert (which_alternative == 1);
3000   return "push{l}\t%1";
3001 }
3002   [(set_attr "type" "multi,push,multi")
3003    (set_attr "unit" "i387,*,*")
3004    (set_attr "mode" "SF,SI,SF")])
3005
3006 (define_insn "*pushsf_rex64"
3007   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3008         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3009   "TARGET_64BIT"
3010 {
3011   /* Anything else should be already split before reg-stack.  */
3012   gcc_assert (which_alternative == 1);
3013   return "push{q}\t%q1";
3014 }
3015   [(set_attr "type" "multi,push,multi")
3016    (set_attr "unit" "i387,*,*")
3017    (set_attr "mode" "SF,DI,SF")])
3018
3019 (define_split
3020   [(set (match_operand:SF 0 "push_operand" "")
3021         (match_operand:SF 1 "memory_operand" ""))]
3022   "reload_completed
3023    && MEM_P (operands[1])
3024    && (operands[2] = find_constant_src (insn))"
3025   [(set (match_dup 0)
3026         (match_dup 2))])
3027
3028 ;; %%% Kill this when call knows how to work this out.
3029 (define_split
3030   [(set (match_operand:SF 0 "push_operand" "")
3031         (match_operand:SF 1 "any_fp_register_operand" ""))]
3032   "!TARGET_64BIT"
3033   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3034    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3035
3036 (define_split
3037   [(set (match_operand:SF 0 "push_operand" "")
3038         (match_operand:SF 1 "any_fp_register_operand" ""))]
3039   "TARGET_64BIT"
3040   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3041    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3042
3043 (define_insn "*movsf_1"
3044   [(set (match_operand:SF 0 "nonimmediate_operand"
3045           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3046         (match_operand:SF 1 "general_operand"
3047           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3048   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3049    && (reload_in_progress || reload_completed
3050        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3051        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3052            && standard_80387_constant_p (operands[1]))
3053        || GET_CODE (operands[1]) != CONST_DOUBLE
3054        || memory_operand (operands[0], SFmode))"
3055 {
3056   switch (which_alternative)
3057     {
3058     case 0:
3059     case 1:
3060       return output_387_reg_move (insn, operands);
3061
3062     case 2:
3063       return standard_80387_constant_opcode (operands[1]);
3064
3065     case 3:
3066     case 4:
3067       return "mov{l}\t{%1, %0|%0, %1}";
3068     case 5:
3069       if (get_attr_mode (insn) == MODE_TI)
3070         return "%vpxor\t%0, %d0";
3071       else
3072         return "%vxorps\t%0, %d0";
3073     case 6:
3074       if (get_attr_mode (insn) == MODE_V4SF)
3075         return "%vmovaps\t{%1, %0|%0, %1}";
3076       else
3077         return "%vmovss\t{%1, %d0|%d0, %1}";
3078     case 7:
3079       if (TARGET_AVX)
3080         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3081                                    : "vmovss\t{%1, %0|%0, %1}";
3082       else
3083         return "movss\t{%1, %0|%0, %1}";
3084     case 8:
3085       return "%vmovss\t{%1, %0|%0, %1}";
3086
3087     case 9: case 10: case 14: case 15:
3088       return "movd\t{%1, %0|%0, %1}";
3089     case 12: case 13:
3090       return "%vmovd\t{%1, %0|%0, %1}";
3091
3092     case 11:
3093       return "movq\t{%1, %0|%0, %1}";
3094
3095     default:
3096       gcc_unreachable ();
3097     }
3098 }
3099   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3100    (set (attr "prefix")
3101      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3102        (const_string "maybe_vex")
3103        (const_string "orig")))
3104    (set (attr "mode")
3105         (cond [(eq_attr "alternative" "3,4,9,10")
3106                  (const_string "SI")
3107                (eq_attr "alternative" "5")
3108                  (if_then_else
3109                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3110                                  (const_int 0))
3111                              (ne (symbol_ref "TARGET_SSE2")
3112                                  (const_int 0)))
3113                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3114                             (const_int 0)))
3115                    (const_string "TI")
3116                    (const_string "V4SF"))
3117                /* For architectures resolving dependencies on
3118                   whole SSE registers use APS move to break dependency
3119                   chains, otherwise use short move to avoid extra work.
3120
3121                   Do the same for architectures resolving dependencies on
3122                   the parts.  While in DF mode it is better to always handle
3123                   just register parts, the SF mode is different due to lack
3124                   of instructions to load just part of the register.  It is
3125                   better to maintain the whole registers in single format
3126                   to avoid problems on using packed logical operations.  */
3127                (eq_attr "alternative" "6")
3128                  (if_then_else
3129                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3130                             (const_int 0))
3131                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3132                             (const_int 0)))
3133                    (const_string "V4SF")
3134                    (const_string "SF"))
3135                (eq_attr "alternative" "11")
3136                  (const_string "DI")]
3137                (const_string "SF")))])
3138
3139 (define_insn "*swapsf"
3140   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3141         (match_operand:SF 1 "fp_register_operand" "+f"))
3142    (set (match_dup 1)
3143         (match_dup 0))]
3144   "reload_completed || TARGET_80387"
3145 {
3146   if (STACK_TOP_P (operands[0]))
3147     return "fxch\t%1";
3148   else
3149     return "fxch\t%0";
3150 }
3151   [(set_attr "type" "fxch")
3152    (set_attr "mode" "SF")])
3153
3154 (define_expand "movdf"
3155   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3156         (match_operand:DF 1 "general_operand" ""))]
3157   ""
3158   "ix86_expand_move (DFmode, operands); DONE;")
3159
3160 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3161 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3162 ;; On the average, pushdf using integers can be still shorter.  Allow this
3163 ;; pattern for optimize_size too.
3164
3165 (define_insn "*pushdf_nointeger"
3166   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3167         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3168   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3169 {
3170   /* This insn should be already split before reg-stack.  */
3171   gcc_unreachable ();
3172 }
3173   [(set_attr "type" "multi")
3174    (set_attr "unit" "i387,*,*,*")
3175    (set_attr "mode" "DF,SI,SI,DF")])
3176
3177 (define_insn "*pushdf_integer"
3178   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3179         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3180   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3181 {
3182   /* This insn should be already split before reg-stack.  */
3183   gcc_unreachable ();
3184 }
3185   [(set_attr "type" "multi")
3186    (set_attr "unit" "i387,*,*")
3187    (set_attr "mode" "DF,SI,DF")])
3188
3189 ;; %%% Kill this when call knows how to work this out.
3190 (define_split
3191   [(set (match_operand:DF 0 "push_operand" "")
3192         (match_operand:DF 1 "any_fp_register_operand" ""))]
3193   "reload_completed"
3194   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3195    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3196   "")
3197
3198 (define_split
3199   [(set (match_operand:DF 0 "push_operand" "")
3200         (match_operand:DF 1 "general_operand" ""))]
3201   "reload_completed"
3202   [(const_int 0)]
3203   "ix86_split_long_move (operands); DONE;")
3204
3205 ;; Moving is usually shorter when only FP registers are used. This separate
3206 ;; movdf pattern avoids the use of integer registers for FP operations
3207 ;; when optimizing for size.
3208
3209 (define_insn "*movdf_nointeger"
3210   [(set (match_operand:DF 0 "nonimmediate_operand"
3211                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3212         (match_operand:DF 1 "general_operand"
3213                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3214   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3215    && ((optimize_function_for_size_p (cfun)
3216        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3217    && (reload_in_progress || reload_completed
3218        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3219        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3220            && optimize_function_for_size_p (cfun)
3221            && !memory_operand (operands[0], DFmode)
3222            && standard_80387_constant_p (operands[1]))
3223        || GET_CODE (operands[1]) != CONST_DOUBLE
3224        || ((optimize_function_for_size_p (cfun)
3225             || !TARGET_MEMORY_MISMATCH_STALL
3226             || reload_in_progress || reload_completed)
3227            && memory_operand (operands[0], DFmode)))"
3228 {
3229   switch (which_alternative)
3230     {
3231     case 0:
3232     case 1:
3233       return output_387_reg_move (insn, operands);
3234
3235     case 2:
3236       return standard_80387_constant_opcode (operands[1]);
3237
3238     case 3:
3239     case 4:
3240       return "#";
3241     case 5:
3242       switch (get_attr_mode (insn))
3243         {
3244         case MODE_V4SF:
3245           return "%vxorps\t%0, %d0";
3246         case MODE_V2DF:
3247           return "%vxorpd\t%0, %d0";
3248         case MODE_TI:
3249           return "%vpxor\t%0, %d0";
3250         default:
3251           gcc_unreachable ();
3252         }
3253     case 6:
3254     case 7:
3255     case 8:
3256       switch (get_attr_mode (insn))
3257         {
3258         case MODE_V4SF:
3259           return "%vmovaps\t{%1, %0|%0, %1}";
3260         case MODE_V2DF:
3261           return "%vmovapd\t{%1, %0|%0, %1}";
3262         case MODE_TI:
3263           return "%vmovdqa\t{%1, %0|%0, %1}";
3264         case MODE_DI:
3265           return "%vmovq\t{%1, %0|%0, %1}";
3266         case MODE_DF:
3267           if (TARGET_AVX)
3268             {
3269               if (REG_P (operands[0]) && REG_P (operands[1]))
3270                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3271               else
3272                 return "vmovsd\t{%1, %0|%0, %1}";
3273             }
3274           else
3275             return "movsd\t{%1, %0|%0, %1}";
3276         case MODE_V1DF:
3277           if (TARGET_AVX)
3278             {
3279               if (REG_P (operands[0]))
3280                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3281               else
3282                 return "vmovlpd\t{%1, %0|%0, %1}";
3283             }
3284           else
3285             return "movlpd\t{%1, %0|%0, %1}";
3286         case MODE_V2SF:
3287           if (TARGET_AVX)
3288             {
3289               if (REG_P (operands[0]))
3290                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3291               else
3292                 return "vmovlps\t{%1, %0|%0, %1}";
3293             }
3294           else
3295             return "movlps\t{%1, %0|%0, %1}";
3296         default:
3297           gcc_unreachable ();
3298         }
3299
3300     default:
3301       gcc_unreachable ();
3302     }
3303 }
3304   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3305    (set (attr "prefix")
3306      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3307        (const_string "orig")
3308        (const_string "maybe_vex")))
3309    (set (attr "prefix_data16")
3310      (if_then_else (eq_attr "mode" "V1DF")
3311        (const_string "1")
3312        (const_string "*")))
3313    (set (attr "mode")
3314         (cond [(eq_attr "alternative" "0,1,2")
3315                  (const_string "DF")
3316                (eq_attr "alternative" "3,4")
3317                  (const_string "SI")
3318
3319                /* For SSE1, we have many fewer alternatives.  */
3320                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3321                  (cond [(eq_attr "alternative" "5,6")
3322                           (const_string "V4SF")
3323                        ]
3324                    (const_string "V2SF"))
3325
3326                /* xorps is one byte shorter.  */
3327                (eq_attr "alternative" "5")
3328                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3329                             (const_int 0))
3330                           (const_string "V4SF")
3331                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3332                             (const_int 0))
3333                           (const_string "TI")
3334                        ]
3335                        (const_string "V2DF"))
3336
3337                /* For architectures resolving dependencies on
3338                   whole SSE registers use APD move to break dependency
3339                   chains, otherwise use short move to avoid extra work.
3340
3341                   movaps encodes one byte shorter.  */
3342                (eq_attr "alternative" "6")
3343                  (cond
3344                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3345                         (const_int 0))
3346                       (const_string "V4SF")
3347                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3348                         (const_int 0))
3349                       (const_string "V2DF")
3350                    ]
3351                    (const_string "DF"))
3352                /* For architectures resolving dependencies on register
3353                   parts we may avoid extra work to zero out upper part
3354                   of register.  */
3355                (eq_attr "alternative" "7")
3356                  (if_then_else
3357                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3358                        (const_int 0))
3359                    (const_string "V1DF")
3360                    (const_string "DF"))
3361               ]
3362               (const_string "DF")))])
3363
3364 (define_insn "*movdf_integer_rex64"
3365   [(set (match_operand:DF 0 "nonimmediate_operand"
3366                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3367         (match_operand:DF 1 "general_operand"
3368                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3369   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3370    && (reload_in_progress || reload_completed
3371        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3372        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3373            && optimize_function_for_size_p (cfun)
3374            && standard_80387_constant_p (operands[1]))
3375        || GET_CODE (operands[1]) != CONST_DOUBLE
3376        || memory_operand (operands[0], DFmode))"
3377 {
3378   switch (which_alternative)
3379     {
3380     case 0:
3381     case 1:
3382       return output_387_reg_move (insn, operands);
3383
3384     case 2:
3385       return standard_80387_constant_opcode (operands[1]);
3386
3387     case 3:
3388     case 4:
3389       return "#";
3390
3391     case 5:
3392       switch (get_attr_mode (insn))
3393         {
3394         case MODE_V4SF:
3395           return "%vxorps\t%0, %d0";
3396         case MODE_V2DF:
3397           return "%vxorpd\t%0, %d0";
3398         case MODE_TI:
3399           return "%vpxor\t%0, %d0";
3400         default:
3401           gcc_unreachable ();
3402         }
3403     case 6:
3404     case 7:
3405     case 8:
3406       switch (get_attr_mode (insn))
3407         {
3408         case MODE_V4SF:
3409           return "%vmovaps\t{%1, %0|%0, %1}";
3410         case MODE_V2DF:
3411           return "%vmovapd\t{%1, %0|%0, %1}";
3412         case MODE_TI:
3413           return "%vmovdqa\t{%1, %0|%0, %1}";
3414         case MODE_DI:
3415           return "%vmovq\t{%1, %0|%0, %1}";
3416         case MODE_DF:
3417           if (TARGET_AVX)
3418             {
3419               if (REG_P (operands[0]) && REG_P (operands[1]))
3420                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3421               else
3422                 return "vmovsd\t{%1, %0|%0, %1}";
3423             }
3424           else
3425             return "movsd\t{%1, %0|%0, %1}";
3426         case MODE_V1DF:
3427           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3428         case MODE_V2SF:
3429           return "%vmovlps\t{%1, %d0|%d0, %1}";
3430         default:
3431           gcc_unreachable ();
3432         }
3433
3434     case 9:
3435     case 10:
3436     return "%vmovd\t{%1, %0|%0, %1}";
3437
3438     default:
3439       gcc_unreachable();
3440     }
3441 }
3442   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3443    (set (attr "prefix")
3444      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3445        (const_string "orig")
3446        (const_string "maybe_vex")))
3447    (set (attr "prefix_data16")
3448      (if_then_else (eq_attr "mode" "V1DF")
3449        (const_string "1")
3450        (const_string "*")))
3451    (set (attr "mode")
3452         (cond [(eq_attr "alternative" "0,1,2")
3453                  (const_string "DF")
3454                (eq_attr "alternative" "3,4,9,10")
3455                  (const_string "DI")
3456
3457                /* For SSE1, we have many fewer alternatives.  */
3458                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3459                  (cond [(eq_attr "alternative" "5,6")
3460                           (const_string "V4SF")
3461                        ]
3462                    (const_string "V2SF"))
3463
3464                /* xorps is one byte shorter.  */
3465                (eq_attr "alternative" "5")
3466                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3467                             (const_int 0))
3468                           (const_string "V4SF")
3469                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3470                             (const_int 0))
3471                           (const_string "TI")
3472                        ]
3473                        (const_string "V2DF"))
3474
3475                /* For architectures resolving dependencies on
3476                   whole SSE registers use APD move to break dependency
3477                   chains, otherwise use short move to avoid extra work.
3478
3479                   movaps encodes one byte shorter.  */
3480                (eq_attr "alternative" "6")
3481                  (cond
3482                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3483                         (const_int 0))
3484                       (const_string "V4SF")
3485                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3486                         (const_int 0))
3487                       (const_string "V2DF")
3488                    ]
3489                    (const_string "DF"))
3490                /* For architectures resolving dependencies on register
3491                   parts we may avoid extra work to zero out upper part
3492                   of register.  */
3493                (eq_attr "alternative" "7")
3494                  (if_then_else
3495                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3496                        (const_int 0))
3497                    (const_string "V1DF")
3498                    (const_string "DF"))
3499               ]
3500               (const_string "DF")))])
3501
3502 (define_insn "*movdf_integer"
3503   [(set (match_operand:DF 0 "nonimmediate_operand"
3504                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3505         (match_operand:DF 1 "general_operand"
3506                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3507   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3508    && optimize_function_for_speed_p (cfun)
3509    && TARGET_INTEGER_DFMODE_MOVES
3510    && (reload_in_progress || reload_completed
3511        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3512        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3513            && optimize_function_for_size_p (cfun)
3514            && standard_80387_constant_p (operands[1]))
3515        || GET_CODE (operands[1]) != CONST_DOUBLE
3516        || memory_operand (operands[0], DFmode))"
3517 {
3518   switch (which_alternative)
3519     {
3520     case 0:
3521     case 1:
3522       return output_387_reg_move (insn, operands);
3523
3524     case 2:
3525       return standard_80387_constant_opcode (operands[1]);
3526
3527     case 3:
3528     case 4:
3529       return "#";
3530
3531     case 5:
3532       switch (get_attr_mode (insn))
3533         {
3534         case MODE_V4SF:
3535           return "xorps\t%0, %0";
3536         case MODE_V2DF:
3537           return "xorpd\t%0, %0";
3538         case MODE_TI:
3539           return "pxor\t%0, %0";
3540         default:
3541           gcc_unreachable ();
3542         }
3543     case 6:
3544     case 7:
3545     case 8:
3546       switch (get_attr_mode (insn))
3547         {
3548         case MODE_V4SF:
3549           return "movaps\t{%1, %0|%0, %1}";
3550         case MODE_V2DF:
3551           return "movapd\t{%1, %0|%0, %1}";
3552         case MODE_TI:
3553           return "movdqa\t{%1, %0|%0, %1}";
3554         case MODE_DI:
3555           return "movq\t{%1, %0|%0, %1}";
3556         case MODE_DF:
3557           return "movsd\t{%1, %0|%0, %1}";
3558         case MODE_V1DF:
3559           return "movlpd\t{%1, %0|%0, %1}";
3560         case MODE_V2SF:
3561           return "movlps\t{%1, %0|%0, %1}";
3562         default:
3563           gcc_unreachable ();
3564         }
3565
3566     default:
3567       gcc_unreachable();
3568     }
3569 }
3570   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3571    (set (attr "prefix_data16")
3572      (if_then_else (eq_attr "mode" "V1DF")
3573        (const_string "1")
3574        (const_string "*")))
3575    (set (attr "mode")
3576         (cond [(eq_attr "alternative" "0,1,2")
3577                  (const_string "DF")
3578                (eq_attr "alternative" "3,4")
3579                  (const_string "SI")
3580
3581                /* For SSE1, we have many fewer alternatives.  */
3582                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3583                  (cond [(eq_attr "alternative" "5,6")
3584                           (const_string "V4SF")
3585                        ]
3586                    (const_string "V2SF"))
3587
3588                /* xorps is one byte shorter.  */
3589                (eq_attr "alternative" "5")
3590                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3591                             (const_int 0))
3592                           (const_string "V4SF")
3593                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3594                             (const_int 0))
3595                           (const_string "TI")
3596                        ]
3597                        (const_string "V2DF"))
3598
3599                /* For architectures resolving dependencies on
3600                   whole SSE registers use APD move to break dependency
3601                   chains, otherwise use short move to avoid extra work.
3602
3603                   movaps encodes one byte shorter.  */
3604                (eq_attr "alternative" "6")
3605                  (cond
3606                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3607                         (const_int 0))
3608                       (const_string "V4SF")
3609                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3610                         (const_int 0))
3611                       (const_string "V2DF")
3612                    ]
3613                    (const_string "DF"))
3614                /* For architectures resolving dependencies on register
3615                   parts we may avoid extra work to zero out upper part
3616                   of register.  */
3617                (eq_attr "alternative" "7")
3618                  (if_then_else
3619                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3620                        (const_int 0))
3621                    (const_string "V1DF")
3622                    (const_string "DF"))
3623               ]
3624               (const_string "DF")))])
3625
3626 (define_split
3627   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3628         (match_operand:DF 1 "general_operand" ""))]
3629   "reload_completed
3630    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3631    && ! (ANY_FP_REG_P (operands[0]) ||
3632          (GET_CODE (operands[0]) == SUBREG
3633           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3634    && ! (ANY_FP_REG_P (operands[1]) ||
3635          (GET_CODE (operands[1]) == SUBREG
3636           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3637   [(const_int 0)]
3638   "ix86_split_long_move (operands); DONE;")
3639
3640 (define_insn "*swapdf"
3641   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3642         (match_operand:DF 1 "fp_register_operand" "+f"))
3643    (set (match_dup 1)
3644         (match_dup 0))]
3645   "reload_completed || TARGET_80387"
3646 {
3647   if (STACK_TOP_P (operands[0]))
3648     return "fxch\t%1";
3649   else
3650     return "fxch\t%0";
3651 }
3652   [(set_attr "type" "fxch")
3653    (set_attr "mode" "DF")])
3654
3655 (define_expand "movxf"
3656   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3657         (match_operand:XF 1 "general_operand" ""))]
3658   ""
3659   "ix86_expand_move (XFmode, operands); DONE;")
3660
3661 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3662 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3663 ;; Pushing using integer instructions is longer except for constants
3664 ;; and direct memory references.
3665 ;; (assuming that any given constant is pushed only once, but this ought to be
3666 ;;  handled elsewhere).
3667
3668 (define_insn "*pushxf_nointeger"
3669   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3670         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3671   "optimize_function_for_size_p (cfun)"
3672 {
3673   /* This insn should be already split before reg-stack.  */
3674   gcc_unreachable ();
3675 }
3676   [(set_attr "type" "multi")
3677    (set_attr "unit" "i387,*,*")
3678    (set_attr "mode" "XF,SI,SI")])
3679
3680 (define_insn "*pushxf_integer"
3681   [(set (match_operand:XF 0 "push_operand" "=<,<")
3682         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3683   "optimize_function_for_speed_p (cfun)"
3684 {
3685   /* This insn should be already split before reg-stack.  */
3686   gcc_unreachable ();
3687 }
3688   [(set_attr "type" "multi")
3689    (set_attr "unit" "i387,*")
3690    (set_attr "mode" "XF,SI")])
3691
3692 (define_split
3693   [(set (match_operand 0 "push_operand" "")
3694         (match_operand 1 "general_operand" ""))]
3695   "reload_completed
3696    && (GET_MODE (operands[0]) == XFmode
3697        || GET_MODE (operands[0]) == DFmode)
3698    && !ANY_FP_REG_P (operands[1])"
3699   [(const_int 0)]
3700   "ix86_split_long_move (operands); DONE;")
3701
3702 (define_split
3703   [(set (match_operand:XF 0 "push_operand" "")
3704         (match_operand:XF 1 "any_fp_register_operand" ""))]
3705   ""
3706   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3707    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3708   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3709
3710 ;; Do not use integer registers when optimizing for size
3711 (define_insn "*movxf_nointeger"
3712   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3713         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3714   "optimize_function_for_size_p (cfun)
3715    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3716    && (reload_in_progress || reload_completed
3717        || standard_80387_constant_p (operands[1])
3718        || GET_CODE (operands[1]) != CONST_DOUBLE
3719        || memory_operand (operands[0], XFmode))"
3720 {
3721   switch (which_alternative)
3722     {
3723     case 0:
3724     case 1:
3725       return output_387_reg_move (insn, operands);
3726
3727     case 2:
3728       return standard_80387_constant_opcode (operands[1]);
3729
3730     case 3: case 4:
3731       return "#";
3732     default:
3733       gcc_unreachable ();
3734     }
3735 }
3736   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3737    (set_attr "mode" "XF,XF,XF,SI,SI")])
3738
3739 (define_insn "*movxf_integer"
3740   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3741         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3742   "optimize_function_for_speed_p (cfun)
3743    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3744    && (reload_in_progress || reload_completed
3745        || GET_CODE (operands[1]) != CONST_DOUBLE
3746        || memory_operand (operands[0], XFmode))"
3747 {
3748   switch (which_alternative)
3749     {
3750     case 0:
3751     case 1:
3752       return output_387_reg_move (insn, operands);
3753
3754     case 2:
3755       return standard_80387_constant_opcode (operands[1]);
3756
3757     case 3: case 4:
3758       return "#";
3759
3760     default:
3761       gcc_unreachable ();
3762     }
3763 }
3764   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3765    (set_attr "mode" "XF,XF,XF,SI,SI")])
3766
3767 (define_expand "movtf"
3768   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3769         (match_operand:TF 1 "nonimmediate_operand" ""))]
3770   "TARGET_SSE2"
3771 {
3772   ix86_expand_move (TFmode, operands);
3773   DONE;
3774 })
3775
3776 (define_insn "*movtf_internal"
3777   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3778         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3779   "TARGET_SSE2
3780    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3781 {
3782   switch (which_alternative)
3783     {
3784     case 0:
3785     case 1:
3786       if (get_attr_mode (insn) == MODE_V4SF)
3787         return "%vmovaps\t{%1, %0|%0, %1}";
3788       else
3789         return "%vmovdqa\t{%1, %0|%0, %1}";
3790     case 2:
3791       if (get_attr_mode (insn) == MODE_V4SF)
3792         return "%vxorps\t%0, %d0";
3793       else
3794         return "%vpxor\t%0, %d0";
3795     case 3:
3796     case 4:
3797         return "#";
3798     default:
3799       gcc_unreachable ();
3800     }
3801 }
3802   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3803    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3804    (set (attr "mode")
3805         (cond [(eq_attr "alternative" "0,2")
3806                  (if_then_else
3807                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3808                        (const_int 0))
3809                    (const_string "V4SF")
3810                    (const_string "TI"))
3811                (eq_attr "alternative" "1")
3812                  (if_then_else
3813                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3814                             (const_int 0))
3815                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3816                             (const_int 0)))
3817                    (const_string "V4SF")
3818                    (const_string "TI"))]
3819                (const_string "DI")))])
3820
3821 (define_insn "*pushtf_sse"
3822   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3823         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3824   "TARGET_SSE2"
3825 {
3826   /* This insn should be already split before reg-stack.  */
3827   gcc_unreachable ();
3828 }
3829   [(set_attr "type" "multi")
3830    (set_attr "unit" "sse,*,*")
3831    (set_attr "mode" "TF,SI,SI")])
3832
3833 (define_split
3834   [(set (match_operand:TF 0 "push_operand" "")
3835         (match_operand:TF 1 "general_operand" ""))]
3836   "TARGET_SSE2 && reload_completed
3837    && !SSE_REG_P (operands[1])"
3838   [(const_int 0)]
3839   "ix86_split_long_move (operands); DONE;")
3840
3841 (define_split
3842   [(set (match_operand:TF 0 "push_operand" "")
3843         (match_operand:TF 1 "any_fp_register_operand" ""))]
3844   "TARGET_SSE2"
3845   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3846    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3847   "")
3848
3849 (define_split
3850   [(set (match_operand 0 "nonimmediate_operand" "")
3851         (match_operand 1 "general_operand" ""))]
3852   "reload_completed
3853    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3854    && GET_MODE (operands[0]) == XFmode
3855    && ! (ANY_FP_REG_P (operands[0]) ||
3856          (GET_CODE (operands[0]) == SUBREG
3857           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3858    && ! (ANY_FP_REG_P (operands[1]) ||
3859          (GET_CODE (operands[1]) == SUBREG
3860           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3861   [(const_int 0)]
3862   "ix86_split_long_move (operands); DONE;")
3863
3864 (define_split
3865   [(set (match_operand 0 "register_operand" "")
3866         (match_operand 1 "memory_operand" ""))]
3867   "reload_completed
3868    && MEM_P (operands[1])
3869    && (GET_MODE (operands[0]) == TFmode
3870        || GET_MODE (operands[0]) == XFmode
3871        || GET_MODE (operands[0]) == SFmode
3872        || GET_MODE (operands[0]) == DFmode)
3873    && (operands[2] = find_constant_src (insn))"
3874   [(set (match_dup 0) (match_dup 2))]
3875 {
3876   rtx c = operands[2];
3877   rtx r = operands[0];
3878
3879   if (GET_CODE (r) == SUBREG)
3880     r = SUBREG_REG (r);
3881
3882   if (SSE_REG_P (r))
3883     {
3884       if (!standard_sse_constant_p (c))
3885         FAIL;
3886     }
3887   else if (FP_REG_P (r))
3888     {
3889       if (!standard_80387_constant_p (c))
3890         FAIL;
3891     }
3892   else if (MMX_REG_P (r))
3893     FAIL;
3894 })
3895
3896 (define_split
3897   [(set (match_operand 0 "register_operand" "")
3898         (float_extend (match_operand 1 "memory_operand" "")))]
3899   "reload_completed
3900    && MEM_P (operands[1])
3901    && (GET_MODE (operands[0]) == TFmode
3902        || GET_MODE (operands[0]) == XFmode
3903        || GET_MODE (operands[0]) == SFmode
3904        || GET_MODE (operands[0]) == DFmode)
3905    && (operands[2] = find_constant_src (insn))"
3906   [(set (match_dup 0) (match_dup 2))]
3907 {
3908   rtx c = operands[2];
3909   rtx r = operands[0];
3910
3911   if (GET_CODE (r) == SUBREG)
3912     r = SUBREG_REG (r);
3913
3914   if (SSE_REG_P (r))
3915     {
3916       if (!standard_sse_constant_p (c))
3917         FAIL;
3918     }
3919   else if (FP_REG_P (r))
3920     {
3921       if (!standard_80387_constant_p (c))
3922         FAIL;
3923     }
3924   else if (MMX_REG_P (r))
3925     FAIL;
3926 })
3927
3928 (define_insn "swapxf"
3929   [(set (match_operand:XF 0 "register_operand" "+f")
3930         (match_operand:XF 1 "register_operand" "+f"))
3931    (set (match_dup 1)
3932         (match_dup 0))]
3933   "TARGET_80387"
3934 {
3935   if (STACK_TOP_P (operands[0]))
3936     return "fxch\t%1";
3937   else
3938     return "fxch\t%0";
3939 }
3940   [(set_attr "type" "fxch")
3941    (set_attr "mode" "XF")])
3942
3943 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3944 (define_split
3945   [(set (match_operand:X87MODEF 0 "register_operand" "")
3946         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3947   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3948    && (standard_80387_constant_p (operands[1]) == 8
3949        || standard_80387_constant_p (operands[1]) == 9)"
3950   [(set (match_dup 0)(match_dup 1))
3951    (set (match_dup 0)
3952         (neg:X87MODEF (match_dup 0)))]
3953 {
3954   REAL_VALUE_TYPE r;
3955
3956   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3957   if (real_isnegzero (&r))
3958     operands[1] = CONST0_RTX (<MODE>mode);
3959   else
3960     operands[1] = CONST1_RTX (<MODE>mode);
3961 })
3962
3963 (define_split
3964   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3965         (match_operand:TF 1 "general_operand" ""))]
3966   "reload_completed
3967    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3968   [(const_int 0)]
3969   "ix86_split_long_move (operands); DONE;")
3970 \f
3971 ;; Zero extension instructions
3972
3973 (define_expand "zero_extendhisi2"
3974   [(set (match_operand:SI 0 "register_operand" "")
3975      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3976   ""
3977 {
3978   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3979     {
3980       operands[1] = force_reg (HImode, operands[1]);
3981       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3982       DONE;
3983     }
3984 })
3985
3986 (define_insn "zero_extendhisi2_and"
3987   [(set (match_operand:SI 0 "register_operand" "=r")
3988      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3989    (clobber (reg:CC FLAGS_REG))]
3990   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3991   "#"
3992   [(set_attr "type" "alu1")
3993    (set_attr "mode" "SI")])
3994
3995 (define_split
3996   [(set (match_operand:SI 0 "register_operand" "")
3997         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3998    (clobber (reg:CC FLAGS_REG))]
3999   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
4000    && optimize_function_for_speed_p (cfun)"
4001   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
4002               (clobber (reg:CC FLAGS_REG))])]
4003   "")
4004
4005 (define_insn "*zero_extendhisi2_movzwl"
4006   [(set (match_operand:SI 0 "register_operand" "=r")
4007      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4008   "!TARGET_ZERO_EXTEND_WITH_AND
4009    || optimize_function_for_size_p (cfun)"
4010   "movz{wl|x}\t{%1, %0|%0, %1}"
4011   [(set_attr "type" "imovx")
4012    (set_attr "mode" "SI")])
4013
4014 (define_expand "zero_extendqihi2"
4015   [(parallel
4016     [(set (match_operand:HI 0 "register_operand" "")
4017        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4018      (clobber (reg:CC FLAGS_REG))])]
4019   ""
4020   "")
4021
4022 (define_insn "*zero_extendqihi2_and"
4023   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4025    (clobber (reg:CC FLAGS_REG))]
4026   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4027   "#"
4028   [(set_attr "type" "alu1")
4029    (set_attr "mode" "HI")])
4030
4031 (define_insn "*zero_extendqihi2_movzbw_and"
4032   [(set (match_operand:HI 0 "register_operand" "=r,r")
4033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4034    (clobber (reg:CC FLAGS_REG))]
4035   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4036   "#"
4037   [(set_attr "type" "imovx,alu1")
4038    (set_attr "mode" "HI")])
4039
4040 ; zero extend to SImode here to avoid partial register stalls
4041 (define_insn "*zero_extendqihi2_movzbl"
4042   [(set (match_operand:HI 0 "register_operand" "=r")
4043      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4045    && reload_completed"
4046   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4047   [(set_attr "type" "imovx")
4048    (set_attr "mode" "SI")])
4049
4050 ;; For the movzbw case strip only the clobber
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    && (!TARGET_ZERO_EXTEND_WITH_AND
4057        || optimize_function_for_size_p (cfun))
4058    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4059   [(set (match_operand:HI 0 "register_operand" "")
4060         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4061
4062 ;; When source and destination does not overlap, clear destination
4063 ;; first and then do the movb
4064 (define_split
4065   [(set (match_operand:HI 0 "register_operand" "")
4066         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4067    (clobber (reg:CC FLAGS_REG))]
4068   "reload_completed
4069    && ANY_QI_REG_P (operands[0])
4070    && (TARGET_ZERO_EXTEND_WITH_AND
4071        && optimize_function_for_speed_p (cfun))
4072    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4073   [(set (match_dup 0) (const_int 0))
4074    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4075   "operands[2] = gen_lowpart (QImode, operands[0]);")
4076
4077 ;; Rest is handled by single and.
4078 (define_split
4079   [(set (match_operand:HI 0 "register_operand" "")
4080         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4081    (clobber (reg:CC FLAGS_REG))]
4082   "reload_completed
4083    && true_regnum (operands[0]) == true_regnum (operands[1])"
4084   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4085               (clobber (reg:CC FLAGS_REG))])]
4086   "")
4087
4088 (define_expand "zero_extendqisi2"
4089   [(parallel
4090     [(set (match_operand:SI 0 "register_operand" "")
4091        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4092      (clobber (reg:CC FLAGS_REG))])]
4093   ""
4094   "")
4095
4096 (define_insn "*zero_extendqisi2_and"
4097   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4099    (clobber (reg:CC FLAGS_REG))]
4100   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4101   "#"
4102   [(set_attr "type" "alu1")
4103    (set_attr "mode" "SI")])
4104
4105 (define_insn "*zero_extendqisi2_movzbw_and"
4106   [(set (match_operand:SI 0 "register_operand" "=r,r")
4107      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4108    (clobber (reg:CC FLAGS_REG))]
4109   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4110   "#"
4111   [(set_attr "type" "imovx,alu1")
4112    (set_attr "mode" "SI")])
4113
4114 (define_insn "*zero_extendqisi2_movzbw"
4115   [(set (match_operand:SI 0 "register_operand" "=r")
4116      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4117   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4118    && reload_completed"
4119   "movz{bl|x}\t{%1, %0|%0, %1}"
4120   [(set_attr "type" "imovx")
4121    (set_attr "mode" "SI")])
4122
4123 ;; For the movzbl case strip only the clobber
4124 (define_split
4125   [(set (match_operand:SI 0 "register_operand" "")
4126         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4127    (clobber (reg:CC FLAGS_REG))]
4128   "reload_completed
4129    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4130    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4131   [(set (match_dup 0)
4132         (zero_extend:SI (match_dup 1)))])
4133
4134 ;; When source and destination does not overlap, clear destination
4135 ;; first and then do the movb
4136 (define_split
4137   [(set (match_operand:SI 0 "register_operand" "")
4138         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4139    (clobber (reg:CC FLAGS_REG))]
4140   "reload_completed
4141    && ANY_QI_REG_P (operands[0])
4142    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4143    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4144    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4145   [(set (match_dup 0) (const_int 0))
4146    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4147   "operands[2] = gen_lowpart (QImode, operands[0]);")
4148
4149 ;; Rest is handled by single and.
4150 (define_split
4151   [(set (match_operand:SI 0 "register_operand" "")
4152         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4153    (clobber (reg:CC FLAGS_REG))]
4154   "reload_completed
4155    && true_regnum (operands[0]) == true_regnum (operands[1])"
4156   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4157               (clobber (reg:CC FLAGS_REG))])]
4158   "")
4159
4160 ;; %%% Kill me once multi-word ops are sane.
4161 (define_expand "zero_extendsidi2"
4162   [(set (match_operand:DI 0 "register_operand" "")
4163      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4164   ""
4165 {
4166   if (!TARGET_64BIT)
4167     {
4168       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4169       DONE;
4170     }
4171 })
4172
4173 (define_insn "zero_extendsidi2_32"
4174   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4175         (zero_extend:DI
4176          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4177    (clobber (reg:CC FLAGS_REG))]
4178   "!TARGET_64BIT"
4179   "@
4180    #
4181    #
4182    #
4183    movd\t{%1, %0|%0, %1}
4184    movd\t{%1, %0|%0, %1}
4185    %vmovd\t{%1, %0|%0, %1}
4186    %vmovd\t{%1, %0|%0, %1}"
4187   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4188    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4189    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4190
4191 (define_insn "zero_extendsidi2_rex64"
4192   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4193      (zero_extend:DI
4194        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4195   "TARGET_64BIT"
4196   "@
4197    mov\t{%k1, %k0|%k0, %k1}
4198    #
4199    movd\t{%1, %0|%0, %1}
4200    movd\t{%1, %0|%0, %1}
4201    %vmovd\t{%1, %0|%0, %1}
4202    %vmovd\t{%1, %0|%0, %1}"
4203   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4204    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4205    (set_attr "prefix_0f" "0,*,*,*,*,*")
4206    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4207
4208 (define_split
4209   [(set (match_operand:DI 0 "memory_operand" "")
4210      (zero_extend:DI (match_dup 0)))]
4211   "TARGET_64BIT"
4212   [(set (match_dup 4) (const_int 0))]
4213   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4214
4215 (define_split
4216   [(set (match_operand:DI 0 "register_operand" "")
4217         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4218    (clobber (reg:CC FLAGS_REG))]
4219   "!TARGET_64BIT && reload_completed
4220    && true_regnum (operands[0]) == true_regnum (operands[1])"
4221   [(set (match_dup 4) (const_int 0))]
4222   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4223
4224 (define_split
4225   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4227    (clobber (reg:CC FLAGS_REG))]
4228   "!TARGET_64BIT && reload_completed
4229    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4230   [(set (match_dup 3) (match_dup 1))
4231    (set (match_dup 4) (const_int 0))]
4232   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4233
4234 (define_insn "zero_extendhidi2"
4235   [(set (match_operand:DI 0 "register_operand" "=r")
4236      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4237   "TARGET_64BIT"
4238   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4239   [(set_attr "type" "imovx")
4240    (set_attr "mode" "SI")])
4241
4242 (define_insn "zero_extendqidi2"
4243   [(set (match_operand:DI 0 "register_operand" "=r")
4244      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4245   "TARGET_64BIT"
4246   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4247   [(set_attr "type" "imovx")
4248    (set_attr "mode" "SI")])
4249 \f
4250 ;; Sign extension instructions
4251
4252 (define_expand "extendsidi2"
4253   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4254                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4255               (clobber (reg:CC FLAGS_REG))
4256               (clobber (match_scratch:SI 2 ""))])]
4257   ""
4258 {
4259   if (TARGET_64BIT)
4260     {
4261       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4262       DONE;
4263     }
4264 })
4265
4266 (define_insn "*extendsidi2_1"
4267   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4268         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4269    (clobber (reg:CC FLAGS_REG))
4270    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4271   "!TARGET_64BIT"
4272   "#")
4273
4274 (define_insn "extendsidi2_rex64"
4275   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4276         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4277   "TARGET_64BIT"
4278   "@
4279    {cltq|cdqe}
4280    movs{lq|x}\t{%1, %0|%0, %1}"
4281   [(set_attr "type" "imovx")
4282    (set_attr "mode" "DI")
4283    (set_attr "prefix_0f" "0")
4284    (set_attr "modrm" "0,1")])
4285
4286 (define_insn "extendhidi2"
4287   [(set (match_operand:DI 0 "register_operand" "=r")
4288         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4289   "TARGET_64BIT"
4290   "movs{wq|x}\t{%1, %0|%0, %1}"
4291   [(set_attr "type" "imovx")
4292    (set_attr "mode" "DI")])
4293
4294 (define_insn "extendqidi2"
4295   [(set (match_operand:DI 0 "register_operand" "=r")
4296         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4297   "TARGET_64BIT"
4298   "movs{bq|x}\t{%1, %0|%0, %1}"
4299    [(set_attr "type" "imovx")
4300     (set_attr "mode" "DI")])
4301
4302 ;; Extend to memory case when source register does die.
4303 (define_split
4304   [(set (match_operand:DI 0 "memory_operand" "")
4305         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4306    (clobber (reg:CC FLAGS_REG))
4307    (clobber (match_operand:SI 2 "register_operand" ""))]
4308   "(reload_completed
4309     && dead_or_set_p (insn, operands[1])
4310     && !reg_mentioned_p (operands[1], operands[0]))"
4311   [(set (match_dup 3) (match_dup 1))
4312    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4313               (clobber (reg:CC FLAGS_REG))])
4314    (set (match_dup 4) (match_dup 1))]
4315   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4316
4317 ;; Extend to memory case when source register does not die.
4318 (define_split
4319   [(set (match_operand:DI 0 "memory_operand" "")
4320         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4321    (clobber (reg:CC FLAGS_REG))
4322    (clobber (match_operand:SI 2 "register_operand" ""))]
4323   "reload_completed"
4324   [(const_int 0)]
4325 {
4326   split_di (&operands[0], 1, &operands[3], &operands[4]);
4327
4328   emit_move_insn (operands[3], operands[1]);
4329
4330   /* Generate a cltd if possible and doing so it profitable.  */
4331   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4332       && true_regnum (operands[1]) == AX_REG
4333       && true_regnum (operands[2]) == DX_REG)
4334     {
4335       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4336     }
4337   else
4338     {
4339       emit_move_insn (operands[2], operands[1]);
4340       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4341     }
4342   emit_move_insn (operands[4], operands[2]);
4343   DONE;
4344 })
4345
4346 ;; Extend to register case.  Optimize case where source and destination
4347 ;; registers match and cases where we can use cltd.
4348 (define_split
4349   [(set (match_operand:DI 0 "register_operand" "")
4350         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4351    (clobber (reg:CC FLAGS_REG))
4352    (clobber (match_scratch:SI 2 ""))]
4353   "reload_completed"
4354   [(const_int 0)]
4355 {
4356   split_di (&operands[0], 1, &operands[3], &operands[4]);
4357
4358   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4359     emit_move_insn (operands[3], operands[1]);
4360
4361   /* Generate a cltd if possible and doing so it profitable.  */
4362   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4363       && true_regnum (operands[3]) == AX_REG)
4364     {
4365       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4366       DONE;
4367     }
4368
4369   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4370     emit_move_insn (operands[4], operands[1]);
4371
4372   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4373   DONE;
4374 })
4375
4376 (define_insn "extendhisi2"
4377   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4378         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4379   ""
4380 {
4381   switch (get_attr_prefix_0f (insn))
4382     {
4383     case 0:
4384       return "{cwtl|cwde}";
4385     default:
4386       return "movs{wl|x}\t{%1, %0|%0, %1}";
4387     }
4388 }
4389   [(set_attr "type" "imovx")
4390    (set_attr "mode" "SI")
4391    (set (attr "prefix_0f")
4392      ;; movsx is short decodable while cwtl is vector decoded.
4393      (if_then_else (and (eq_attr "cpu" "!k6")
4394                         (eq_attr "alternative" "0"))
4395         (const_string "0")
4396         (const_string "1")))
4397    (set (attr "modrm")
4398      (if_then_else (eq_attr "prefix_0f" "0")
4399         (const_string "0")
4400         (const_string "1")))])
4401
4402 (define_insn "*extendhisi2_zext"
4403   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4404         (zero_extend:DI
4405           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4406   "TARGET_64BIT"
4407 {
4408   switch (get_attr_prefix_0f (insn))
4409     {
4410     case 0:
4411       return "{cwtl|cwde}";
4412     default:
4413       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4414     }
4415 }
4416   [(set_attr "type" "imovx")
4417    (set_attr "mode" "SI")
4418    (set (attr "prefix_0f")
4419      ;; movsx is short decodable while cwtl is vector decoded.
4420      (if_then_else (and (eq_attr "cpu" "!k6")
4421                         (eq_attr "alternative" "0"))
4422         (const_string "0")
4423         (const_string "1")))
4424    (set (attr "modrm")
4425      (if_then_else (eq_attr "prefix_0f" "0")
4426         (const_string "0")
4427         (const_string "1")))])
4428
4429 (define_insn "extendqihi2"
4430   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4431         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4432   ""
4433 {
4434   switch (get_attr_prefix_0f (insn))
4435     {
4436     case 0:
4437       return "{cbtw|cbw}";
4438     default:
4439       return "movs{bw|x}\t{%1, %0|%0, %1}";
4440     }
4441 }
4442   [(set_attr "type" "imovx")
4443    (set_attr "mode" "HI")
4444    (set (attr "prefix_0f")
4445      ;; movsx is short decodable while cwtl is vector decoded.
4446      (if_then_else (and (eq_attr "cpu" "!k6")
4447                         (eq_attr "alternative" "0"))
4448         (const_string "0")
4449         (const_string "1")))
4450    (set (attr "modrm")
4451      (if_then_else (eq_attr "prefix_0f" "0")
4452         (const_string "0")
4453         (const_string "1")))])
4454
4455 (define_insn "extendqisi2"
4456   [(set (match_operand:SI 0 "register_operand" "=r")
4457         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4458   ""
4459   "movs{bl|x}\t{%1, %0|%0, %1}"
4460    [(set_attr "type" "imovx")
4461     (set_attr "mode" "SI")])
4462
4463 (define_insn "*extendqisi2_zext"
4464   [(set (match_operand:DI 0 "register_operand" "=r")
4465         (zero_extend:DI
4466           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4467   "TARGET_64BIT"
4468   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4469    [(set_attr "type" "imovx")
4470     (set_attr "mode" "SI")])
4471 \f
4472 ;; Conversions between float and double.
4473
4474 ;; These are all no-ops in the model used for the 80387.  So just
4475 ;; emit moves.
4476
4477 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4478 (define_insn "*dummy_extendsfdf2"
4479   [(set (match_operand:DF 0 "push_operand" "=<")
4480         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4481   "0"
4482   "#")
4483
4484 (define_split
4485   [(set (match_operand:DF 0 "push_operand" "")
4486         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4487   ""
4488   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4489    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4490
4491 (define_insn "*dummy_extendsfxf2"
4492   [(set (match_operand:XF 0 "push_operand" "=<")
4493         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4494   "0"
4495   "#")
4496
4497 (define_split
4498   [(set (match_operand:XF 0 "push_operand" "")
4499         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4500   ""
4501   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4502    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4503   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4504
4505 (define_split
4506   [(set (match_operand:XF 0 "push_operand" "")
4507         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4508   ""
4509   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4510    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4511   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4512
4513 (define_expand "extendsfdf2"
4514   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4515         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4516   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4517 {
4518   /* ??? Needed for compress_float_constant since all fp constants
4519      are LEGITIMATE_CONSTANT_P.  */
4520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4521     {
4522       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4523           && standard_80387_constant_p (operands[1]) > 0)
4524         {
4525           operands[1] = simplify_const_unary_operation
4526             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4527           emit_move_insn_1 (operands[0], operands[1]);
4528           DONE;
4529         }
4530       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4531     }
4532 })
4533
4534 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4535    cvtss2sd:
4536       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4537       cvtps2pd xmm2,xmm1
4538    We do the conversion post reload to avoid producing of 128bit spills
4539    that might lead to ICE on 32bit target.  The sequence unlikely combine
4540    anyway.  */
4541 (define_split
4542   [(set (match_operand:DF 0 "register_operand" "")
4543         (float_extend:DF
4544           (match_operand:SF 1 "nonimmediate_operand" "")))]
4545   "TARGET_USE_VECTOR_FP_CONVERTS
4546    && optimize_insn_for_speed_p ()
4547    && reload_completed && SSE_REG_P (operands[0])"
4548    [(set (match_dup 2)
4549          (float_extend:V2DF
4550            (vec_select:V2SF
4551              (match_dup 3)
4552              (parallel [(const_int 0) (const_int 1)]))))]
4553 {
4554   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4555   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4556   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4557      Try to avoid move when unpacking can be done in source.  */
4558   if (REG_P (operands[1]))
4559     {
4560       /* If it is unsafe to overwrite upper half of source, we need
4561          to move to destination and unpack there.  */
4562       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4563            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4564           && true_regnum (operands[0]) != true_regnum (operands[1]))
4565         {
4566           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4567           emit_move_insn (tmp, operands[1]);
4568         }
4569       else
4570         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4571       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4572     }
4573   else
4574     emit_insn (gen_vec_setv4sf_0 (operands[3],
4575                                   CONST0_RTX (V4SFmode), operands[1]));
4576 })
4577
4578 (define_insn "*extendsfdf2_mixed"
4579   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4580         (float_extend:DF
4581           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4582   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4583 {
4584   switch (which_alternative)
4585     {
4586     case 0:
4587     case 1:
4588       return output_387_reg_move (insn, operands);
4589
4590     case 2:
4591       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4592
4593     default:
4594       gcc_unreachable ();
4595     }
4596 }
4597   [(set_attr "type" "fmov,fmov,ssecvt")
4598    (set_attr "prefix" "orig,orig,maybe_vex")
4599    (set_attr "mode" "SF,XF,DF")])
4600
4601 (define_insn "*extendsfdf2_sse"
4602   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4603         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4604   "TARGET_SSE2 && TARGET_SSE_MATH"
4605   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4606   [(set_attr "type" "ssecvt")
4607    (set_attr "prefix" "maybe_vex")
4608    (set_attr "mode" "DF")])
4609
4610 (define_insn "*extendsfdf2_i387"
4611   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4612         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4613   "TARGET_80387"
4614   "* return output_387_reg_move (insn, operands);"
4615   [(set_attr "type" "fmov")
4616    (set_attr "mode" "SF,XF")])
4617
4618 (define_expand "extend<mode>xf2"
4619   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4620         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4621   "TARGET_80387"
4622 {
4623   /* ??? Needed for compress_float_constant since all fp constants
4624      are LEGITIMATE_CONSTANT_P.  */
4625   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4626     {
4627       if (standard_80387_constant_p (operands[1]) > 0)
4628         {
4629           operands[1] = simplify_const_unary_operation
4630             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4631           emit_move_insn_1 (operands[0], operands[1]);
4632           DONE;
4633         }
4634       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4635     }
4636 })
4637
4638 (define_insn "*extend<mode>xf2_i387"
4639   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4640         (float_extend:XF
4641           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4642   "TARGET_80387"
4643   "* return output_387_reg_move (insn, operands);"
4644   [(set_attr "type" "fmov")
4645    (set_attr "mode" "<MODE>,XF")])
4646
4647 ;; %%% This seems bad bad news.
4648 ;; This cannot output into an f-reg because there is no way to be sure
4649 ;; of truncating in that case.  Otherwise this is just like a simple move
4650 ;; insn.  So we pretend we can output to a reg in order to get better
4651 ;; register preferencing, but we really use a stack slot.
4652
4653 ;; Conversion from DFmode to SFmode.
4654
4655 (define_expand "truncdfsf2"
4656   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4657         (float_truncate:SF
4658           (match_operand:DF 1 "nonimmediate_operand" "")))]
4659   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4660 {
4661   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4662     ;
4663   else if (flag_unsafe_math_optimizations)
4664     ;
4665   else
4666     {
4667       enum ix86_stack_slot slot = (virtuals_instantiated
4668                                    ? SLOT_TEMP
4669                                    : SLOT_VIRTUAL);
4670       rtx temp = assign_386_stack_local (SFmode, slot);
4671       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4672       DONE;
4673     }
4674 })
4675
4676 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4677    cvtsd2ss:
4678       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4679       cvtpd2ps xmm2,xmm1
4680    We do the conversion post reload to avoid producing of 128bit spills
4681    that might lead to ICE on 32bit target.  The sequence unlikely combine
4682    anyway.  */
4683 (define_split
4684   [(set (match_operand:SF 0 "register_operand" "")
4685         (float_truncate:SF
4686           (match_operand:DF 1 "nonimmediate_operand" "")))]
4687   "TARGET_USE_VECTOR_FP_CONVERTS
4688    && optimize_insn_for_speed_p ()
4689    && reload_completed && SSE_REG_P (operands[0])"
4690    [(set (match_dup 2)
4691          (vec_concat:V4SF
4692            (float_truncate:V2SF
4693              (match_dup 4))
4694            (match_dup 3)))]
4695 {
4696   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4697   operands[3] = CONST0_RTX (V2SFmode);
4698   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4699   /* Use movsd for loading from memory, unpcklpd for registers.
4700      Try to avoid move when unpacking can be done in source, or SSE3
4701      movddup is available.  */
4702   if (REG_P (operands[1]))
4703     {
4704       if (!TARGET_SSE3
4705           && true_regnum (operands[0]) != true_regnum (operands[1])
4706           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4707               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4708         {
4709           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4710           emit_move_insn (tmp, operands[1]);
4711           operands[1] = tmp;
4712         }
4713       else if (!TARGET_SSE3)
4714         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4715       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4716     }
4717   else
4718     emit_insn (gen_sse2_loadlpd (operands[4],
4719                                  CONST0_RTX (V2DFmode), operands[1]));
4720 })
4721
4722 (define_expand "truncdfsf2_with_temp"
4723   [(parallel [(set (match_operand:SF 0 "" "")
4724                    (float_truncate:SF (match_operand:DF 1 "" "")))
4725               (clobber (match_operand:SF 2 "" ""))])]
4726   "")
4727
4728 (define_insn "*truncdfsf_fast_mixed"
4729   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4730         (float_truncate:SF
4731           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4732   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4733 {
4734   switch (which_alternative)
4735     {
4736     case 0:
4737       return output_387_reg_move (insn, operands);
4738     case 1:
4739       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4740     default:
4741       gcc_unreachable ();
4742     }
4743 }
4744   [(set_attr "type" "fmov,ssecvt")
4745    (set_attr "prefix" "orig,maybe_vex")
4746    (set_attr "mode" "SF")])
4747
4748 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4749 ;; because nothing we do here is unsafe.
4750 (define_insn "*truncdfsf_fast_sse"
4751   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4752         (float_truncate:SF
4753           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4754   "TARGET_SSE2 && TARGET_SSE_MATH"
4755   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4756   [(set_attr "type" "ssecvt")
4757    (set_attr "prefix" "maybe_vex")
4758    (set_attr "mode" "SF")])
4759
4760 (define_insn "*truncdfsf_fast_i387"
4761   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4762         (float_truncate:SF
4763           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4764   "TARGET_80387 && flag_unsafe_math_optimizations"
4765   "* return output_387_reg_move (insn, operands);"
4766   [(set_attr "type" "fmov")
4767    (set_attr "mode" "SF")])
4768
4769 (define_insn "*truncdfsf_mixed"
4770   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4771         (float_truncate:SF
4772           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4773    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4774   "TARGET_MIX_SSE_I387"
4775 {
4776   switch (which_alternative)
4777     {
4778     case 0:
4779       return output_387_reg_move (insn, operands);
4780     case 1:
4781       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4782
4783     default:
4784       return "#";
4785     }
4786 }
4787   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4788    (set_attr "unit" "*,*,i387,i387,i387")
4789    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4790    (set_attr "mode" "SF")])
4791
4792 (define_insn "*truncdfsf_i387"
4793   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4794         (float_truncate:SF
4795           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4796    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4797   "TARGET_80387"
4798 {
4799   switch (which_alternative)
4800     {
4801     case 0:
4802       return output_387_reg_move (insn, operands);
4803
4804     default:
4805       return "#";
4806     }
4807 }
4808   [(set_attr "type" "fmov,multi,multi,multi")
4809    (set_attr "unit" "*,i387,i387,i387")
4810    (set_attr "mode" "SF")])
4811
4812 (define_insn "*truncdfsf2_i387_1"
4813   [(set (match_operand:SF 0 "memory_operand" "=m")
4814         (float_truncate:SF
4815           (match_operand:DF 1 "register_operand" "f")))]
4816   "TARGET_80387
4817    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4818    && !TARGET_MIX_SSE_I387"
4819   "* return output_387_reg_move (insn, operands);"
4820   [(set_attr "type" "fmov")
4821    (set_attr "mode" "SF")])
4822
4823 (define_split
4824   [(set (match_operand:SF 0 "register_operand" "")
4825         (float_truncate:SF
4826          (match_operand:DF 1 "fp_register_operand" "")))
4827    (clobber (match_operand 2 "" ""))]
4828   "reload_completed"
4829   [(set (match_dup 2) (match_dup 1))
4830    (set (match_dup 0) (match_dup 2))]
4831 {
4832   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4833 })
4834
4835 ;; Conversion from XFmode to {SF,DF}mode
4836
4837 (define_expand "truncxf<mode>2"
4838   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4839                    (float_truncate:MODEF
4840                      (match_operand:XF 1 "register_operand" "")))
4841               (clobber (match_dup 2))])]
4842   "TARGET_80387"
4843 {
4844   if (flag_unsafe_math_optimizations)
4845     {
4846       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4847       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4848       if (reg != operands[0])
4849         emit_move_insn (operands[0], reg);
4850       DONE;
4851     }
4852   else
4853     {
4854      enum ix86_stack_slot slot = (virtuals_instantiated
4855                                   ? SLOT_TEMP
4856                                   : SLOT_VIRTUAL);
4857       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4858     }
4859 })
4860
4861 (define_insn "*truncxfsf2_mixed"
4862   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4863         (float_truncate:SF
4864           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4865    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4866   "TARGET_80387"
4867 {
4868   gcc_assert (!which_alternative);
4869   return output_387_reg_move (insn, operands);
4870 }
4871   [(set_attr "type" "fmov,multi,multi,multi")
4872    (set_attr "unit" "*,i387,i387,i387")
4873    (set_attr "mode" "SF")])
4874
4875 (define_insn "*truncxfdf2_mixed"
4876   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4877         (float_truncate:DF
4878           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4879    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4880   "TARGET_80387"
4881 {
4882   gcc_assert (!which_alternative);
4883   return output_387_reg_move (insn, operands);
4884 }
4885   [(set_attr "type" "fmov,multi,multi,multi")
4886    (set_attr "unit" "*,i387,i387,i387")
4887    (set_attr "mode" "DF")])
4888
4889 (define_insn "truncxf<mode>2_i387_noop"
4890   [(set (match_operand:MODEF 0 "register_operand" "=f")
4891         (float_truncate:MODEF
4892           (match_operand:XF 1 "register_operand" "f")))]
4893   "TARGET_80387 && flag_unsafe_math_optimizations"
4894   "* return output_387_reg_move (insn, operands);"
4895   [(set_attr "type" "fmov")
4896    (set_attr "mode" "<MODE>")])
4897
4898 (define_insn "*truncxf<mode>2_i387"
4899   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4900         (float_truncate:MODEF
4901           (match_operand:XF 1 "register_operand" "f")))]
4902   "TARGET_80387"
4903   "* return output_387_reg_move (insn, operands);"
4904   [(set_attr "type" "fmov")
4905    (set_attr "mode" "<MODE>")])
4906
4907 (define_split
4908   [(set (match_operand:MODEF 0 "register_operand" "")
4909         (float_truncate:MODEF
4910           (match_operand:XF 1 "register_operand" "")))
4911    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4912   "TARGET_80387 && reload_completed"
4913   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4914    (set (match_dup 0) (match_dup 2))]
4915   "")
4916
4917 (define_split
4918   [(set (match_operand:MODEF 0 "memory_operand" "")
4919         (float_truncate:MODEF
4920           (match_operand:XF 1 "register_operand" "")))
4921    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4922   "TARGET_80387"
4923   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4924   "")
4925 \f
4926 ;; Signed conversion to DImode.
4927
4928 (define_expand "fix_truncxfdi2"
4929   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4930                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4931               (clobber (reg:CC FLAGS_REG))])]
4932   "TARGET_80387"
4933 {
4934   if (TARGET_FISTTP)
4935    {
4936      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4937      DONE;
4938    }
4939 })
4940
4941 (define_expand "fix_trunc<mode>di2"
4942   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4943                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4944               (clobber (reg:CC FLAGS_REG))])]
4945   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4946 {
4947   if (TARGET_FISTTP
4948       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4949    {
4950      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4951      DONE;
4952    }
4953   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4954    {
4955      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4956      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4957      if (out != operands[0])
4958         emit_move_insn (operands[0], out);
4959      DONE;
4960    }
4961 })
4962
4963 ;; Signed conversion to SImode.
4964
4965 (define_expand "fix_truncxfsi2"
4966   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4967                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4968               (clobber (reg:CC FLAGS_REG))])]
4969   "TARGET_80387"
4970 {
4971   if (TARGET_FISTTP)
4972    {
4973      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4974      DONE;
4975    }
4976 })
4977
4978 (define_expand "fix_trunc<mode>si2"
4979   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4980                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4981               (clobber (reg:CC FLAGS_REG))])]
4982   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4983 {
4984   if (TARGET_FISTTP
4985       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4986    {
4987      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4988      DONE;
4989    }
4990   if (SSE_FLOAT_MODE_P (<MODE>mode))
4991    {
4992      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4993      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4994      if (out != operands[0])
4995         emit_move_insn (operands[0], out);
4996      DONE;
4997    }
4998 })
4999
5000 ;; Signed conversion to HImode.
5001
5002 (define_expand "fix_trunc<mode>hi2"
5003   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5004                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
5005               (clobber (reg:CC FLAGS_REG))])]
5006   "TARGET_80387
5007    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5008 {
5009   if (TARGET_FISTTP)
5010    {
5011      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5012      DONE;
5013    }
5014 })
5015
5016 ;; Unsigned conversion to SImode.
5017
5018 (define_expand "fixuns_trunc<mode>si2"
5019   [(parallel
5020     [(set (match_operand:SI 0 "register_operand" "")
5021           (unsigned_fix:SI
5022             (match_operand:MODEF 1 "nonimmediate_operand" "")))
5023      (use (match_dup 2))
5024      (clobber (match_scratch:<ssevecmode> 3 ""))
5025      (clobber (match_scratch:<ssevecmode> 4 ""))])]
5026   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5027 {
5028   enum machine_mode mode = <MODE>mode;
5029   enum machine_mode vecmode = <ssevecmode>mode;
5030   REAL_VALUE_TYPE TWO31r;
5031   rtx two31;
5032
5033   if (optimize_insn_for_size_p ())
5034     FAIL;
5035
5036   real_ldexp (&TWO31r, &dconst1, 31);
5037   two31 = const_double_from_real_value (TWO31r, mode);
5038   two31 = ix86_build_const_vector (mode, true, two31);
5039   operands[2] = force_reg (vecmode, two31);
5040 })
5041
5042 (define_insn_and_split "*fixuns_trunc<mode>_1"
5043   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5044         (unsigned_fix:SI
5045           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5046    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5047    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5048    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5049   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5050    && optimize_function_for_speed_p (cfun)"
5051   "#"
5052   "&& reload_completed"
5053   [(const_int 0)]
5054 {
5055   ix86_split_convert_uns_si_sse (operands);
5056   DONE;
5057 })
5058
5059 ;; Unsigned conversion to HImode.
5060 ;; Without these patterns, we'll try the unsigned SI conversion which
5061 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5062
5063 (define_expand "fixuns_trunc<mode>hi2"
5064   [(set (match_dup 2)
5065         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5066    (set (match_operand:HI 0 "nonimmediate_operand" "")
5067         (subreg:HI (match_dup 2) 0))]
5068   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5069   "operands[2] = gen_reg_rtx (SImode);")
5070
5071 ;; When SSE is available, it is always faster to use it!
5072 (define_insn "fix_trunc<mode>di_sse"
5073   [(set (match_operand:DI 0 "register_operand" "=r,r")
5074         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5075   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5076    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5077   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5078   [(set_attr "type" "sseicvt")
5079    (set_attr "prefix" "maybe_vex")
5080    (set_attr "prefix_rex" "1")
5081    (set_attr "mode" "<MODE>")
5082    (set_attr "athlon_decode" "double,vector")
5083    (set_attr "amdfam10_decode" "double,double")])
5084
5085 (define_insn "fix_trunc<mode>si_sse"
5086   [(set (match_operand:SI 0 "register_operand" "=r,r")
5087         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5088   "SSE_FLOAT_MODE_P (<MODE>mode)
5089    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5090   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5091   [(set_attr "type" "sseicvt")
5092    (set_attr "prefix" "maybe_vex")
5093    (set_attr "mode" "<MODE>")
5094    (set_attr "athlon_decode" "double,vector")
5095    (set_attr "amdfam10_decode" "double,double")])
5096
5097 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5098 (define_peephole2
5099   [(set (match_operand:MODEF 0 "register_operand" "")
5100         (match_operand:MODEF 1 "memory_operand" ""))
5101    (set (match_operand:SSEMODEI24 2 "register_operand" "")
5102         (fix:SSEMODEI24 (match_dup 0)))]
5103   "TARGET_SHORTEN_X87_SSE
5104    && peep2_reg_dead_p (2, operands[0])"
5105   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5106   "")
5107
5108 ;; Avoid vector decoded forms of the instruction.
5109 (define_peephole2
5110   [(match_scratch:DF 2 "Y2")
5111    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5112         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5113   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5114   [(set (match_dup 2) (match_dup 1))
5115    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5116   "")
5117
5118 (define_peephole2
5119   [(match_scratch:SF 2 "x")
5120    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5121         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5122   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5123   [(set (match_dup 2) (match_dup 1))
5124    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5125   "")
5126
5127 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5128   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5129         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5130   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5131    && TARGET_FISTTP
5132    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5133          && (TARGET_64BIT || <MODE>mode != DImode))
5134         && TARGET_SSE_MATH)
5135    && can_create_pseudo_p ()"
5136   "#"
5137   "&& 1"
5138   [(const_int 0)]
5139 {
5140   if (memory_operand (operands[0], VOIDmode))
5141     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5142   else
5143     {
5144       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5145       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5146                                                             operands[1],
5147                                                             operands[2]));
5148     }
5149   DONE;
5150 }
5151   [(set_attr "type" "fisttp")
5152    (set_attr "mode" "<MODE>")])
5153
5154 (define_insn "fix_trunc<mode>_i387_fisttp"
5155   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5156         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5157    (clobber (match_scratch:XF 2 "=&1f"))]
5158   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5159    && TARGET_FISTTP
5160    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5161          && (TARGET_64BIT || <MODE>mode != DImode))
5162         && TARGET_SSE_MATH)"
5163   "* return output_fix_trunc (insn, operands, 1);"
5164   [(set_attr "type" "fisttp")
5165    (set_attr "mode" "<MODE>")])
5166
5167 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5168   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5169         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5170    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5171    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5172   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5173    && TARGET_FISTTP
5174    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5175         && (TARGET_64BIT || <MODE>mode != DImode))
5176         && TARGET_SSE_MATH)"
5177   "#"
5178   [(set_attr "type" "fisttp")
5179    (set_attr "mode" "<MODE>")])
5180
5181 (define_split
5182   [(set (match_operand:X87MODEI 0 "register_operand" "")
5183         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5184    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5185    (clobber (match_scratch 3 ""))]
5186   "reload_completed"
5187   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5188               (clobber (match_dup 3))])
5189    (set (match_dup 0) (match_dup 2))]
5190   "")
5191
5192 (define_split
5193   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5194         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5195    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5196    (clobber (match_scratch 3 ""))]
5197   "reload_completed"
5198   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5199               (clobber (match_dup 3))])]
5200   "")
5201
5202 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5203 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5204 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5205 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5206 ;; function in i386.c.
5207 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5208   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5209         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5210    (clobber (reg:CC FLAGS_REG))]
5211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5212    && !TARGET_FISTTP
5213    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5214          && (TARGET_64BIT || <MODE>mode != DImode))
5215    && can_create_pseudo_p ()"
5216   "#"
5217   "&& 1"
5218   [(const_int 0)]
5219 {
5220   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5221
5222   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5223   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5224   if (memory_operand (operands[0], VOIDmode))
5225     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5226                                          operands[2], operands[3]));
5227   else
5228     {
5229       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5230       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5231                                                      operands[2], operands[3],
5232                                                      operands[4]));
5233     }
5234   DONE;
5235 }
5236   [(set_attr "type" "fistp")
5237    (set_attr "i387_cw" "trunc")
5238    (set_attr "mode" "<MODE>")])
5239
5240 (define_insn "fix_truncdi_i387"
5241   [(set (match_operand:DI 0 "memory_operand" "=m")
5242         (fix:DI (match_operand 1 "register_operand" "f")))
5243    (use (match_operand:HI 2 "memory_operand" "m"))
5244    (use (match_operand:HI 3 "memory_operand" "m"))
5245    (clobber (match_scratch:XF 4 "=&1f"))]
5246   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5247    && !TARGET_FISTTP
5248    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5249   "* return output_fix_trunc (insn, operands, 0);"
5250   [(set_attr "type" "fistp")
5251    (set_attr "i387_cw" "trunc")
5252    (set_attr "mode" "DI")])
5253
5254 (define_insn "fix_truncdi_i387_with_temp"
5255   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5256         (fix:DI (match_operand 1 "register_operand" "f,f")))
5257    (use (match_operand:HI 2 "memory_operand" "m,m"))
5258    (use (match_operand:HI 3 "memory_operand" "m,m"))
5259    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5260    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5261   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5262    && !TARGET_FISTTP
5263    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5264   "#"
5265   [(set_attr "type" "fistp")
5266    (set_attr "i387_cw" "trunc")
5267    (set_attr "mode" "DI")])
5268
5269 (define_split
5270   [(set (match_operand:DI 0 "register_operand" "")
5271         (fix:DI (match_operand 1 "register_operand" "")))
5272    (use (match_operand:HI 2 "memory_operand" ""))
5273    (use (match_operand:HI 3 "memory_operand" ""))
5274    (clobber (match_operand:DI 4 "memory_operand" ""))
5275    (clobber (match_scratch 5 ""))]
5276   "reload_completed"
5277   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5278               (use (match_dup 2))
5279               (use (match_dup 3))
5280               (clobber (match_dup 5))])
5281    (set (match_dup 0) (match_dup 4))]
5282   "")
5283
5284 (define_split
5285   [(set (match_operand:DI 0 "memory_operand" "")
5286         (fix:DI (match_operand 1 "register_operand" "")))
5287    (use (match_operand:HI 2 "memory_operand" ""))
5288    (use (match_operand:HI 3 "memory_operand" ""))
5289    (clobber (match_operand:DI 4 "memory_operand" ""))
5290    (clobber (match_scratch 5 ""))]
5291   "reload_completed"
5292   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5293               (use (match_dup 2))
5294               (use (match_dup 3))
5295               (clobber (match_dup 5))])]
5296   "")
5297
5298 (define_insn "fix_trunc<mode>_i387"
5299   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5300         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5301    (use (match_operand:HI 2 "memory_operand" "m"))
5302    (use (match_operand:HI 3 "memory_operand" "m"))]
5303   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5304    && !TARGET_FISTTP
5305    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5306   "* return output_fix_trunc (insn, operands, 0);"
5307   [(set_attr "type" "fistp")
5308    (set_attr "i387_cw" "trunc")
5309    (set_attr "mode" "<MODE>")])
5310
5311 (define_insn "fix_trunc<mode>_i387_with_temp"
5312   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5313         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5314    (use (match_operand:HI 2 "memory_operand" "m,m"))
5315    (use (match_operand:HI 3 "memory_operand" "m,m"))
5316    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5317   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5318    && !TARGET_FISTTP
5319    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5320   "#"
5321   [(set_attr "type" "fistp")
5322    (set_attr "i387_cw" "trunc")
5323    (set_attr "mode" "<MODE>")])
5324
5325 (define_split
5326   [(set (match_operand:X87MODEI12 0 "register_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 4) (fix:X87MODEI12 (match_dup 1)))
5333               (use (match_dup 2))
5334               (use (match_dup 3))])
5335    (set (match_dup 0) (match_dup 4))]
5336   "")
5337
5338 (define_split
5339   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5340         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5341    (use (match_operand:HI 2 "memory_operand" ""))
5342    (use (match_operand:HI 3 "memory_operand" ""))
5343    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5344   "reload_completed"
5345   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5346               (use (match_dup 2))
5347               (use (match_dup 3))])]
5348   "")
5349
5350 (define_insn "x86_fnstcw_1"
5351   [(set (match_operand:HI 0 "memory_operand" "=m")
5352         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5353   "TARGET_80387"
5354   "fnstcw\t%0"
5355   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5356    (set_attr "mode" "HI")
5357    (set_attr "unit" "i387")])
5358
5359 (define_insn "x86_fldcw_1"
5360   [(set (reg:HI FPCR_REG)
5361         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5362   "TARGET_80387"
5363   "fldcw\t%0"
5364   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5365    (set_attr "mode" "HI")
5366    (set_attr "unit" "i387")
5367    (set_attr "athlon_decode" "vector")
5368    (set_attr "amdfam10_decode" "vector")])
5369 \f
5370 ;; Conversion between fixed point and floating point.
5371
5372 ;; Even though we only accept memory inputs, the backend _really_
5373 ;; wants to be able to do this between registers.
5374
5375 (define_expand "floathi<mode>2"
5376   [(set (match_operand:X87MODEF 0 "register_operand" "")
5377         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5378   "TARGET_80387
5379    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5380        || TARGET_MIX_SSE_I387)"
5381   "")
5382
5383 ;; Pre-reload splitter to add memory clobber to the pattern.
5384 (define_insn_and_split "*floathi<mode>2_1"
5385   [(set (match_operand:X87MODEF 0 "register_operand" "")
5386         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5387   "TARGET_80387
5388    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5389        || TARGET_MIX_SSE_I387)
5390    && can_create_pseudo_p ()"
5391   "#"
5392   "&& 1"
5393   [(parallel [(set (match_dup 0)
5394               (float:X87MODEF (match_dup 1)))
5395    (clobber (match_dup 2))])]
5396   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5397
5398 (define_insn "*floathi<mode>2_i387_with_temp"
5399   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5400         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5401   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5402   "TARGET_80387
5403    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5404        || TARGET_MIX_SSE_I387)"
5405   "#"
5406   [(set_attr "type" "fmov,multi")
5407    (set_attr "mode" "<MODE>")
5408    (set_attr "unit" "*,i387")
5409    (set_attr "fp_int_src" "true")])
5410
5411 (define_insn "*floathi<mode>2_i387"
5412   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5413         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5414   "TARGET_80387
5415    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5416        || TARGET_MIX_SSE_I387)"
5417   "fild%Z1\t%1"
5418   [(set_attr "type" "fmov")
5419    (set_attr "mode" "<MODE>")
5420    (set_attr "fp_int_src" "true")])
5421
5422 (define_split
5423   [(set (match_operand:X87MODEF 0 "register_operand" "")
5424         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5425    (clobber (match_operand:HI 2 "memory_operand" ""))]
5426   "TARGET_80387
5427    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5428        || TARGET_MIX_SSE_I387)
5429    && reload_completed"
5430   [(set (match_dup 2) (match_dup 1))
5431    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5432   "")
5433
5434 (define_split
5435   [(set (match_operand:X87MODEF 0 "register_operand" "")
5436         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5437    (clobber (match_operand:HI 2 "memory_operand" ""))]
5438    "TARGET_80387
5439     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5440         || TARGET_MIX_SSE_I387)
5441     && reload_completed"
5442   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5443   "")
5444
5445 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5446   [(set (match_operand:X87MODEF 0 "register_operand" "")
5447         (float:X87MODEF
5448           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5449   "TARGET_80387
5450    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5451        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5452   "
5453 {
5454   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5456       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5457     {
5458       rtx reg = gen_reg_rtx (XFmode);
5459       rtx insn;
5460
5461       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5462
5463       if (<X87MODEF:MODE>mode == SFmode)
5464         insn = gen_truncxfsf2 (operands[0], reg);
5465       else if (<X87MODEF:MODE>mode == DFmode)
5466         insn = gen_truncxfdf2 (operands[0], reg);
5467       else
5468         gcc_unreachable ();
5469
5470       emit_insn (insn);
5471       DONE;
5472     }
5473 }")
5474
5475 ;; Pre-reload splitter to add memory clobber to the pattern.
5476 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5477   [(set (match_operand:X87MODEF 0 "register_operand" "")
5478         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5479   "((TARGET_80387
5480      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5481      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5482            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5483          || TARGET_MIX_SSE_I387))
5484     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5485         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5486         && ((<SSEMODEI24:MODE>mode == SImode
5487              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5488              && optimize_function_for_speed_p (cfun)
5489              && flag_trapping_math)
5490             || !(TARGET_INTER_UNIT_CONVERSIONS
5491                  || optimize_function_for_size_p (cfun)))))
5492    && can_create_pseudo_p ()"
5493   "#"
5494   "&& 1"
5495   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5496               (clobber (match_dup 2))])]
5497 {
5498   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5499
5500   /* Avoid store forwarding (partial memory) stall penalty
5501      by passing DImode value through XMM registers.  */
5502   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5503       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5504       && optimize_function_for_speed_p (cfun))
5505     {
5506       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5507                                                             operands[1],
5508                                                             operands[2]));
5509       DONE;
5510     }
5511 })
5512
5513 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5514   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5515         (float:MODEF
5516           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5517    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5518   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5519    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5520   "#"
5521   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5522    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5523    (set_attr "unit" "*,i387,*,*,*")
5524    (set_attr "athlon_decode" "*,*,double,direct,double")
5525    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5526    (set_attr "fp_int_src" "true")])
5527
5528 (define_insn "*floatsi<mode>2_vector_mixed"
5529   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5530         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5531   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5532    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5533   "@
5534    fild%Z1\t%1
5535    #"
5536   [(set_attr "type" "fmov,sseicvt")
5537    (set_attr "mode" "<MODE>,<ssevecmode>")
5538    (set_attr "unit" "i387,*")
5539    (set_attr "athlon_decode" "*,direct")
5540    (set_attr "amdfam10_decode" "*,double")
5541    (set_attr "fp_int_src" "true")])
5542
5543 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5544   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5545         (float:MODEF
5546           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5547   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5548   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5549    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5550   "#"
5551   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5552    (set_attr "mode" "<MODEF:MODE>")
5553    (set_attr "unit" "*,i387,*,*")
5554    (set_attr "athlon_decode" "*,*,double,direct")
5555    (set_attr "amdfam10_decode" "*,*,vector,double")
5556    (set_attr "fp_int_src" "true")])
5557
5558 (define_split
5559   [(set (match_operand:MODEF 0 "register_operand" "")
5560         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5561    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5562   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5563    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5564    && TARGET_INTER_UNIT_CONVERSIONS
5565    && reload_completed
5566    && (SSE_REG_P (operands[0])
5567        || (GET_CODE (operands[0]) == SUBREG
5568            && SSE_REG_P (operands[0])))"
5569   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5570   "")
5571
5572 (define_split
5573   [(set (match_operand:MODEF 0 "register_operand" "")
5574         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5575    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5576   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5577    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5578    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5579    && reload_completed
5580    && (SSE_REG_P (operands[0])
5581        || (GET_CODE (operands[0]) == SUBREG
5582            && SSE_REG_P (operands[0])))"
5583   [(set (match_dup 2) (match_dup 1))
5584    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5585   "")
5586
5587 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5588   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5589         (float:MODEF
5590           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5591   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5592    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5593    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5594   "@
5595    fild%Z1\t%1
5596    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5597    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5598   [(set_attr "type" "fmov,sseicvt,sseicvt")
5599    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5600    (set_attr "mode" "<MODEF:MODE>")
5601    (set (attr "prefix_rex")
5602      (if_then_else
5603        (and (eq_attr "prefix" "maybe_vex")
5604             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5605        (const_string "1")
5606        (const_string "*")))
5607    (set_attr "unit" "i387,*,*")
5608    (set_attr "athlon_decode" "*,double,direct")
5609    (set_attr "amdfam10_decode" "*,vector,double")
5610    (set_attr "fp_int_src" "true")])
5611
5612 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5613   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5614         (float:MODEF
5615           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5616   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5617    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5618    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5619   "@
5620    fild%Z1\t%1
5621    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5622   [(set_attr "type" "fmov,sseicvt")
5623    (set_attr "prefix" "orig,maybe_vex")
5624    (set_attr "mode" "<MODEF:MODE>")
5625    (set (attr "prefix_rex")
5626      (if_then_else
5627        (and (eq_attr "prefix" "maybe_vex")
5628             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5629        (const_string "1")
5630        (const_string "*")))
5631    (set_attr "athlon_decode" "*,direct")
5632    (set_attr "amdfam10_decode" "*,double")
5633    (set_attr "fp_int_src" "true")])
5634
5635 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5636   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5637         (float:MODEF
5638           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5639    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5640   "TARGET_SSE2 && TARGET_SSE_MATH
5641    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5642   "#"
5643   [(set_attr "type" "sseicvt")
5644    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5645    (set_attr "athlon_decode" "double,direct,double")
5646    (set_attr "amdfam10_decode" "vector,double,double")
5647    (set_attr "fp_int_src" "true")])
5648
5649 (define_insn "*floatsi<mode>2_vector_sse"
5650   [(set (match_operand:MODEF 0 "register_operand" "=x")
5651         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5652   "TARGET_SSE2 && TARGET_SSE_MATH
5653    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5654   "#"
5655   [(set_attr "type" "sseicvt")
5656    (set_attr "mode" "<MODE>")
5657    (set_attr "athlon_decode" "direct")
5658    (set_attr "amdfam10_decode" "double")
5659    (set_attr "fp_int_src" "true")])
5660
5661 (define_split
5662   [(set (match_operand:MODEF 0 "register_operand" "")
5663         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5664    (clobber (match_operand:SI 2 "memory_operand" ""))]
5665   "TARGET_SSE2 && TARGET_SSE_MATH
5666    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5667    && reload_completed
5668    && (SSE_REG_P (operands[0])
5669        || (GET_CODE (operands[0]) == SUBREG
5670            && SSE_REG_P (operands[0])))"
5671   [(const_int 0)]
5672 {
5673   rtx op1 = operands[1];
5674
5675   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5676                                      <MODE>mode, 0);
5677   if (GET_CODE (op1) == SUBREG)
5678     op1 = SUBREG_REG (op1);
5679
5680   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5681     {
5682       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5683       emit_insn (gen_sse2_loadld (operands[4],
5684                                   CONST0_RTX (V4SImode), operands[1]));
5685     }
5686   /* We can ignore possible trapping value in the
5687      high part of SSE register for non-trapping math. */
5688   else if (SSE_REG_P (op1) && !flag_trapping_math)
5689     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5690   else
5691     {
5692       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5693       emit_move_insn (operands[2], operands[1]);
5694       emit_insn (gen_sse2_loadld (operands[4],
5695                                   CONST0_RTX (V4SImode), operands[2]));
5696     }
5697   emit_insn
5698     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5699   DONE;
5700 })
5701
5702 (define_split
5703   [(set (match_operand:MODEF 0 "register_operand" "")
5704         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5705    (clobber (match_operand:SI 2 "memory_operand" ""))]
5706   "TARGET_SSE2 && TARGET_SSE_MATH
5707    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5708    && reload_completed
5709    && (SSE_REG_P (operands[0])
5710        || (GET_CODE (operands[0]) == SUBREG
5711            && SSE_REG_P (operands[0])))"
5712   [(const_int 0)]
5713 {
5714   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5715                                      <MODE>mode, 0);
5716   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5717
5718   emit_insn (gen_sse2_loadld (operands[4],
5719                               CONST0_RTX (V4SImode), operands[1]));
5720   emit_insn
5721     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5722   DONE;
5723 })
5724
5725 (define_split
5726   [(set (match_operand:MODEF 0 "register_operand" "")
5727         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5728   "TARGET_SSE2 && TARGET_SSE_MATH
5729    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5730    && reload_completed
5731    && (SSE_REG_P (operands[0])
5732        || (GET_CODE (operands[0]) == SUBREG
5733            && SSE_REG_P (operands[0])))"
5734   [(const_int 0)]
5735 {
5736   rtx op1 = operands[1];
5737
5738   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5739                                      <MODE>mode, 0);
5740   if (GET_CODE (op1) == SUBREG)
5741     op1 = SUBREG_REG (op1);
5742
5743   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5744     {
5745       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5746       emit_insn (gen_sse2_loadld (operands[4],
5747                                   CONST0_RTX (V4SImode), operands[1]));
5748     }
5749   /* We can ignore possible trapping value in the
5750      high part of SSE register for non-trapping math. */
5751   else if (SSE_REG_P (op1) && !flag_trapping_math)
5752     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5753   else
5754     gcc_unreachable ();
5755   emit_insn
5756     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5757   DONE;
5758 })
5759
5760 (define_split
5761   [(set (match_operand:MODEF 0 "register_operand" "")
5762         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5763   "TARGET_SSE2 && TARGET_SSE_MATH
5764    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5765    && reload_completed
5766    && (SSE_REG_P (operands[0])
5767        || (GET_CODE (operands[0]) == SUBREG
5768            && SSE_REG_P (operands[0])))"
5769   [(const_int 0)]
5770 {
5771   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5772                                      <MODE>mode, 0);
5773   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5774
5775   emit_insn (gen_sse2_loadld (operands[4],
5776                               CONST0_RTX (V4SImode), operands[1]));
5777   emit_insn
5778     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5779   DONE;
5780 })
5781
5782 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5783   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5784         (float:MODEF
5785           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5786   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5787   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5788    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5789   "#"
5790   [(set_attr "type" "sseicvt")
5791    (set_attr "mode" "<MODEF:MODE>")
5792    (set_attr "athlon_decode" "double,direct")
5793    (set_attr "amdfam10_decode" "vector,double")
5794    (set_attr "fp_int_src" "true")])
5795
5796 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5797   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5798         (float:MODEF
5799           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5800   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5801    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5802    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5803   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5804   [(set_attr "type" "sseicvt")
5805    (set_attr "prefix" "maybe_vex")
5806    (set_attr "mode" "<MODEF:MODE>")
5807    (set (attr "prefix_rex")
5808      (if_then_else
5809        (and (eq_attr "prefix" "maybe_vex")
5810             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5811        (const_string "1")
5812        (const_string "*")))
5813    (set_attr "athlon_decode" "double,direct")
5814    (set_attr "amdfam10_decode" "vector,double")
5815    (set_attr "fp_int_src" "true")])
5816
5817 (define_split
5818   [(set (match_operand:MODEF 0 "register_operand" "")
5819         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5820    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5821   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5822    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5823    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5824    && reload_completed
5825    && (SSE_REG_P (operands[0])
5826        || (GET_CODE (operands[0]) == SUBREG
5827            && SSE_REG_P (operands[0])))"
5828   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5829   "")
5830
5831 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5832   [(set (match_operand:MODEF 0 "register_operand" "=x")
5833         (float:MODEF
5834           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5835   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5836    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5837    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5838   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5839   [(set_attr "type" "sseicvt")
5840    (set_attr "prefix" "maybe_vex")
5841    (set_attr "mode" "<MODEF:MODE>")
5842    (set (attr "prefix_rex")
5843      (if_then_else
5844        (and (eq_attr "prefix" "maybe_vex")
5845             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5846        (const_string "1")
5847        (const_string "*")))
5848    (set_attr "athlon_decode" "direct")
5849    (set_attr "amdfam10_decode" "double")
5850    (set_attr "fp_int_src" "true")])
5851
5852 (define_split
5853   [(set (match_operand:MODEF 0 "register_operand" "")
5854         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5855    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5856   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5857    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5858    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5859    && reload_completed
5860    && (SSE_REG_P (operands[0])
5861        || (GET_CODE (operands[0]) == SUBREG
5862            && SSE_REG_P (operands[0])))"
5863   [(set (match_dup 2) (match_dup 1))
5864    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5865   "")
5866
5867 (define_split
5868   [(set (match_operand:MODEF 0 "register_operand" "")
5869         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5870    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5871   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5872    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5873    && reload_completed
5874    && (SSE_REG_P (operands[0])
5875        || (GET_CODE (operands[0]) == SUBREG
5876            && SSE_REG_P (operands[0])))"
5877   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5878   "")
5879
5880 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5881   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5882         (float:X87MODEF
5883           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5884   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5885   "TARGET_80387
5886    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5887   "@
5888    fild%Z1\t%1
5889    #"
5890   [(set_attr "type" "fmov,multi")
5891    (set_attr "mode" "<X87MODEF:MODE>")
5892    (set_attr "unit" "*,i387")
5893    (set_attr "fp_int_src" "true")])
5894
5895 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5896   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5897         (float:X87MODEF
5898           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5899   "TARGET_80387
5900    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5901   "fild%Z1\t%1"
5902   [(set_attr "type" "fmov")
5903    (set_attr "mode" "<X87MODEF:MODE>")
5904    (set_attr "fp_int_src" "true")])
5905
5906 (define_split
5907   [(set (match_operand:X87MODEF 0 "register_operand" "")
5908         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5909    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5910   "TARGET_80387
5911    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5912    && reload_completed
5913    && FP_REG_P (operands[0])"
5914   [(set (match_dup 2) (match_dup 1))
5915    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5916   "")
5917
5918 (define_split
5919   [(set (match_operand:X87MODEF 0 "register_operand" "")
5920         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5921    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5922   "TARGET_80387
5923    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5924    && reload_completed
5925    && FP_REG_P (operands[0])"
5926   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5927   "")
5928
5929 ;; Avoid store forwarding (partial memory) stall penalty
5930 ;; by passing DImode value through XMM registers.  */
5931
5932 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5933   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5934         (float:X87MODEF
5935           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5936    (clobber (match_scratch:V4SI 3 "=X,x"))
5937    (clobber (match_scratch:V4SI 4 "=X,x"))
5938    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5939   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5940    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5941    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5942   "#"
5943   [(set_attr "type" "multi")
5944    (set_attr "mode" "<X87MODEF:MODE>")
5945    (set_attr "unit" "i387")
5946    (set_attr "fp_int_src" "true")])
5947
5948 (define_split
5949   [(set (match_operand:X87MODEF 0 "register_operand" "")
5950         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5951    (clobber (match_scratch:V4SI 3 ""))
5952    (clobber (match_scratch:V4SI 4 ""))
5953    (clobber (match_operand:DI 2 "memory_operand" ""))]
5954   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5955    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5956    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5957    && reload_completed
5958    && FP_REG_P (operands[0])"
5959   [(set (match_dup 2) (match_dup 3))
5960    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5961 {
5962   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5963      Assemble the 64-bit DImode value in an xmm register.  */
5964   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5965                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5966   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5967                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5968   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5969
5970   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5971 })
5972
5973 (define_split
5974   [(set (match_operand:X87MODEF 0 "register_operand" "")
5975         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5976    (clobber (match_scratch:V4SI 3 ""))
5977    (clobber (match_scratch:V4SI 4 ""))
5978    (clobber (match_operand:DI 2 "memory_operand" ""))]
5979   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5980    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5981    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5982    && reload_completed
5983    && FP_REG_P (operands[0])"
5984   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5985   "")
5986
5987 ;; Avoid store forwarding (partial memory) stall penalty by extending
5988 ;; SImode value to DImode through XMM register instead of pushing two
5989 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5990 ;; targets benefit from this optimization. Also note that fild
5991 ;; loads from memory only.
5992
5993 (define_insn "*floatunssi<mode>2_1"
5994   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5995         (unsigned_float:X87MODEF
5996           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5997    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5998    (clobber (match_scratch:SI 3 "=X,x"))]
5999   "!TARGET_64BIT
6000    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6001    && TARGET_SSE"
6002   "#"
6003   [(set_attr "type" "multi")
6004    (set_attr "mode" "<MODE>")])
6005
6006 (define_split
6007   [(set (match_operand:X87MODEF 0 "register_operand" "")
6008         (unsigned_float:X87MODEF
6009           (match_operand:SI 1 "register_operand" "")))
6010    (clobber (match_operand:DI 2 "memory_operand" ""))
6011    (clobber (match_scratch:SI 3 ""))]
6012   "!TARGET_64BIT
6013    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6014    && TARGET_SSE
6015    && reload_completed"
6016   [(set (match_dup 2) (match_dup 1))
6017    (set (match_dup 0)
6018         (float:X87MODEF (match_dup 2)))]
6019   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6020
6021 (define_split
6022   [(set (match_operand:X87MODEF 0 "register_operand" "")
6023         (unsigned_float:X87MODEF
6024           (match_operand:SI 1 "memory_operand" "")))
6025    (clobber (match_operand:DI 2 "memory_operand" ""))
6026    (clobber (match_scratch:SI 3 ""))]
6027   "!TARGET_64BIT
6028    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6029    && TARGET_SSE
6030    && reload_completed"
6031   [(set (match_dup 2) (match_dup 3))
6032    (set (match_dup 0)
6033         (float:X87MODEF (match_dup 2)))]
6034 {
6035   emit_move_insn (operands[3], operands[1]);
6036   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6037 })
6038
6039 (define_expand "floatunssi<mode>2"
6040   [(parallel
6041      [(set (match_operand:X87MODEF 0 "register_operand" "")
6042            (unsigned_float:X87MODEF
6043              (match_operand:SI 1 "nonimmediate_operand" "")))
6044       (clobber (match_dup 2))
6045       (clobber (match_scratch:SI 3 ""))])]
6046   "!TARGET_64BIT
6047    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6048         && TARGET_SSE)
6049        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6050 {
6051   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6052     {
6053       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6054       DONE;
6055     }
6056   else
6057     {
6058       enum ix86_stack_slot slot = (virtuals_instantiated
6059                                    ? SLOT_TEMP
6060                                    : SLOT_VIRTUAL);
6061       operands[2] = assign_386_stack_local (DImode, slot);
6062     }
6063 })
6064
6065 (define_expand "floatunsdisf2"
6066   [(use (match_operand:SF 0 "register_operand" ""))
6067    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6068   "TARGET_64BIT && TARGET_SSE_MATH"
6069   "x86_emit_floatuns (operands); DONE;")
6070
6071 (define_expand "floatunsdidf2"
6072   [(use (match_operand:DF 0 "register_operand" ""))
6073    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6074   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6075    && TARGET_SSE2 && TARGET_SSE_MATH"
6076 {
6077   if (TARGET_64BIT)
6078     x86_emit_floatuns (operands);
6079   else
6080     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6081   DONE;
6082 })
6083 \f
6084 ;; Add instructions
6085
6086 (define_expand "add<mode>3"
6087   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6088         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6089                     (match_operand:SDWIM 2 "<general_operand>" "")))]
6090   ""
6091   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6092
6093 (define_insn_and_split "*add<mode>3_doubleword"
6094   [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
6095         (plus:DWI
6096           (match_operand:DWI 1 "nonimmediate_operand" "%0,0")
6097           (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
6098    (clobber (reg:CC FLAGS_REG))]
6099   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6100   "#"
6101   "reload_completed"
6102   [(parallel [(set (reg:CC FLAGS_REG)
6103                    (unspec:CC [(match_dup 1) (match_dup 2)]
6104                               UNSPEC_ADD_CARRY))
6105               (set (match_dup 0)
6106                    (plus:<DWIH> (match_dup 1) (match_dup 2)))])
6107    (parallel [(set (match_dup 3)
6108                    (plus:<DWIH>
6109                      (plus:<DWIH>
6110                        (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
6111                        (match_dup 4))
6112                      (match_dup 5)))
6113               (clobber (reg:CC FLAGS_REG))])]
6114   "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
6115
6116 (define_insn "add<mode>3_carry"
6117   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6118         (plus:SWI
6119           (plus:SWI (match_operand:SWI 3 "ix86_carry_flag_operator" "")
6120                     (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6121           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6122    (clobber (reg:CC FLAGS_REG))]
6123   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6124   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6125   [(set_attr "type" "alu")
6126    (set_attr "use_carry" "1")
6127    (set_attr "pent_pair" "pu")
6128    (set_attr "mode" "<MODE>")])
6129
6130 (define_insn "*addsi3_carry_zext"
6131   [(set (match_operand:DI 0 "register_operand" "=r")
6132         (zero_extend:DI
6133           (plus:SI
6134             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6135                      (match_operand:SI 1 "nonimmediate_operand" "%0"))
6136           (match_operand:SI 2 "general_operand" "g"))))
6137    (clobber (reg:CC FLAGS_REG))]
6138   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6139   "adc{l}\t{%2, %k0|%k0, %2}"
6140   [(set_attr "type" "alu")
6141    (set_attr "use_carry" "1")
6142    (set_attr "pent_pair" "pu")
6143    (set_attr "mode" "SI")])
6144
6145 (define_insn "*add<mode>3_cc"
6146   [(set (reg:CC FLAGS_REG)
6147         (unspec:CC
6148           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6149            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6150           UNSPEC_ADD_CARRY))
6151    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6152         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6153   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6154   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6155   [(set_attr "type" "alu")
6156    (set_attr "mode" "<MODE>")])
6157
6158 (define_insn "addqi3_cc"
6159   [(set (reg:CC FLAGS_REG)
6160         (unspec:CC
6161           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6162            (match_operand:QI 2 "general_operand" "qn,qm")]
6163           UNSPEC_ADD_CARRY))
6164    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6165         (plus:QI (match_dup 1) (match_dup 2)))]
6166   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6167   "add{b}\t{%2, %0|%0, %2}"
6168   [(set_attr "type" "alu")
6169    (set_attr "mode" "QI")])
6170
6171 (define_insn "*add<mode>3_cconly_overflow"
6172   [(set (reg:CCC FLAGS_REG)
6173         (compare:CCC
6174           (plus:SWI
6175             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6176             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6177           (match_dup 1)))
6178    (clobber (match_scratch:SWI 0 "=<r>"))]
6179   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6180   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6181   [(set_attr "type" "alu")
6182    (set_attr "mode" "<MODE>")])
6183
6184 (define_insn "*lea_1_rex64"
6185   [(set (match_operand:DI 0 "register_operand" "=r")
6186         (match_operand:DI 1 "no_seg_address_operand" "p"))]
6187   "TARGET_64BIT"
6188   "lea{q}\t{%a1, %0|%0, %a1}"
6189   [(set_attr "type" "lea")
6190    (set_attr "mode" "DI")])
6191
6192 (define_insn "*lea_1"
6193   [(set (match_operand:SI 0 "register_operand" "=r")
6194         (match_operand:SI 1 "no_seg_address_operand" "p"))]
6195   "!TARGET_64BIT"
6196   "lea{l}\t{%a1, %0|%0, %a1}"
6197   [(set_attr "type" "lea")
6198    (set_attr "mode" "SI")])
6199
6200 (define_insn "*lea_1_zext"
6201   [(set (match_operand:DI 0 "register_operand" "=r")
6202         (zero_extend:DI
6203          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6204   "TARGET_64BIT"
6205   "lea{l}\t{%a1, %k0|%k0, %a1}"
6206   [(set_attr "type" "lea")
6207    (set_attr "mode" "SI")])
6208
6209 (define_insn "*lea_2_rex64"
6210   [(set (match_operand:SI 0 "register_operand" "=r")
6211         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6212   "TARGET_64BIT"
6213   "lea{l}\t{%a1, %0|%0, %a1}"
6214   [(set_attr "type" "lea")
6215    (set_attr "mode" "SI")])
6216
6217 (define_insn "*add<mode>_1"
6218   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6219         (plus:SWI48
6220           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6221           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6222    (clobber (reg:CC FLAGS_REG))]
6223   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6224 {
6225   switch (get_attr_type (insn))
6226     {
6227     case TYPE_LEA:
6228       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6229       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6230
6231     case TYPE_INCDEC:
6232       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6233       if (operands[2] == const1_rtx)
6234         return "inc{<imodesuffix>}\t%0";
6235       else
6236         {
6237           gcc_assert (operands[2] == constm1_rtx);
6238           return "dec{<imodesuffix>}\t%0";
6239         }
6240
6241     default:
6242       /* Use add as much as possible to replace lea for AGU optimization. */
6243       if (which_alternative == 2 && TARGET_OPT_AGU)
6244         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6245         
6246       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6247
6248       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6249          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6250       if (CONST_INT_P (operands[2])
6251           /* Avoid overflows.  */
6252           && (<MODE>mode != DImode
6253               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6254           && (INTVAL (operands[2]) == 128
6255               || (INTVAL (operands[2]) < 0
6256                   && INTVAL (operands[2]) != -128)))
6257         {
6258           operands[2] = GEN_INT (-INTVAL (operands[2]));
6259           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6260         }
6261       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6262     }
6263 }
6264   [(set (attr "type")
6265      (cond [(and (eq_attr "alternative" "2") 
6266                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6267               (const_string "lea")
6268             (eq_attr "alternative" "3")
6269               (const_string "lea")
6270             ; Current assemblers are broken and do not allow @GOTOFF in
6271             ; ought but a memory context.
6272             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6273               (const_string "lea")
6274             (match_operand:SWI48 2 "incdec_operand" "")
6275               (const_string "incdec")
6276            ]
6277            (const_string "alu")))
6278    (set (attr "length_immediate")
6279       (if_then_else
6280         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6281         (const_string "1")
6282         (const_string "*")))
6283    (set_attr "mode" "<MODE>")])
6284
6285 ;; It may seem that nonimmediate operand is proper one for operand 1.
6286 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6287 ;; we take care in ix86_binary_operator_ok to not allow two memory
6288 ;; operands so proper swapping will be done in reload.  This allow
6289 ;; patterns constructed from addsi_1 to match.
6290
6291 (define_insn "*addsi_1_zext"
6292   [(set (match_operand:DI 0 "register_operand" "=r,r")
6293         (zero_extend:DI
6294           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6295                    (match_operand:SI 2 "general_operand" "g,li"))))
6296    (clobber (reg:CC FLAGS_REG))]
6297   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6298 {
6299   switch (get_attr_type (insn))
6300     {
6301     case TYPE_LEA:
6302       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6303       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6304
6305     case TYPE_INCDEC:
6306       if (operands[2] == const1_rtx)
6307         return "inc{l}\t%k0";
6308       else
6309         {
6310           gcc_assert (operands[2] == constm1_rtx);
6311           return "dec{l}\t%k0";
6312         }
6313
6314     default:
6315       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6316          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6317       if (CONST_INT_P (operands[2])
6318           && (INTVAL (operands[2]) == 128
6319               || (INTVAL (operands[2]) < 0
6320                   && INTVAL (operands[2]) != -128)))
6321         {
6322           operands[2] = GEN_INT (-INTVAL (operands[2]));
6323           return "sub{l}\t{%2, %k0|%k0, %2}";
6324         }
6325       return "add{l}\t{%2, %k0|%k0, %2}";
6326     }
6327 }
6328   [(set (attr "type")
6329      (cond [(eq_attr "alternative" "1")
6330               (const_string "lea")
6331             ; Current assemblers are broken and do not allow @GOTOFF in
6332             ; ought but a memory context.
6333             (match_operand:SI 2 "pic_symbolic_operand" "")
6334               (const_string "lea")
6335             (match_operand:SI 2 "incdec_operand" "")
6336               (const_string "incdec")
6337            ]
6338            (const_string "alu")))
6339    (set (attr "length_immediate")
6340       (if_then_else
6341         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6342         (const_string "1")
6343         (const_string "*")))
6344    (set_attr "mode" "SI")])
6345
6346 (define_insn "*addhi_1"
6347   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6348         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6349                  (match_operand:HI 2 "general_operand" "rn,rm")))
6350    (clobber (reg:CC FLAGS_REG))]
6351   "TARGET_PARTIAL_REG_STALL
6352    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6353 {
6354   switch (get_attr_type (insn))
6355     {
6356     case TYPE_INCDEC:
6357       if (operands[2] == const1_rtx)
6358         return "inc{w}\t%0";
6359       else
6360         {
6361           gcc_assert (operands[2] == constm1_rtx);
6362           return "dec{w}\t%0";
6363         }
6364
6365     default:
6366       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6367          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6368       if (CONST_INT_P (operands[2])
6369           && (INTVAL (operands[2]) == 128
6370               || (INTVAL (operands[2]) < 0
6371                   && INTVAL (operands[2]) != -128)))
6372         {
6373           operands[2] = GEN_INT (-INTVAL (operands[2]));
6374           return "sub{w}\t{%2, %0|%0, %2}";
6375         }
6376       return "add{w}\t{%2, %0|%0, %2}";
6377     }
6378 }
6379   [(set (attr "type")
6380      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6381         (const_string "incdec")
6382         (const_string "alu")))
6383    (set (attr "length_immediate")
6384       (if_then_else
6385         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6386         (const_string "1")
6387         (const_string "*")))
6388    (set_attr "mode" "HI")])
6389
6390 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6391 ;; type optimizations enabled by define-splits.  This is not important
6392 ;; for PII, and in fact harmful because of partial register stalls.
6393
6394 (define_insn "*addhi_1_lea"
6395   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6396         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6397                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6398    (clobber (reg:CC FLAGS_REG))]
6399   "!TARGET_PARTIAL_REG_STALL
6400    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6401 {
6402   switch (get_attr_type (insn))
6403     {
6404     case TYPE_LEA:
6405       return "#";
6406     case TYPE_INCDEC:
6407       if (operands[2] == const1_rtx)
6408         return "inc{w}\t%0";
6409       else
6410         {
6411           gcc_assert (operands[2] == constm1_rtx);
6412           return "dec{w}\t%0";
6413         }
6414
6415     default:
6416       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6417          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6418       if (CONST_INT_P (operands[2])
6419           && (INTVAL (operands[2]) == 128
6420               || (INTVAL (operands[2]) < 0
6421                   && INTVAL (operands[2]) != -128)))
6422         {
6423           operands[2] = GEN_INT (-INTVAL (operands[2]));
6424           return "sub{w}\t{%2, %0|%0, %2}";
6425         }
6426       return "add{w}\t{%2, %0|%0, %2}";
6427     }
6428 }
6429   [(set (attr "type")
6430      (if_then_else (eq_attr "alternative" "2")
6431         (const_string "lea")
6432         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6433            (const_string "incdec")
6434            (const_string "alu"))))
6435    (set (attr "length_immediate")
6436       (if_then_else
6437         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6438         (const_string "1")
6439         (const_string "*")))
6440    (set_attr "mode" "HI,HI,SI")])
6441
6442 (define_insn "*addqi_1"
6443   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6444         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6445                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6446    (clobber (reg:CC FLAGS_REG))]
6447   "TARGET_PARTIAL_REG_STALL
6448    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6449 {
6450   int widen = (which_alternative == 2);
6451   switch (get_attr_type (insn))
6452     {
6453     case TYPE_INCDEC:
6454       if (operands[2] == const1_rtx)
6455         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6456       else
6457         {
6458           gcc_assert (operands[2] == constm1_rtx);
6459           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6460         }
6461
6462     default:
6463       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6464          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6465       if (CONST_INT_P (operands[2])
6466           && (INTVAL (operands[2]) == 128
6467               || (INTVAL (operands[2]) < 0
6468                   && INTVAL (operands[2]) != -128)))
6469         {
6470           operands[2] = GEN_INT (-INTVAL (operands[2]));
6471           if (widen)
6472             return "sub{l}\t{%2, %k0|%k0, %2}";
6473           else
6474             return "sub{b}\t{%2, %0|%0, %2}";
6475         }
6476       if (widen)
6477         return "add{l}\t{%k2, %k0|%k0, %k2}";
6478       else
6479         return "add{b}\t{%2, %0|%0, %2}";
6480     }
6481 }
6482   [(set (attr "type")
6483      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6484         (const_string "incdec")
6485         (const_string "alu")))
6486    (set (attr "length_immediate")
6487       (if_then_else
6488         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6489         (const_string "1")
6490         (const_string "*")))
6491    (set_attr "mode" "QI,QI,SI")])
6492
6493 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6494 (define_insn "*addqi_1_lea"
6495   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6496         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6497                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6498    (clobber (reg:CC FLAGS_REG))]
6499   "!TARGET_PARTIAL_REG_STALL
6500    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6501 {
6502   int widen = (which_alternative == 2);
6503   switch (get_attr_type (insn))
6504     {
6505     case TYPE_LEA:
6506       return "#";
6507     case TYPE_INCDEC:
6508       if (operands[2] == const1_rtx)
6509         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6510       else
6511         {
6512           gcc_assert (operands[2] == constm1_rtx);
6513           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6514         }
6515
6516     default:
6517       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6518          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6519       if (CONST_INT_P (operands[2])
6520           && (INTVAL (operands[2]) == 128
6521               || (INTVAL (operands[2]) < 0
6522                   && INTVAL (operands[2]) != -128)))
6523         {
6524           operands[2] = GEN_INT (-INTVAL (operands[2]));
6525           if (widen)
6526             return "sub{l}\t{%2, %k0|%k0, %2}";
6527           else
6528             return "sub{b}\t{%2, %0|%0, %2}";
6529         }
6530       if (widen)
6531         return "add{l}\t{%k2, %k0|%k0, %k2}";
6532       else
6533         return "add{b}\t{%2, %0|%0, %2}";
6534     }
6535 }
6536   [(set (attr "type")
6537      (if_then_else (eq_attr "alternative" "3")
6538         (const_string "lea")
6539         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6540            (const_string "incdec")
6541            (const_string "alu"))))
6542    (set (attr "length_immediate")
6543       (if_then_else
6544         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6545         (const_string "1")
6546         (const_string "*")))
6547    (set_attr "mode" "QI,QI,SI,SI")])
6548
6549 (define_insn "*addqi_1_slp"
6550   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6551         (plus:QI (match_dup 0)
6552                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6553    (clobber (reg:CC FLAGS_REG))]
6554   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6555    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6556 {
6557   switch (get_attr_type (insn))
6558     {
6559     case TYPE_INCDEC:
6560       if (operands[1] == const1_rtx)
6561         return "inc{b}\t%0";
6562       else
6563         {
6564           gcc_assert (operands[1] == constm1_rtx);
6565           return "dec{b}\t%0";
6566         }
6567
6568     default:
6569       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6570       if (CONST_INT_P (operands[1])
6571           && INTVAL (operands[1]) < 0)
6572         {
6573           operands[1] = GEN_INT (-INTVAL (operands[1]));
6574           return "sub{b}\t{%1, %0|%0, %1}";
6575         }
6576       return "add{b}\t{%1, %0|%0, %1}";
6577     }
6578 }
6579   [(set (attr "type")
6580      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6581         (const_string "incdec")
6582         (const_string "alu1")))
6583    (set (attr "memory")
6584      (if_then_else (match_operand 1 "memory_operand" "")
6585         (const_string "load")
6586         (const_string "none")))
6587    (set_attr "mode" "QI")])
6588
6589 (define_insn "*add<mode>_2"
6590   [(set (reg FLAGS_REG)
6591         (compare
6592           (plus:SWI48
6593             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6594             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6595           (const_int 0)))
6596    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6597         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6598   "ix86_match_ccmode (insn, CCGOCmode)
6599    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6600    /* Current assemblers are broken and do not allow @GOTOFF in
6601       ought but a memory context.  */
6602    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6603 {
6604   switch (get_attr_type (insn))
6605     {
6606     case TYPE_INCDEC:
6607       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6608       if (operands[2] == const1_rtx)
6609         return "inc{<imodesuffix>}\t%0";
6610       else
6611         {
6612           gcc_assert (operands[2] == constm1_rtx);
6613           return "dec{<imodesuffix>}\t%0";
6614         }
6615
6616     default:
6617       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6618       /* ???? In DImode, we ought to handle there the 32bit case too
6619          - do we need new constraint?  */
6620       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6621          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6622       if (CONST_INT_P (operands[2])
6623           /* Avoid overflows.  */
6624           && (<MODE>mode != DImode
6625               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6626           && (INTVAL (operands[2]) == 128
6627               || (INTVAL (operands[2]) < 0
6628                   && INTVAL (operands[2]) != -128)))
6629         {
6630           operands[2] = GEN_INT (-INTVAL (operands[2]));
6631           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6632         }
6633       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6634     }
6635 }
6636   [(set (attr "type")
6637      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6638         (const_string "incdec")
6639         (const_string "alu")))
6640    (set (attr "length_immediate")
6641       (if_then_else
6642         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6643         (const_string "1")
6644         (const_string "*")))
6645    (set_attr "mode" "<MODE>")])
6646
6647 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6648 (define_insn "*addsi_2_zext"
6649   [(set (reg FLAGS_REG)
6650         (compare
6651           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6652                    (match_operand:SI 2 "general_operand" "g"))
6653           (const_int 0)))
6654    (set (match_operand:DI 0 "register_operand" "=r")
6655         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6656   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6657    && ix86_binary_operator_ok (PLUS, SImode, operands)
6658    /* Current assemblers are broken and do not allow @GOTOFF in
6659       ought but a memory context.  */
6660    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6661 {
6662   switch (get_attr_type (insn))
6663     {
6664     case TYPE_INCDEC:
6665       if (operands[2] == const1_rtx)
6666         return "inc{l}\t%k0";
6667       else
6668         {
6669           gcc_assert (operands[2] == constm1_rtx);
6670           return "dec{l}\t%k0";
6671         }
6672
6673     default:
6674       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6675          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6676       if (CONST_INT_P (operands[2])
6677           && (INTVAL (operands[2]) == 128
6678               || (INTVAL (operands[2]) < 0
6679                   && INTVAL (operands[2]) != -128)))
6680         {
6681           operands[2] = GEN_INT (-INTVAL (operands[2]));
6682           return "sub{l}\t{%2, %k0|%k0, %2}";
6683         }
6684       return "add{l}\t{%2, %k0|%k0, %2}";
6685     }
6686 }
6687   [(set (attr "type")
6688      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6689         (const_string "incdec")
6690         (const_string "alu")))
6691    (set (attr "length_immediate")
6692       (if_then_else
6693         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6694         (const_string "1")
6695         (const_string "*")))
6696    (set_attr "mode" "SI")])
6697
6698 (define_insn "*addhi_2"
6699   [(set (reg FLAGS_REG)
6700         (compare
6701           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6702                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6703           (const_int 0)))
6704    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6705         (plus:HI (match_dup 1) (match_dup 2)))]
6706   "ix86_match_ccmode (insn, CCGOCmode)
6707    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6708 {
6709   switch (get_attr_type (insn))
6710     {
6711     case TYPE_INCDEC:
6712       if (operands[2] == const1_rtx)
6713         return "inc{w}\t%0";
6714       else
6715         {
6716           gcc_assert (operands[2] == constm1_rtx);
6717           return "dec{w}\t%0";
6718         }
6719
6720     default:
6721       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6722          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6723       if (CONST_INT_P (operands[2])
6724           && (INTVAL (operands[2]) == 128
6725               || (INTVAL (operands[2]) < 0
6726                   && INTVAL (operands[2]) != -128)))
6727         {
6728           operands[2] = GEN_INT (-INTVAL (operands[2]));
6729           return "sub{w}\t{%2, %0|%0, %2}";
6730         }
6731       return "add{w}\t{%2, %0|%0, %2}";
6732     }
6733 }
6734   [(set (attr "type")
6735      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6736         (const_string "incdec")
6737         (const_string "alu")))
6738    (set (attr "length_immediate")
6739       (if_then_else
6740         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6741         (const_string "1")
6742         (const_string "*")))
6743    (set_attr "mode" "HI")])
6744
6745 (define_insn "*addqi_2"
6746   [(set (reg FLAGS_REG)
6747         (compare
6748           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6749                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6750           (const_int 0)))
6751    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6752         (plus:QI (match_dup 1) (match_dup 2)))]
6753   "ix86_match_ccmode (insn, CCGOCmode)
6754    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6755 {
6756   switch (get_attr_type (insn))
6757     {
6758     case TYPE_INCDEC:
6759       if (operands[2] == const1_rtx)
6760         return "inc{b}\t%0";
6761       else
6762         {
6763           gcc_assert (operands[2] == constm1_rtx
6764                       || (CONST_INT_P (operands[2])
6765                           && INTVAL (operands[2]) == 255));
6766           return "dec{b}\t%0";
6767         }
6768
6769     default:
6770       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6771       if (CONST_INT_P (operands[2])
6772           && INTVAL (operands[2]) < 0)
6773         {
6774           operands[2] = GEN_INT (-INTVAL (operands[2]));
6775           return "sub{b}\t{%2, %0|%0, %2}";
6776         }
6777       return "add{b}\t{%2, %0|%0, %2}";
6778     }
6779 }
6780   [(set (attr "type")
6781      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6782         (const_string "incdec")
6783         (const_string "alu")))
6784    (set_attr "mode" "QI")])
6785
6786 (define_insn "*add<mode>_3"
6787   [(set (reg FLAGS_REG)
6788         (compare
6789           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6790           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6791    (clobber (match_scratch:SWI48 0 "=r"))]
6792   "ix86_match_ccmode (insn, CCZmode)
6793    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6794    /* Current assemblers are broken and do not allow @GOTOFF in
6795       ought but a memory context.  */
6796    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6797 {
6798   switch (get_attr_type (insn))
6799     {
6800     case TYPE_INCDEC:
6801       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6802       if (operands[2] == const1_rtx)
6803         return "inc{<imodesuffix>}\t%0";
6804       else
6805         {
6806           gcc_assert (operands[2] == constm1_rtx);
6807           return "dec{<imodesuffix>}\t%0";
6808         }
6809
6810     default:
6811       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6812       /* ???? In DImode, we ought to handle there the 32bit case too
6813          - do we need new constraint?  */
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           /* Avoid overflows.  */
6818           && (<MODE>mode != DImode
6819               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6820           && (INTVAL (operands[2]) == 128
6821               || (INTVAL (operands[2]) < 0
6822                   && INTVAL (operands[2]) != -128)))
6823         {
6824           operands[2] = GEN_INT (-INTVAL (operands[2]));
6825           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6826         }
6827       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6828     }
6829 }
6830   [(set (attr "type")
6831      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6832         (const_string "incdec")
6833         (const_string "alu")))
6834    (set (attr "length_immediate")
6835       (if_then_else
6836         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6837         (const_string "1")
6838         (const_string "*")))
6839    (set_attr "mode" "<MODE>")])
6840
6841 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6842 (define_insn "*addsi_3_zext"
6843   [(set (reg FLAGS_REG)
6844         (compare
6845           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6846           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6847    (set (match_operand:DI 0 "register_operand" "=r")
6848         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6849   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6850    && ix86_binary_operator_ok (PLUS, SImode, operands)
6851    /* Current assemblers are broken and do not allow @GOTOFF in
6852       ought but a memory context.  */
6853    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6854 {
6855   switch (get_attr_type (insn))
6856     {
6857     case TYPE_INCDEC:
6858       if (operands[2] == const1_rtx)
6859         return "inc{l}\t%k0";
6860       else
6861         {
6862           gcc_assert (operands[2] == constm1_rtx);
6863           return "dec{l}\t%k0";
6864         }
6865
6866     default:
6867       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6868          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6869       if (CONST_INT_P (operands[2])
6870           && (INTVAL (operands[2]) == 128
6871               || (INTVAL (operands[2]) < 0
6872                   && INTVAL (operands[2]) != -128)))
6873         {
6874           operands[2] = GEN_INT (-INTVAL (operands[2]));
6875           return "sub{l}\t{%2, %k0|%k0, %2}";
6876         }
6877       return "add{l}\t{%2, %k0|%k0, %2}";
6878     }
6879 }
6880   [(set (attr "type")
6881      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6882         (const_string "incdec")
6883         (const_string "alu")))
6884    (set (attr "length_immediate")
6885       (if_then_else
6886         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6887         (const_string "1")
6888         (const_string "*")))
6889    (set_attr "mode" "SI")])
6890
6891 (define_insn "*addhi_3"
6892   [(set (reg FLAGS_REG)
6893         (compare
6894           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6895           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6896    (clobber (match_scratch:HI 0 "=r"))]
6897   "ix86_match_ccmode (insn, CCZmode)
6898    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6899 {
6900   switch (get_attr_type (insn))
6901     {
6902     case TYPE_INCDEC:
6903       if (operands[2] == const1_rtx)
6904         return "inc{w}\t%0";
6905       else
6906         {
6907           gcc_assert (operands[2] == constm1_rtx);
6908           return "dec{w}\t%0";
6909         }
6910
6911     default:
6912       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6913          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6914       if (CONST_INT_P (operands[2])
6915           && (INTVAL (operands[2]) == 128
6916               || (INTVAL (operands[2]) < 0
6917                   && INTVAL (operands[2]) != -128)))
6918         {
6919           operands[2] = GEN_INT (-INTVAL (operands[2]));
6920           return "sub{w}\t{%2, %0|%0, %2}";
6921         }
6922       return "add{w}\t{%2, %0|%0, %2}";
6923     }
6924 }
6925   [(set (attr "type")
6926      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6927         (const_string "incdec")
6928         (const_string "alu")))
6929    (set (attr "length_immediate")
6930       (if_then_else
6931         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6932         (const_string "1")
6933         (const_string "*")))
6934    (set_attr "mode" "HI")])
6935
6936 (define_insn "*addqi_3"
6937   [(set (reg FLAGS_REG)
6938         (compare
6939           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6940           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6941    (clobber (match_scratch:QI 0 "=q"))]
6942   "ix86_match_ccmode (insn, CCZmode)
6943    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 {
6945   switch (get_attr_type (insn))
6946     {
6947     case TYPE_INCDEC:
6948       if (operands[2] == const1_rtx)
6949         return "inc{b}\t%0";
6950       else
6951         {
6952           gcc_assert (operands[2] == constm1_rtx
6953                       || (CONST_INT_P (operands[2])
6954                           && INTVAL (operands[2]) == 255));
6955           return "dec{b}\t%0";
6956         }
6957
6958     default:
6959       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6960       if (CONST_INT_P (operands[2])
6961           && INTVAL (operands[2]) < 0)
6962         {
6963           operands[2] = GEN_INT (-INTVAL (operands[2]));
6964           return "sub{b}\t{%2, %0|%0, %2}";
6965         }
6966       return "add{b}\t{%2, %0|%0, %2}";
6967     }
6968 }
6969   [(set (attr "type")
6970      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6971         (const_string "incdec")
6972         (const_string "alu")))
6973    (set_attr "mode" "QI")])
6974
6975 ; For comparisons against 1, -1 and 128, we may generate better code
6976 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6977 ; is matched then.  We can't accept general immediate, because for
6978 ; case of overflows,  the result is messed up.
6979 ; This pattern also don't hold of 0x8000000000000000, since the value
6980 ; overflows when negated.
6981 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6982 ; only for comparisons not depending on it.
6983
6984 (define_insn "*adddi_4"
6985   [(set (reg FLAGS_REG)
6986         (compare
6987           (match_operand:DI 1 "nonimmediate_operand" "0")
6988           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6989    (clobber (match_scratch:DI 0 "=rm"))]
6990   "TARGET_64BIT
6991    && ix86_match_ccmode (insn, CCGCmode)"
6992 {
6993   switch (get_attr_type (insn))
6994     {
6995     case TYPE_INCDEC:
6996       if (operands[2] == constm1_rtx)
6997         return "inc{q}\t%0";
6998       else
6999         {
7000           gcc_assert (operands[2] == const1_rtx);
7001           return "dec{q}\t%0";
7002         }
7003
7004     default:
7005       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7006       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7007          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7008       if ((INTVAL (operands[2]) == -128
7009            || (INTVAL (operands[2]) > 0
7010                && INTVAL (operands[2]) != 128))
7011           /* Avoid overflows.  */
7012           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
7013         return "sub{q}\t{%2, %0|%0, %2}";
7014       operands[2] = GEN_INT (-INTVAL (operands[2]));
7015       return "add{q}\t{%2, %0|%0, %2}";
7016     }
7017 }
7018   [(set (attr "type")
7019      (if_then_else (match_operand:DI 2 "incdec_operand" "")
7020         (const_string "incdec")
7021         (const_string "alu")))
7022    (set (attr "length_immediate")
7023       (if_then_else
7024         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7025         (const_string "1")
7026         (const_string "*")))
7027    (set_attr "mode" "DI")])
7028
7029 ; For comparisons against 1, -1 and 128, we may generate better code
7030 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7031 ; is matched then.  We can't accept general immediate, because for
7032 ; case of overflows,  the result is messed up.
7033 ; This pattern also don't hold of 0x80000000, since the value overflows
7034 ; when negated.
7035 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7036 ; only for comparisons not depending on it.
7037
7038 (define_insn "*addsi_4"
7039   [(set (reg FLAGS_REG)
7040         (compare
7041           (match_operand:SI 1 "nonimmediate_operand" "0")
7042           (match_operand:SI 2 "const_int_operand" "n")))
7043    (clobber (match_scratch:SI 0 "=rm"))]
7044   "ix86_match_ccmode (insn, CCGCmode)
7045    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7046 {
7047   switch (get_attr_type (insn))
7048     {
7049     case TYPE_INCDEC:
7050       if (operands[2] == constm1_rtx)
7051         return "inc{l}\t%0";
7052       else
7053         {
7054           gcc_assert (operands[2] == const1_rtx);
7055           return "dec{l}\t%0";
7056         }
7057
7058     default:
7059       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7060       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7061          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7062       if ((INTVAL (operands[2]) == -128
7063            || (INTVAL (operands[2]) > 0
7064                && INTVAL (operands[2]) != 128)))
7065         return "sub{l}\t{%2, %0|%0, %2}";
7066       operands[2] = GEN_INT (-INTVAL (operands[2]));
7067       return "add{l}\t{%2, %0|%0, %2}";
7068     }
7069 }
7070   [(set (attr "type")
7071      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7072         (const_string "incdec")
7073         (const_string "alu")))
7074    (set (attr "length_immediate")
7075       (if_then_else
7076         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7077         (const_string "1")
7078         (const_string "*")))
7079    (set_attr "mode" "SI")])
7080
7081 ; See comments above addsi_4 for details.
7082
7083 (define_insn "*addhi_4"
7084   [(set (reg FLAGS_REG)
7085         (compare
7086           (match_operand:HI 1 "nonimmediate_operand" "0")
7087           (match_operand:HI 2 "const_int_operand" "n")))
7088    (clobber (match_scratch:HI 0 "=rm"))]
7089   "ix86_match_ccmode (insn, CCGCmode)
7090    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7091 {
7092   switch (get_attr_type (insn))
7093     {
7094     case TYPE_INCDEC:
7095       if (operands[2] == constm1_rtx)
7096         return "inc{w}\t%0";
7097       else
7098         {
7099           gcc_assert (operands[2] == const1_rtx);
7100           return "dec{w}\t%0";
7101         }
7102
7103     default:
7104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7105       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7106          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7107       if ((INTVAL (operands[2]) == -128
7108            || (INTVAL (operands[2]) > 0
7109                && INTVAL (operands[2]) != 128)))
7110         return "sub{w}\t{%2, %0|%0, %2}";
7111       operands[2] = GEN_INT (-INTVAL (operands[2]));
7112       return "add{w}\t{%2, %0|%0, %2}";
7113     }
7114 }
7115   [(set (attr "type")
7116      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7117         (const_string "incdec")
7118         (const_string "alu")))
7119    (set (attr "length_immediate")
7120       (if_then_else
7121         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7122         (const_string "1")
7123         (const_string "*")))
7124    (set_attr "mode" "HI")])
7125
7126 ; See comments above addsi_4 for details.
7127
7128 (define_insn "*addqi_4"
7129   [(set (reg FLAGS_REG)
7130         (compare
7131           (match_operand:QI 1 "nonimmediate_operand" "0")
7132           (match_operand:QI 2 "const_int_operand" "n")))
7133    (clobber (match_scratch:QI 0 "=qm"))]
7134   "ix86_match_ccmode (insn, CCGCmode)
7135    && (INTVAL (operands[2]) & 0xff) != 0x80"
7136 {
7137   switch (get_attr_type (insn))
7138     {
7139     case TYPE_INCDEC:
7140       if (operands[2] == constm1_rtx
7141           || (CONST_INT_P (operands[2])
7142               && INTVAL (operands[2]) == 255))
7143         return "inc{b}\t%0";
7144       else
7145         {
7146           gcc_assert (operands[2] == const1_rtx);
7147           return "dec{b}\t%0";
7148         }
7149
7150     default:
7151       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7152       if (INTVAL (operands[2]) < 0)
7153         {
7154           operands[2] = GEN_INT (-INTVAL (operands[2]));
7155           return "add{b}\t{%2, %0|%0, %2}";
7156         }
7157       return "sub{b}\t{%2, %0|%0, %2}";
7158     }
7159 }
7160   [(set (attr "type")
7161      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7162         (const_string "incdec")
7163         (const_string "alu")))
7164    (set_attr "mode" "QI")])
7165
7166 (define_insn "*add<mode>_5"
7167   [(set (reg FLAGS_REG)
7168         (compare
7169           (plus:SWI48
7170             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
7171             (match_operand:SWI48 2 "<general_operand>" "<g>"))
7172           (const_int 0)))
7173    (clobber (match_scratch:SWI48 0 "=r"))]
7174   "ix86_match_ccmode (insn, CCGOCmode)
7175    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7176    /* Current assemblers are broken and do not allow @GOTOFF in
7177       ought but a memory context.  */
7178    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7179 {
7180   switch (get_attr_type (insn))
7181     {
7182     case TYPE_INCDEC:
7183       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7184       if (operands[2] == const1_rtx)
7185         return "inc{<imodesuffix>}\t%0";
7186       else
7187         {
7188           gcc_assert (operands[2] == constm1_rtx);
7189           return "dec{<imodesuffix>}\t%0";
7190         }
7191
7192     default:
7193       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7194       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7195          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7196       if (CONST_INT_P (operands[2])
7197           /* Avoid overflows.  */
7198           && (<MODE>mode != DImode
7199               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
7200           && (INTVAL (operands[2]) == 128
7201               || (INTVAL (operands[2]) < 0
7202                   && INTVAL (operands[2]) != -128)))
7203         {
7204           operands[2] = GEN_INT (-INTVAL (operands[2]));
7205           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7206         }
7207       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7208     }
7209 }
7210   [(set (attr "type")
7211      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
7212         (const_string "incdec")
7213         (const_string "alu")))
7214    (set (attr "length_immediate")
7215       (if_then_else
7216         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7217         (const_string "1")
7218         (const_string "*")))
7219    (set_attr "mode" "<MODE>")])
7220
7221 (define_insn "*addhi_5"
7222   [(set (reg FLAGS_REG)
7223         (compare
7224           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7225                    (match_operand:HI 2 "general_operand" "rmn"))
7226           (const_int 0)))
7227    (clobber (match_scratch:HI 0 "=r"))]
7228   "ix86_match_ccmode (insn, CCGOCmode)
7229    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7230 {
7231   switch (get_attr_type (insn))
7232     {
7233     case TYPE_INCDEC:
7234       if (operands[2] == const1_rtx)
7235         return "inc{w}\t%0";
7236       else
7237         {
7238           gcc_assert (operands[2] == constm1_rtx);
7239           return "dec{w}\t%0";
7240         }
7241
7242     default:
7243       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7244          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7245       if (CONST_INT_P (operands[2])
7246           && (INTVAL (operands[2]) == 128
7247               || (INTVAL (operands[2]) < 0
7248                   && INTVAL (operands[2]) != -128)))
7249         {
7250           operands[2] = GEN_INT (-INTVAL (operands[2]));
7251           return "sub{w}\t{%2, %0|%0, %2}";
7252         }
7253       return "add{w}\t{%2, %0|%0, %2}";
7254     }
7255 }
7256   [(set (attr "type")
7257      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7258         (const_string "incdec")
7259         (const_string "alu")))
7260    (set (attr "length_immediate")
7261       (if_then_else
7262         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7263         (const_string "1")
7264         (const_string "*")))
7265    (set_attr "mode" "HI")])
7266
7267 (define_insn "*addqi_5"
7268   [(set (reg FLAGS_REG)
7269         (compare
7270           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7271                    (match_operand:QI 2 "general_operand" "qmn"))
7272           (const_int 0)))
7273    (clobber (match_scratch:QI 0 "=q"))]
7274   "ix86_match_ccmode (insn, CCGOCmode)
7275    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7276 {
7277   switch (get_attr_type (insn))
7278     {
7279     case TYPE_INCDEC:
7280       if (operands[2] == const1_rtx)
7281         return "inc{b}\t%0";
7282       else
7283         {
7284           gcc_assert (operands[2] == constm1_rtx
7285                       || (CONST_INT_P (operands[2])
7286                           && INTVAL (operands[2]) == 255));
7287           return "dec{b}\t%0";
7288         }
7289
7290     default:
7291       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7292       if (CONST_INT_P (operands[2])
7293           && INTVAL (operands[2]) < 0)
7294         {
7295           operands[2] = GEN_INT (-INTVAL (operands[2]));
7296           return "sub{b}\t{%2, %0|%0, %2}";
7297         }
7298       return "add{b}\t{%2, %0|%0, %2}";
7299     }
7300 }
7301   [(set (attr "type")
7302      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7303         (const_string "incdec")
7304         (const_string "alu")))
7305    (set_attr "mode" "QI")])
7306
7307 (define_insn "*addqi_ext_1_rex64"
7308   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7309                          (const_int 8)
7310                          (const_int 8))
7311         (plus:SI
7312           (zero_extract:SI
7313             (match_operand 1 "ext_register_operand" "0")
7314             (const_int 8)
7315             (const_int 8))
7316           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7317    (clobber (reg:CC FLAGS_REG))]
7318   "TARGET_64BIT"
7319 {
7320   switch (get_attr_type (insn))
7321     {
7322     case TYPE_INCDEC:
7323       if (operands[2] == const1_rtx)
7324         return "inc{b}\t%h0";
7325       else
7326         {
7327           gcc_assert (operands[2] == constm1_rtx
7328                       || (CONST_INT_P (operands[2])
7329                           && INTVAL (operands[2]) == 255));
7330           return "dec{b}\t%h0";
7331         }
7332
7333     default:
7334       return "add{b}\t{%2, %h0|%h0, %2}";
7335     }
7336 }
7337   [(set (attr "type")
7338      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7339         (const_string "incdec")
7340         (const_string "alu")))
7341    (set_attr "modrm" "1")
7342    (set_attr "mode" "QI")])
7343
7344 (define_insn "addqi_ext_1"
7345   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7346                          (const_int 8)
7347                          (const_int 8))
7348         (plus:SI
7349           (zero_extract:SI
7350             (match_operand 1 "ext_register_operand" "0")
7351             (const_int 8)
7352             (const_int 8))
7353           (match_operand:QI 2 "general_operand" "Qmn")))
7354    (clobber (reg:CC FLAGS_REG))]
7355   "!TARGET_64BIT"
7356 {
7357   switch (get_attr_type (insn))
7358     {
7359     case TYPE_INCDEC:
7360       if (operands[2] == const1_rtx)
7361         return "inc{b}\t%h0";
7362       else
7363         {
7364           gcc_assert (operands[2] == constm1_rtx
7365                       || (CONST_INT_P (operands[2])
7366                           && INTVAL (operands[2]) == 255));
7367           return "dec{b}\t%h0";
7368         }
7369
7370     default:
7371       return "add{b}\t{%2, %h0|%h0, %2}";
7372     }
7373 }
7374   [(set (attr "type")
7375      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7376         (const_string "incdec")
7377         (const_string "alu")))
7378    (set_attr "modrm" "1")
7379    (set_attr "mode" "QI")])
7380
7381 (define_insn "*addqi_ext_2"
7382   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7383                          (const_int 8)
7384                          (const_int 8))
7385         (plus:SI
7386           (zero_extract:SI
7387             (match_operand 1 "ext_register_operand" "%0")
7388             (const_int 8)
7389             (const_int 8))
7390           (zero_extract:SI
7391             (match_operand 2 "ext_register_operand" "Q")
7392             (const_int 8)
7393             (const_int 8))))
7394    (clobber (reg:CC FLAGS_REG))]
7395   ""
7396   "add{b}\t{%h2, %h0|%h0, %h2}"
7397   [(set_attr "type" "alu")
7398    (set_attr "mode" "QI")])
7399
7400 ;; The lea patterns for non-Pmodes needs to be matched by
7401 ;; several insns converted to real lea by splitters.
7402
7403 (define_insn_and_split "*lea_general_1"
7404   [(set (match_operand 0 "register_operand" "=r")
7405         (plus (plus (match_operand 1 "index_register_operand" "l")
7406                     (match_operand 2 "register_operand" "r"))
7407               (match_operand 3 "immediate_operand" "i")))]
7408   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7409     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7410    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7411    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7412    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7413    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7414        || GET_MODE (operands[3]) == VOIDmode)"
7415   "#"
7416   "&& reload_completed"
7417   [(const_int 0)]
7418 {
7419   rtx pat;
7420   operands[0] = gen_lowpart (SImode, operands[0]);
7421   operands[1] = gen_lowpart (Pmode, operands[1]);
7422   operands[2] = gen_lowpart (Pmode, operands[2]);
7423   operands[3] = gen_lowpart (Pmode, operands[3]);
7424   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7425                       operands[3]);
7426   if (Pmode != SImode)
7427     pat = gen_rtx_SUBREG (SImode, pat, 0);
7428   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7429   DONE;
7430 }
7431   [(set_attr "type" "lea")
7432    (set_attr "mode" "SI")])
7433
7434 (define_insn_and_split "*lea_general_1_zext"
7435   [(set (match_operand:DI 0 "register_operand" "=r")
7436         (zero_extend:DI
7437           (plus:SI (plus:SI
7438                      (match_operand:SI 1 "index_register_operand" "l")
7439                      (match_operand:SI 2 "register_operand" "r"))
7440                    (match_operand:SI 3 "immediate_operand" "i"))))]
7441   "TARGET_64BIT"
7442   "#"
7443   "&& reload_completed"
7444   [(set (match_dup 0)
7445         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7446                                                      (match_dup 2))
7447                                             (match_dup 3)) 0)))]
7448 {
7449   operands[1] = gen_lowpart (Pmode, operands[1]);
7450   operands[2] = gen_lowpart (Pmode, operands[2]);
7451   operands[3] = gen_lowpart (Pmode, operands[3]);
7452 }
7453   [(set_attr "type" "lea")
7454    (set_attr "mode" "SI")])
7455
7456 (define_insn_and_split "*lea_general_2"
7457   [(set (match_operand 0 "register_operand" "=r")
7458         (plus (mult (match_operand 1 "index_register_operand" "l")
7459                     (match_operand 2 "const248_operand" "i"))
7460               (match_operand 3 "nonmemory_operand" "ri")))]
7461   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7462     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7463    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7464    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7465    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7466        || GET_MODE (operands[3]) == VOIDmode)"
7467   "#"
7468   "&& reload_completed"
7469   [(const_int 0)]
7470 {
7471   rtx pat;
7472   operands[0] = gen_lowpart (SImode, operands[0]);
7473   operands[1] = gen_lowpart (Pmode, operands[1]);
7474   operands[3] = gen_lowpart (Pmode, operands[3]);
7475   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7476                       operands[3]);
7477   if (Pmode != SImode)
7478     pat = gen_rtx_SUBREG (SImode, pat, 0);
7479   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7480   DONE;
7481 }
7482   [(set_attr "type" "lea")
7483    (set_attr "mode" "SI")])
7484
7485 (define_insn_and_split "*lea_general_2_zext"
7486   [(set (match_operand:DI 0 "register_operand" "=r")
7487         (zero_extend:DI
7488           (plus:SI (mult:SI
7489                      (match_operand:SI 1 "index_register_operand" "l")
7490                      (match_operand:SI 2 "const248_operand" "n"))
7491                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7492   "TARGET_64BIT"
7493   "#"
7494   "&& reload_completed"
7495   [(set (match_dup 0)
7496         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7497                                                      (match_dup 2))
7498                                             (match_dup 3)) 0)))]
7499 {
7500   operands[1] = gen_lowpart (Pmode, operands[1]);
7501   operands[3] = gen_lowpart (Pmode, operands[3]);
7502 }
7503   [(set_attr "type" "lea")
7504    (set_attr "mode" "SI")])
7505
7506 (define_insn_and_split "*lea_general_3"
7507   [(set (match_operand 0 "register_operand" "=r")
7508         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7509                           (match_operand 2 "const248_operand" "i"))
7510                     (match_operand 3 "register_operand" "r"))
7511               (match_operand 4 "immediate_operand" "i")))]
7512   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7513     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7514    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7515    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7516    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7517   "#"
7518   "&& reload_completed"
7519   [(const_int 0)]
7520 {
7521   rtx pat;
7522   operands[0] = gen_lowpart (SImode, operands[0]);
7523   operands[1] = gen_lowpart (Pmode, operands[1]);
7524   operands[3] = gen_lowpart (Pmode, operands[3]);
7525   operands[4] = gen_lowpart (Pmode, operands[4]);
7526   pat = gen_rtx_PLUS (Pmode,
7527                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7528                                                          operands[2]),
7529                                     operands[3]),
7530                       operands[4]);
7531   if (Pmode != SImode)
7532     pat = gen_rtx_SUBREG (SImode, pat, 0);
7533   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7534   DONE;
7535 }
7536   [(set_attr "type" "lea")
7537    (set_attr "mode" "SI")])
7538
7539 (define_insn_and_split "*lea_general_3_zext"
7540   [(set (match_operand:DI 0 "register_operand" "=r")
7541         (zero_extend:DI
7542           (plus:SI (plus:SI
7543                      (mult:SI
7544                        (match_operand:SI 1 "index_register_operand" "l")
7545                        (match_operand:SI 2 "const248_operand" "n"))
7546                      (match_operand:SI 3 "register_operand" "r"))
7547                    (match_operand:SI 4 "immediate_operand" "i"))))]
7548   "TARGET_64BIT"
7549   "#"
7550   "&& reload_completed"
7551   [(set (match_dup 0)
7552         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7553                                                               (match_dup 2))
7554                                                      (match_dup 3))
7555                                             (match_dup 4)) 0)))]
7556 {
7557   operands[1] = gen_lowpart (Pmode, operands[1]);
7558   operands[3] = gen_lowpart (Pmode, operands[3]);
7559   operands[4] = gen_lowpart (Pmode, operands[4]);
7560 }
7561   [(set_attr "type" "lea")
7562    (set_attr "mode" "SI")])
7563
7564 ;; Convert lea to the lea pattern to avoid flags dependency.
7565 (define_split
7566   [(set (match_operand:DI 0 "register_operand" "")
7567         (plus:DI (match_operand:DI 1 "register_operand" "")
7568                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7569    (clobber (reg:CC FLAGS_REG))]
7570   "TARGET_64BIT && reload_completed 
7571    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7572   [(set (match_dup 0)
7573         (plus:DI (match_dup 1)
7574                  (match_dup 2)))]
7575   "")
7576
7577 ;; Convert lea to the lea pattern to avoid flags dependency.
7578 (define_split
7579   [(set (match_operand 0 "register_operand" "")
7580         (plus (match_operand 1 "register_operand" "")
7581               (match_operand 2 "nonmemory_operand" "")))
7582    (clobber (reg:CC FLAGS_REG))]
7583   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7584   [(const_int 0)]
7585 {
7586   rtx pat;
7587   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7588      may confuse gen_lowpart.  */
7589   if (GET_MODE (operands[0]) != Pmode)
7590     {
7591       operands[1] = gen_lowpart (Pmode, operands[1]);
7592       operands[2] = gen_lowpart (Pmode, operands[2]);
7593     }
7594   operands[0] = gen_lowpart (SImode, operands[0]);
7595   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7596   if (Pmode != SImode)
7597     pat = gen_rtx_SUBREG (SImode, pat, 0);
7598   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7599   DONE;
7600 })
7601
7602 ;; Convert lea to the lea pattern to avoid flags dependency.
7603 (define_split
7604   [(set (match_operand:DI 0 "register_operand" "")
7605         (zero_extend:DI
7606           (plus:SI (match_operand:SI 1 "register_operand" "")
7607                    (match_operand:SI 2 "nonmemory_operand" ""))))
7608    (clobber (reg:CC FLAGS_REG))]
7609   "TARGET_64BIT && reload_completed
7610    && true_regnum (operands[0]) != true_regnum (operands[1])"
7611   [(set (match_dup 0)
7612         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7613 {
7614   operands[1] = gen_lowpart (Pmode, operands[1]);
7615   operands[2] = gen_lowpart (Pmode, operands[2]);
7616 })
7617 \f
7618 ;; Subtract instructions
7619
7620 (define_expand "sub<mode>3"
7621   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7622         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7623                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7624   ""
7625   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7626
7627 (define_insn_and_split "*sub<mode>3_doubleword"
7628   [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
7629         (minus:DWI
7630           (match_operand:DWI 1 "nonimmediate_operand" "0,0")
7631           (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
7632    (clobber (reg:CC FLAGS_REG))]
7633   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7634   "#"
7635   "reload_completed"
7636   [(parallel [(set (reg:CC FLAGS_REG)
7637                    (compare:CC (match_dup 1) (match_dup 2)))
7638               (set (match_dup 0)
7639                    (minus:<DWIH> (match_dup 1) (match_dup 2)))])
7640    (parallel [(set (match_dup 3)
7641                    (minus:<DWIH>
7642                      (match_dup 4)
7643                      (plus:<DWIH>
7644                        (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
7645                        (match_dup 5))))
7646               (clobber (reg:CC FLAGS_REG))])]
7647   "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
7648
7649 (define_insn "sub<mode>3_carry"
7650   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7651           (minus:SWI
7652             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7653             (plus:SWI
7654               (match_operand:SWI 3 "ix86_carry_flag_operator" "")
7655               (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7656    (clobber (reg:CC FLAGS_REG))]
7657   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7658   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7659   [(set_attr "type" "alu")
7660    (set_attr "use_carry" "1")
7661    (set_attr "pent_pair" "pu")
7662    (set_attr "mode" "<MODE>")])
7663
7664 (define_insn "*subsi3_carry_zext"
7665   [(set (match_operand:DI 0 "register_operand" "=r")
7666           (zero_extend:DI
7667             (minus:SI (match_operand:SI 1 "register_operand" "0")
7668               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7669                  (match_operand:SI 2 "general_operand" "g")))))
7670    (clobber (reg:CC FLAGS_REG))]
7671   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7672   "sbb{l}\t{%2, %k0|%k0, %2}"
7673   [(set_attr "type" "alu")
7674    (set_attr "pent_pair" "pu")
7675    (set_attr "mode" "SI")])
7676
7677 (define_insn "*sub<mode>3_cconly_overflow"
7678   [(set (reg:CCC FLAGS_REG)
7679         (compare:CCC
7680           (minus:SWI
7681             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7682             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7683           (match_dup 0)))]
7684   ""
7685   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7686   [(set_attr "type" "icmp")
7687    (set_attr "mode" "<MODE>")])
7688
7689 (define_insn "*sub<mode>_1"
7690   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7691         (minus:SWI
7692           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7693           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7694    (clobber (reg:CC FLAGS_REG))]
7695   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7696   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7697   [(set_attr "type" "alu")
7698    (set_attr "mode" "<MODE>")])
7699
7700 (define_insn "*subsi_1_zext"
7701   [(set (match_operand:DI 0 "register_operand" "=r")
7702         (zero_extend:DI
7703           (minus:SI (match_operand:SI 1 "register_operand" "0")
7704                     (match_operand:SI 2 "general_operand" "g"))))
7705    (clobber (reg:CC FLAGS_REG))]
7706   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7707   "sub{l}\t{%2, %k0|%k0, %2}"
7708   [(set_attr "type" "alu")
7709    (set_attr "mode" "SI")])
7710
7711 (define_insn "*subqi_1_slp"
7712   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7713         (minus:QI (match_dup 0)
7714                   (match_operand:QI 1 "general_operand" "qn,qm")))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7717    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7718   "sub{b}\t{%1, %0|%0, %1}"
7719   [(set_attr "type" "alu1")
7720    (set_attr "mode" "QI")])
7721
7722 (define_insn "*sub<mode>_2"
7723   [(set (reg FLAGS_REG)
7724         (compare
7725           (minus:SWI
7726             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7727             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7728           (const_int 0)))
7729    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7730         (minus:SWI (match_dup 1) (match_dup 2)))]
7731   "ix86_match_ccmode (insn, CCGOCmode)
7732    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7733   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7734   [(set_attr "type" "alu")
7735    (set_attr "mode" "<MODE>")])
7736
7737 (define_insn "*subsi_2_zext"
7738   [(set (reg FLAGS_REG)
7739         (compare
7740           (minus:SI (match_operand:SI 1 "register_operand" "0")
7741                     (match_operand:SI 2 "general_operand" "g"))
7742           (const_int 0)))
7743    (set (match_operand:DI 0 "register_operand" "=r")
7744         (zero_extend:DI
7745           (minus:SI (match_dup 1)
7746                     (match_dup 2))))]
7747   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7748    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7749   "sub{l}\t{%2, %k0|%k0, %2}"
7750   [(set_attr "type" "alu")
7751    (set_attr "mode" "SI")])
7752
7753 (define_insn "*sub<mode>_3"
7754   [(set (reg FLAGS_REG)
7755         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7756                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7757    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7758         (minus:SWI (match_dup 1) (match_dup 2)))]
7759   "ix86_match_ccmode (insn, CCmode)
7760    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7761   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7762   [(set_attr "type" "alu")
7763    (set_attr "mode" "<MODE>")])
7764
7765 (define_insn "*subsi_3_zext"
7766   [(set (reg FLAGS_REG)
7767         (compare (match_operand:SI 1 "register_operand" "0")
7768                  (match_operand:SI 2 "general_operand" "g")))
7769    (set (match_operand:DI 0 "register_operand" "=r")
7770         (zero_extend:DI
7771           (minus:SI (match_dup 1)
7772                     (match_dup 2))))]
7773   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7774    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7775   "sub{l}\t{%2, %1|%1, %2}"
7776   [(set_attr "type" "alu")
7777    (set_attr "mode" "SI")])
7778
7779
7780 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7781   [(set (reg:CCC FLAGS_REG)
7782         (compare:CCC
7783             (plusminus:SWI
7784                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7785                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7786             (match_dup 1)))
7787    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7788         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7789   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7790   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7791   [(set_attr "type" "alu")
7792    (set_attr "mode" "<MODE>")])
7793
7794 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7795   [(set (reg:CCC FLAGS_REG)
7796         (compare:CCC
7797           (plusminus:SI
7798             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7799             (match_operand:SI 2 "general_operand" "g"))
7800           (match_dup 1)))
7801    (set (match_operand:DI 0 "register_operand" "=r")
7802         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7803   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7804   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7805   [(set_attr "type" "alu")
7806    (set_attr "mode" "SI")])
7807
7808 ;; The patterns that match these are at the end of this file.
7809
7810 (define_expand "<plusminus_insn>xf3"
7811   [(set (match_operand:XF 0 "register_operand" "")
7812         (plusminus:XF
7813           (match_operand:XF 1 "register_operand" "")
7814           (match_operand:XF 2 "register_operand" "")))]
7815   "TARGET_80387"
7816   "")
7817
7818 (define_expand "<plusminus_insn><mode>3"
7819   [(set (match_operand:MODEF 0 "register_operand" "")
7820         (plusminus:MODEF
7821           (match_operand:MODEF 1 "register_operand" "")
7822           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7823   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7824     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7825   "")
7826 \f
7827 ;; Multiply instructions
7828
7829 (define_expand "muldi3"
7830   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7831                    (mult:DI (match_operand:DI 1 "register_operand" "")
7832                             (match_operand:DI 2 "x86_64_general_operand" "")))
7833               (clobber (reg:CC FLAGS_REG))])]
7834   "TARGET_64BIT"
7835   "")
7836
7837 ;; On AMDFAM10
7838 ;; IMUL reg64, reg64, imm8      Direct
7839 ;; IMUL reg64, mem64, imm8      VectorPath
7840 ;; IMUL reg64, reg64, imm32     Direct
7841 ;; IMUL reg64, mem64, imm32     VectorPath
7842 ;; IMUL reg64, reg64            Direct
7843 ;; IMUL reg64, mem64            Direct
7844
7845 (define_insn "*muldi3_1_rex64"
7846   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7847         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7848                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7849    (clobber (reg:CC FLAGS_REG))]
7850   "TARGET_64BIT
7851    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7852   "@
7853    imul{q}\t{%2, %1, %0|%0, %1, %2}
7854    imul{q}\t{%2, %1, %0|%0, %1, %2}
7855    imul{q}\t{%2, %0|%0, %2}"
7856   [(set_attr "type" "imul")
7857    (set_attr "prefix_0f" "0,0,1")
7858    (set (attr "athlon_decode")
7859         (cond [(eq_attr "cpu" "athlon")
7860                   (const_string "vector")
7861                (eq_attr "alternative" "1")
7862                   (const_string "vector")
7863                (and (eq_attr "alternative" "2")
7864                     (match_operand 1 "memory_operand" ""))
7865                   (const_string "vector")]
7866               (const_string "direct")))
7867    (set (attr "amdfam10_decode")
7868         (cond [(and (eq_attr "alternative" "0,1")
7869                     (match_operand 1 "memory_operand" ""))
7870                   (const_string "vector")]
7871               (const_string "direct")))
7872    (set_attr "mode" "DI")])
7873
7874 (define_expand "mulsi3"
7875   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7876                    (mult:SI (match_operand:SI 1 "register_operand" "")
7877                             (match_operand:SI 2 "general_operand" "")))
7878               (clobber (reg:CC FLAGS_REG))])]
7879   ""
7880   "")
7881
7882 ;; On AMDFAM10
7883 ;; IMUL reg32, reg32, imm8      Direct
7884 ;; IMUL reg32, mem32, imm8      VectorPath
7885 ;; IMUL reg32, reg32, imm32     Direct
7886 ;; IMUL reg32, mem32, imm32     VectorPath
7887 ;; IMUL reg32, reg32            Direct
7888 ;; IMUL reg32, mem32            Direct
7889
7890 (define_insn "*mulsi3_1"
7891   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7892         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7893                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7894    (clobber (reg:CC FLAGS_REG))]
7895   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7896   "@
7897    imul{l}\t{%2, %1, %0|%0, %1, %2}
7898    imul{l}\t{%2, %1, %0|%0, %1, %2}
7899    imul{l}\t{%2, %0|%0, %2}"
7900   [(set_attr "type" "imul")
7901    (set_attr "prefix_0f" "0,0,1")
7902    (set (attr "athlon_decode")
7903         (cond [(eq_attr "cpu" "athlon")
7904                   (const_string "vector")
7905                (eq_attr "alternative" "1")
7906                   (const_string "vector")
7907                (and (eq_attr "alternative" "2")
7908                     (match_operand 1 "memory_operand" ""))
7909                   (const_string "vector")]
7910               (const_string "direct")))
7911    (set (attr "amdfam10_decode")
7912         (cond [(and (eq_attr "alternative" "0,1")
7913                     (match_operand 1 "memory_operand" ""))
7914                   (const_string "vector")]
7915               (const_string "direct")))
7916    (set_attr "mode" "SI")])
7917
7918 (define_insn "*mulsi3_1_zext"
7919   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7920         (zero_extend:DI
7921           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7922                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7923    (clobber (reg:CC FLAGS_REG))]
7924   "TARGET_64BIT
7925    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7926   "@
7927    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7928    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7929    imul{l}\t{%2, %k0|%k0, %2}"
7930   [(set_attr "type" "imul")
7931    (set_attr "prefix_0f" "0,0,1")
7932    (set (attr "athlon_decode")
7933         (cond [(eq_attr "cpu" "athlon")
7934                   (const_string "vector")
7935                (eq_attr "alternative" "1")
7936                   (const_string "vector")
7937                (and (eq_attr "alternative" "2")
7938                     (match_operand 1 "memory_operand" ""))
7939                   (const_string "vector")]
7940               (const_string "direct")))
7941    (set (attr "amdfam10_decode")
7942         (cond [(and (eq_attr "alternative" "0,1")
7943                     (match_operand 1 "memory_operand" ""))
7944                   (const_string "vector")]
7945               (const_string "direct")))
7946    (set_attr "mode" "SI")])
7947
7948 (define_expand "mulhi3"
7949   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7950                    (mult:HI (match_operand:HI 1 "register_operand" "")
7951                             (match_operand:HI 2 "general_operand" "")))
7952               (clobber (reg:CC FLAGS_REG))])]
7953   "TARGET_HIMODE_MATH"
7954   "")
7955
7956 ;; On AMDFAM10
7957 ;; IMUL reg16, reg16, imm8      VectorPath
7958 ;; IMUL reg16, mem16, imm8      VectorPath
7959 ;; IMUL reg16, reg16, imm16     VectorPath
7960 ;; IMUL reg16, mem16, imm16     VectorPath
7961 ;; IMUL reg16, reg16            Direct
7962 ;; IMUL reg16, mem16            Direct
7963 (define_insn "*mulhi3_1"
7964   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7965         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7966                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7967    (clobber (reg:CC FLAGS_REG))]
7968   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7969   "@
7970    imul{w}\t{%2, %1, %0|%0, %1, %2}
7971    imul{w}\t{%2, %1, %0|%0, %1, %2}
7972    imul{w}\t{%2, %0|%0, %2}"
7973   [(set_attr "type" "imul")
7974    (set_attr "prefix_0f" "0,0,1")
7975    (set (attr "athlon_decode")
7976         (cond [(eq_attr "cpu" "athlon")
7977                   (const_string "vector")
7978                (eq_attr "alternative" "1,2")
7979                   (const_string "vector")]
7980               (const_string "direct")))
7981    (set (attr "amdfam10_decode")
7982         (cond [(eq_attr "alternative" "0,1")
7983                   (const_string "vector")]
7984               (const_string "direct")))
7985    (set_attr "mode" "HI")])
7986
7987 (define_expand "mulqi3"
7988   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7989                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7990                             (match_operand:QI 2 "register_operand" "")))
7991               (clobber (reg:CC FLAGS_REG))])]
7992   "TARGET_QIMODE_MATH"
7993   "")
7994
7995 ;;On AMDFAM10
7996 ;; MUL reg8     Direct
7997 ;; MUL mem8     Direct
7998
7999 (define_insn "*mulqi3_1"
8000   [(set (match_operand:QI 0 "register_operand" "=a")
8001         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8002                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8003    (clobber (reg:CC FLAGS_REG))]
8004   "TARGET_QIMODE_MATH
8005    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8006   "mul{b}\t%2"
8007   [(set_attr "type" "imul")
8008    (set_attr "length_immediate" "0")
8009    (set (attr "athlon_decode")
8010      (if_then_else (eq_attr "cpu" "athlon")
8011         (const_string "vector")
8012         (const_string "direct")))
8013    (set_attr "amdfam10_decode" "direct")
8014    (set_attr "mode" "QI")])
8015
8016 (define_expand "umulqihi3"
8017   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8018                    (mult:HI (zero_extend:HI
8019                               (match_operand:QI 1 "nonimmediate_operand" ""))
8020                             (zero_extend:HI
8021                               (match_operand:QI 2 "register_operand" ""))))
8022               (clobber (reg:CC FLAGS_REG))])]
8023   "TARGET_QIMODE_MATH"
8024   "")
8025
8026 (define_insn "*umulqihi3_1"
8027   [(set (match_operand:HI 0 "register_operand" "=a")
8028         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8029                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8030    (clobber (reg:CC FLAGS_REG))]
8031   "TARGET_QIMODE_MATH
8032    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8033   "mul{b}\t%2"
8034   [(set_attr "type" "imul")
8035    (set_attr "length_immediate" "0")
8036    (set (attr "athlon_decode")
8037      (if_then_else (eq_attr "cpu" "athlon")
8038         (const_string "vector")
8039         (const_string "direct")))
8040    (set_attr "amdfam10_decode" "direct")
8041    (set_attr "mode" "QI")])
8042
8043 (define_expand "mulqihi3"
8044   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8045                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8046                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8047               (clobber (reg:CC FLAGS_REG))])]
8048   "TARGET_QIMODE_MATH"
8049   "")
8050
8051 (define_insn "*mulqihi3_insn"
8052   [(set (match_operand:HI 0 "register_operand" "=a")
8053         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8054                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8055    (clobber (reg:CC FLAGS_REG))]
8056   "TARGET_QIMODE_MATH
8057    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8058   "imul{b}\t%2"
8059   [(set_attr "type" "imul")
8060    (set_attr "length_immediate" "0")
8061    (set (attr "athlon_decode")
8062      (if_then_else (eq_attr "cpu" "athlon")
8063         (const_string "vector")
8064         (const_string "direct")))
8065    (set_attr "amdfam10_decode" "direct")
8066    (set_attr "mode" "QI")])
8067
8068 (define_expand "umulditi3"
8069   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8070                    (mult:TI (zero_extend:TI
8071                               (match_operand:DI 1 "nonimmediate_operand" ""))
8072                             (zero_extend:TI
8073                               (match_operand:DI 2 "register_operand" ""))))
8074               (clobber (reg:CC FLAGS_REG))])]
8075   "TARGET_64BIT"
8076   "")
8077
8078 (define_insn "*umulditi3_insn"
8079   [(set (match_operand:TI 0 "register_operand" "=A")
8080         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8081                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8082    (clobber (reg:CC FLAGS_REG))]
8083   "TARGET_64BIT
8084    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8085   "mul{q}\t%2"
8086   [(set_attr "type" "imul")
8087    (set_attr "length_immediate" "0")
8088    (set (attr "athlon_decode")
8089      (if_then_else (eq_attr "cpu" "athlon")
8090         (const_string "vector")
8091         (const_string "double")))
8092    (set_attr "amdfam10_decode" "double")
8093    (set_attr "mode" "DI")])
8094
8095 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8096 (define_expand "umulsidi3"
8097   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8098                    (mult:DI (zero_extend:DI
8099                               (match_operand:SI 1 "nonimmediate_operand" ""))
8100                             (zero_extend:DI
8101                               (match_operand:SI 2 "register_operand" ""))))
8102               (clobber (reg:CC FLAGS_REG))])]
8103   "!TARGET_64BIT"
8104   "")
8105
8106 (define_insn "*umulsidi3_insn"
8107   [(set (match_operand:DI 0 "register_operand" "=A")
8108         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8109                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8110    (clobber (reg:CC FLAGS_REG))]
8111   "!TARGET_64BIT
8112    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8113   "mul{l}\t%2"
8114   [(set_attr "type" "imul")
8115    (set_attr "length_immediate" "0")
8116    (set (attr "athlon_decode")
8117      (if_then_else (eq_attr "cpu" "athlon")
8118         (const_string "vector")
8119         (const_string "double")))
8120    (set_attr "amdfam10_decode" "double")
8121    (set_attr "mode" "SI")])
8122
8123 (define_expand "mulditi3"
8124   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8125                    (mult:TI (sign_extend:TI
8126                               (match_operand:DI 1 "nonimmediate_operand" ""))
8127                             (sign_extend:TI
8128                               (match_operand:DI 2 "register_operand" ""))))
8129               (clobber (reg:CC FLAGS_REG))])]
8130   "TARGET_64BIT"
8131   "")
8132
8133 (define_insn "*mulditi3_insn"
8134   [(set (match_operand:TI 0 "register_operand" "=A")
8135         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8136                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8137    (clobber (reg:CC FLAGS_REG))]
8138   "TARGET_64BIT
8139    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8140   "imul{q}\t%2"
8141   [(set_attr "type" "imul")
8142    (set_attr "length_immediate" "0")
8143    (set (attr "athlon_decode")
8144      (if_then_else (eq_attr "cpu" "athlon")
8145         (const_string "vector")
8146         (const_string "double")))
8147    (set_attr "amdfam10_decode" "double")
8148    (set_attr "mode" "DI")])
8149
8150 (define_expand "mulsidi3"
8151   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8152                    (mult:DI (sign_extend:DI
8153                               (match_operand:SI 1 "nonimmediate_operand" ""))
8154                             (sign_extend:DI
8155                               (match_operand:SI 2 "register_operand" ""))))
8156               (clobber (reg:CC FLAGS_REG))])]
8157   "!TARGET_64BIT"
8158   "")
8159
8160 (define_insn "*mulsidi3_insn"
8161   [(set (match_operand:DI 0 "register_operand" "=A")
8162         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8163                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8164    (clobber (reg:CC FLAGS_REG))]
8165   "!TARGET_64BIT
8166    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8167   "imul{l}\t%2"
8168   [(set_attr "type" "imul")
8169    (set_attr "length_immediate" "0")
8170    (set (attr "athlon_decode")
8171      (if_then_else (eq_attr "cpu" "athlon")
8172         (const_string "vector")
8173         (const_string "double")))
8174    (set_attr "amdfam10_decode" "double")
8175    (set_attr "mode" "SI")])
8176
8177 (define_expand "umuldi3_highpart"
8178   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8179                    (truncate:DI
8180                      (lshiftrt:TI
8181                        (mult:TI (zero_extend:TI
8182                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8183                                 (zero_extend:TI
8184                                   (match_operand:DI 2 "register_operand" "")))
8185                        (const_int 64))))
8186               (clobber (match_scratch:DI 3 ""))
8187               (clobber (reg:CC FLAGS_REG))])]
8188   "TARGET_64BIT"
8189   "")
8190
8191 (define_insn "*umuldi3_highpart_rex64"
8192   [(set (match_operand:DI 0 "register_operand" "=d")
8193         (truncate:DI
8194           (lshiftrt:TI
8195             (mult:TI (zero_extend:TI
8196                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8197                      (zero_extend:TI
8198                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8199             (const_int 64))))
8200    (clobber (match_scratch:DI 3 "=1"))
8201    (clobber (reg:CC FLAGS_REG))]
8202   "TARGET_64BIT
8203    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8204   "mul{q}\t%2"
8205   [(set_attr "type" "imul")
8206    (set_attr "length_immediate" "0")
8207    (set (attr "athlon_decode")
8208      (if_then_else (eq_attr "cpu" "athlon")
8209         (const_string "vector")
8210         (const_string "double")))
8211    (set_attr "amdfam10_decode" "double")
8212    (set_attr "mode" "DI")])
8213
8214 (define_expand "umulsi3_highpart"
8215   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8216                    (truncate:SI
8217                      (lshiftrt:DI
8218                        (mult:DI (zero_extend:DI
8219                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8220                                 (zero_extend:DI
8221                                   (match_operand:SI 2 "register_operand" "")))
8222                        (const_int 32))))
8223               (clobber (match_scratch:SI 3 ""))
8224               (clobber (reg:CC FLAGS_REG))])]
8225   ""
8226   "")
8227
8228 (define_insn "*umulsi3_highpart_insn"
8229   [(set (match_operand:SI 0 "register_operand" "=d")
8230         (truncate:SI
8231           (lshiftrt:DI
8232             (mult:DI (zero_extend:DI
8233                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8234                      (zero_extend:DI
8235                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8236             (const_int 32))))
8237    (clobber (match_scratch:SI 3 "=1"))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8240   "mul{l}\t%2"
8241   [(set_attr "type" "imul")
8242    (set_attr "length_immediate" "0")
8243    (set (attr "athlon_decode")
8244      (if_then_else (eq_attr "cpu" "athlon")
8245         (const_string "vector")
8246         (const_string "double")))
8247    (set_attr "amdfam10_decode" "double")
8248    (set_attr "mode" "SI")])
8249
8250 (define_insn "*umulsi3_highpart_zext"
8251   [(set (match_operand:DI 0 "register_operand" "=d")
8252         (zero_extend:DI (truncate:SI
8253           (lshiftrt:DI
8254             (mult:DI (zero_extend:DI
8255                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8256                      (zero_extend:DI
8257                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8258             (const_int 32)))))
8259    (clobber (match_scratch:SI 3 "=1"))
8260    (clobber (reg:CC FLAGS_REG))]
8261   "TARGET_64BIT
8262    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8263   "mul{l}\t%2"
8264   [(set_attr "type" "imul")
8265    (set_attr "length_immediate" "0")
8266    (set (attr "athlon_decode")
8267      (if_then_else (eq_attr "cpu" "athlon")
8268         (const_string "vector")
8269         (const_string "double")))
8270    (set_attr "amdfam10_decode" "double")
8271    (set_attr "mode" "SI")])
8272
8273 (define_expand "smuldi3_highpart"
8274   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8275                    (truncate:DI
8276                      (lshiftrt:TI
8277                        (mult:TI (sign_extend:TI
8278                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8279                                 (sign_extend:TI
8280                                   (match_operand:DI 2 "register_operand" "")))
8281                        (const_int 64))))
8282               (clobber (match_scratch:DI 3 ""))
8283               (clobber (reg:CC FLAGS_REG))])]
8284   "TARGET_64BIT"
8285   "")
8286
8287 (define_insn "*smuldi3_highpart_rex64"
8288   [(set (match_operand:DI 0 "register_operand" "=d")
8289         (truncate:DI
8290           (lshiftrt:TI
8291             (mult:TI (sign_extend:TI
8292                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8293                      (sign_extend:TI
8294                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8295             (const_int 64))))
8296    (clobber (match_scratch:DI 3 "=1"))
8297    (clobber (reg:CC FLAGS_REG))]
8298   "TARGET_64BIT
8299    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8300   "imul{q}\t%2"
8301   [(set_attr "type" "imul")
8302    (set (attr "athlon_decode")
8303      (if_then_else (eq_attr "cpu" "athlon")
8304         (const_string "vector")
8305         (const_string "double")))
8306    (set_attr "amdfam10_decode" "double")
8307    (set_attr "mode" "DI")])
8308
8309 (define_expand "smulsi3_highpart"
8310   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8311                    (truncate:SI
8312                      (lshiftrt:DI
8313                        (mult:DI (sign_extend:DI
8314                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8315                                 (sign_extend:DI
8316                                   (match_operand:SI 2 "register_operand" "")))
8317                        (const_int 32))))
8318               (clobber (match_scratch:SI 3 ""))
8319               (clobber (reg:CC FLAGS_REG))])]
8320   ""
8321   "")
8322
8323 (define_insn "*smulsi3_highpart_insn"
8324   [(set (match_operand:SI 0 "register_operand" "=d")
8325         (truncate:SI
8326           (lshiftrt:DI
8327             (mult:DI (sign_extend:DI
8328                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8329                      (sign_extend:DI
8330                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8331             (const_int 32))))
8332    (clobber (match_scratch:SI 3 "=1"))
8333    (clobber (reg:CC FLAGS_REG))]
8334   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8335   "imul{l}\t%2"
8336   [(set_attr "type" "imul")
8337    (set (attr "athlon_decode")
8338      (if_then_else (eq_attr "cpu" "athlon")
8339         (const_string "vector")
8340         (const_string "double")))
8341    (set_attr "amdfam10_decode" "double")
8342    (set_attr "mode" "SI")])
8343
8344 (define_insn "*smulsi3_highpart_zext"
8345   [(set (match_operand:DI 0 "register_operand" "=d")
8346         (zero_extend:DI (truncate:SI
8347           (lshiftrt:DI
8348             (mult:DI (sign_extend:DI
8349                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8350                      (sign_extend:DI
8351                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8352             (const_int 32)))))
8353    (clobber (match_scratch:SI 3 "=1"))
8354    (clobber (reg:CC FLAGS_REG))]
8355   "TARGET_64BIT
8356    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8357   "imul{l}\t%2"
8358   [(set_attr "type" "imul")
8359    (set (attr "athlon_decode")
8360      (if_then_else (eq_attr "cpu" "athlon")
8361         (const_string "vector")
8362         (const_string "double")))
8363    (set_attr "amdfam10_decode" "double")
8364    (set_attr "mode" "SI")])
8365
8366 ;; The patterns that match these are at the end of this file.
8367
8368 (define_expand "mulxf3"
8369   [(set (match_operand:XF 0 "register_operand" "")
8370         (mult:XF (match_operand:XF 1 "register_operand" "")
8371                  (match_operand:XF 2 "register_operand" "")))]
8372   "TARGET_80387"
8373   "")
8374
8375 (define_expand "mul<mode>3"
8376   [(set (match_operand:MODEF 0 "register_operand" "")
8377         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8378                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8379   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8380     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8381   "")
8382
8383 \f
8384 ;; Divide instructions
8385
8386 (define_insn "divqi3"
8387   [(set (match_operand:QI 0 "register_operand" "=a")
8388         (div:QI (match_operand:HI 1 "register_operand" "0")
8389                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "TARGET_QIMODE_MATH"
8392   "idiv{b}\t%2"
8393   [(set_attr "type" "idiv")
8394    (set_attr "mode" "QI")])
8395
8396 (define_insn "udivqi3"
8397   [(set (match_operand:QI 0 "register_operand" "=a")
8398         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8399                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8400    (clobber (reg:CC FLAGS_REG))]
8401   "TARGET_QIMODE_MATH"
8402   "div{b}\t%2"
8403   [(set_attr "type" "idiv")
8404    (set_attr "mode" "QI")])
8405
8406 ;; The patterns that match these are at the end of this file.
8407
8408 (define_expand "divxf3"
8409   [(set (match_operand:XF 0 "register_operand" "")
8410         (div:XF (match_operand:XF 1 "register_operand" "")
8411                 (match_operand:XF 2 "register_operand" "")))]
8412   "TARGET_80387"
8413   "")
8414
8415 (define_expand "divdf3"
8416   [(set (match_operand:DF 0 "register_operand" "")
8417         (div:DF (match_operand:DF 1 "register_operand" "")
8418                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8419    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8420     || (TARGET_SSE2 && TARGET_SSE_MATH)"
8421    "")
8422
8423 (define_expand "divsf3"
8424   [(set (match_operand:SF 0 "register_operand" "")
8425         (div:SF (match_operand:SF 1 "register_operand" "")
8426                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8427   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8428     || TARGET_SSE_MATH"
8429 {
8430   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8431       && flag_finite_math_only && !flag_trapping_math
8432       && flag_unsafe_math_optimizations)
8433     {
8434       ix86_emit_swdivsf (operands[0], operands[1],
8435                          operands[2], SFmode);
8436       DONE;
8437     }
8438 })
8439 \f
8440 ;; Divmod instructions.
8441
8442 (define_expand "divmod<mode>4"
8443   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8444                    (div:SWIM248
8445                      (match_operand:SWIM248 1 "register_operand" "")
8446                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8447               (set (match_operand:SWIM248 3 "register_operand" "")
8448                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
8449               (clobber (reg:CC FLAGS_REG))])]
8450   ""
8451   "")
8452
8453 (define_insn_and_split "*divmod<mode>4"
8454   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8455         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8456                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8457    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8458         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8459    (clobber (reg:CC FLAGS_REG))]
8460   ""
8461   "#"
8462   "&& reload_completed"
8463   [(parallel [(set (match_dup 1)
8464                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8465               (clobber (reg:CC FLAGS_REG))])
8466    (parallel [(set (match_dup 0)
8467                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8468               (set (match_dup 1)
8469                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8470               (use (match_dup 1))
8471               (clobber (reg:CC FLAGS_REG))])]
8472 {
8473   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8474
8475   if (<MODE>mode != HImode
8476       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8477     operands[4] = operands[2];
8478   else
8479     {
8480       /* Avoid use of cltd in favor of a mov+shift.  */
8481       emit_move_insn (operands[1], operands[2]);
8482       operands[4] = operands[1];
8483     }
8484 }
8485   [(set_attr "type" "multi")
8486    (set_attr "mode" "<MODE>")])
8487
8488 (define_insn "*divmod<mode>4_noext"
8489   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8490         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8491                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8492    (set (match_operand:SWIM248 1 "register_operand" "=d")
8493         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8494    (use (match_operand:SWIM248 4 "register_operand" "1"))
8495    (clobber (reg:CC FLAGS_REG))]
8496   ""
8497   "idiv{<imodesuffix>}\t%3"
8498   [(set_attr "type" "idiv")
8499    (set_attr "mode" "<MODE>")])
8500
8501 (define_expand "udivmod<mode>4"
8502   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8503                    (udiv:SWIM248
8504                      (match_operand:SWIM248 1 "register_operand" "")
8505                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8506               (set (match_operand:SWIM248 3 "register_operand" "")
8507                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8508               (clobber (reg:CC FLAGS_REG))])]
8509   ""
8510   "")
8511
8512 (define_insn_and_split "*udivmod<mode>4"
8513   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8514         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8515                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8516    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8517         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8518    (clobber (reg:CC FLAGS_REG))]
8519   ""
8520   "#"
8521   "&& reload_completed"
8522   [(set (match_dup 1) (const_int 0))
8523    (parallel [(set (match_dup 0)
8524                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8525               (set (match_dup 1)
8526                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8527               (use (match_dup 1))
8528               (clobber (reg:CC FLAGS_REG))])]
8529   ""
8530   [(set_attr "type" "multi")
8531    (set_attr "mode" "<MODE>")])
8532
8533 (define_insn "*udivmod<mode>4_noext"
8534   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8535         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8536                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8537    (set (match_operand:SWIM248 1 "register_operand" "=d")
8538         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8539    (use (match_operand:SWIM248 4 "register_operand" "1"))
8540    (clobber (reg:CC FLAGS_REG))]
8541   ""
8542   "div{<imodesuffix>}\t%3"
8543   [(set_attr "type" "idiv")
8544    (set_attr "mode" "<MODE>")])
8545
8546 ;; We cannot use div/idiv for double division, because it causes
8547 ;; "division by zero" on the overflow and that's not what we expect
8548 ;; from truncate.  Because true (non truncating) double division is
8549 ;; never generated, we can't create this insn anyway.
8550 ;
8551 ;(define_insn ""
8552 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8553 ;       (truncate:SI
8554 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8555 ;                  (zero_extend:DI
8556 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8557 ;   (set (match_operand:SI 3 "register_operand" "=d")
8558 ;       (truncate:SI
8559 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8560 ;   (clobber (reg:CC FLAGS_REG))]
8561 ;  ""
8562 ;  "div{l}\t{%2, %0|%0, %2}"
8563 ;  [(set_attr "type" "idiv")])
8564 \f
8565 ;;- Logical AND instructions
8566
8567 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8568 ;; Note that this excludes ah.
8569
8570 (define_insn "*testdi_1_rex64"
8571   [(set (reg FLAGS_REG)
8572         (compare
8573           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8574                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8575           (const_int 0)))]
8576   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8577    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8578   "@
8579    test{l}\t{%k1, %k0|%k0, %k1}
8580    test{l}\t{%k1, %k0|%k0, %k1}
8581    test{q}\t{%1, %0|%0, %1}
8582    test{q}\t{%1, %0|%0, %1}
8583    test{q}\t{%1, %0|%0, %1}"
8584   [(set_attr "type" "test")
8585    (set_attr "modrm" "0,1,0,1,1")
8586    (set_attr "mode" "SI,SI,DI,DI,DI")
8587    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8588
8589 (define_insn "testsi_1"
8590   [(set (reg FLAGS_REG)
8591         (compare
8592           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8593                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8594           (const_int 0)))]
8595   "ix86_match_ccmode (insn, CCNOmode)
8596    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8597   "test{l}\t{%1, %0|%0, %1}"
8598   [(set_attr "type" "test")
8599    (set_attr "modrm" "0,1,1")
8600    (set_attr "mode" "SI")
8601    (set_attr "pent_pair" "uv,np,uv")])
8602
8603 (define_expand "testsi_ccno_1"
8604   [(set (reg:CCNO FLAGS_REG)
8605         (compare:CCNO
8606           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8607                   (match_operand:SI 1 "nonmemory_operand" ""))
8608           (const_int 0)))]
8609   ""
8610   "")
8611
8612 (define_insn "*testhi_1"
8613   [(set (reg FLAGS_REG)
8614         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8615                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8616                  (const_int 0)))]
8617   "ix86_match_ccmode (insn, CCNOmode)
8618    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8619   "test{w}\t{%1, %0|%0, %1}"
8620   [(set_attr "type" "test")
8621    (set_attr "modrm" "0,1,1")
8622    (set_attr "mode" "HI")
8623    (set_attr "pent_pair" "uv,np,uv")])
8624
8625 (define_expand "testqi_ccz_1"
8626   [(set (reg:CCZ FLAGS_REG)
8627         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8628                              (match_operand:QI 1 "nonmemory_operand" ""))
8629                  (const_int 0)))]
8630   ""
8631   "")
8632
8633 (define_insn "*testqi_1_maybe_si"
8634   [(set (reg FLAGS_REG)
8635         (compare
8636           (and:QI
8637             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8638             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8639           (const_int 0)))]
8640    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8641     && ix86_match_ccmode (insn,
8642                          CONST_INT_P (operands[1])
8643                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8644 {
8645   if (which_alternative == 3)
8646     {
8647       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8648         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8649       return "test{l}\t{%1, %k0|%k0, %1}";
8650     }
8651   return "test{b}\t{%1, %0|%0, %1}";
8652 }
8653   [(set_attr "type" "test")
8654    (set_attr "modrm" "0,1,1,1")
8655    (set_attr "mode" "QI,QI,QI,SI")
8656    (set_attr "pent_pair" "uv,np,uv,np")])
8657
8658 (define_insn "*testqi_1"
8659   [(set (reg FLAGS_REG)
8660         (compare
8661           (and:QI
8662             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8663             (match_operand:QI 1 "general_operand" "n,n,qn"))
8664           (const_int 0)))]
8665   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8666    && ix86_match_ccmode (insn, CCNOmode)"
8667   "test{b}\t{%1, %0|%0, %1}"
8668   [(set_attr "type" "test")
8669    (set_attr "modrm" "0,1,1")
8670    (set_attr "mode" "QI")
8671    (set_attr "pent_pair" "uv,np,uv")])
8672
8673 (define_expand "testqi_ext_ccno_0"
8674   [(set (reg:CCNO FLAGS_REG)
8675         (compare:CCNO
8676           (and:SI
8677             (zero_extract:SI
8678               (match_operand 0 "ext_register_operand" "")
8679               (const_int 8)
8680               (const_int 8))
8681             (match_operand 1 "const_int_operand" ""))
8682           (const_int 0)))]
8683   ""
8684   "")
8685
8686 (define_insn "*testqi_ext_0"
8687   [(set (reg FLAGS_REG)
8688         (compare
8689           (and:SI
8690             (zero_extract:SI
8691               (match_operand 0 "ext_register_operand" "Q")
8692               (const_int 8)
8693               (const_int 8))
8694             (match_operand 1 "const_int_operand" "n"))
8695           (const_int 0)))]
8696   "ix86_match_ccmode (insn, CCNOmode)"
8697   "test{b}\t{%1, %h0|%h0, %1}"
8698   [(set_attr "type" "test")
8699    (set_attr "mode" "QI")
8700    (set_attr "length_immediate" "1")
8701    (set_attr "modrm" "1")
8702    (set_attr "pent_pair" "np")])
8703
8704 (define_insn "*testqi_ext_1"
8705   [(set (reg FLAGS_REG)
8706         (compare
8707           (and:SI
8708             (zero_extract:SI
8709               (match_operand 0 "ext_register_operand" "Q")
8710               (const_int 8)
8711               (const_int 8))
8712             (zero_extend:SI
8713               (match_operand:QI 1 "general_operand" "Qm")))
8714           (const_int 0)))]
8715   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8716    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8717   "test{b}\t{%1, %h0|%h0, %1}"
8718   [(set_attr "type" "test")
8719    (set_attr "mode" "QI")])
8720
8721 (define_insn "*testqi_ext_1_rex64"
8722   [(set (reg FLAGS_REG)
8723         (compare
8724           (and:SI
8725             (zero_extract:SI
8726               (match_operand 0 "ext_register_operand" "Q")
8727               (const_int 8)
8728               (const_int 8))
8729             (zero_extend:SI
8730               (match_operand:QI 1 "register_operand" "Q")))
8731           (const_int 0)))]
8732   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8733   "test{b}\t{%1, %h0|%h0, %1}"
8734   [(set_attr "type" "test")
8735    (set_attr "mode" "QI")])
8736
8737 (define_insn "*testqi_ext_2"
8738   [(set (reg FLAGS_REG)
8739         (compare
8740           (and:SI
8741             (zero_extract:SI
8742               (match_operand 0 "ext_register_operand" "Q")
8743               (const_int 8)
8744               (const_int 8))
8745             (zero_extract:SI
8746               (match_operand 1 "ext_register_operand" "Q")
8747               (const_int 8)
8748               (const_int 8)))
8749           (const_int 0)))]
8750   "ix86_match_ccmode (insn, CCNOmode)"
8751   "test{b}\t{%h1, %h0|%h0, %h1}"
8752   [(set_attr "type" "test")
8753    (set_attr "mode" "QI")])
8754
8755 ;; Combine likes to form bit extractions for some tests.  Humor it.
8756 (define_insn "*testqi_ext_3"
8757   [(set (reg FLAGS_REG)
8758         (compare (zero_extract:SI
8759                    (match_operand 0 "nonimmediate_operand" "rm")
8760                    (match_operand:SI 1 "const_int_operand" "")
8761                    (match_operand:SI 2 "const_int_operand" ""))
8762                  (const_int 0)))]
8763   "ix86_match_ccmode (insn, CCNOmode)
8764    && INTVAL (operands[1]) > 0
8765    && INTVAL (operands[2]) >= 0
8766    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8767    && (GET_MODE (operands[0]) == SImode
8768        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8769        || GET_MODE (operands[0]) == HImode
8770        || GET_MODE (operands[0]) == QImode)"
8771   "#")
8772
8773 (define_insn "*testqi_ext_3_rex64"
8774   [(set (reg FLAGS_REG)
8775         (compare (zero_extract:DI
8776                    (match_operand 0 "nonimmediate_operand" "rm")
8777                    (match_operand:DI 1 "const_int_operand" "")
8778                    (match_operand:DI 2 "const_int_operand" ""))
8779                  (const_int 0)))]
8780   "TARGET_64BIT
8781    && ix86_match_ccmode (insn, CCNOmode)
8782    && INTVAL (operands[1]) > 0
8783    && INTVAL (operands[2]) >= 0
8784    /* Ensure that resulting mask is zero or sign extended operand.  */
8785    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8786        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8787            && INTVAL (operands[1]) > 32))
8788    && (GET_MODE (operands[0]) == SImode
8789        || GET_MODE (operands[0]) == DImode
8790        || GET_MODE (operands[0]) == HImode
8791        || GET_MODE (operands[0]) == QImode)"
8792   "#")
8793
8794 (define_split
8795   [(set (match_operand 0 "flags_reg_operand" "")
8796         (match_operator 1 "compare_operator"
8797           [(zero_extract
8798              (match_operand 2 "nonimmediate_operand" "")
8799              (match_operand 3 "const_int_operand" "")
8800              (match_operand 4 "const_int_operand" ""))
8801            (const_int 0)]))]
8802   "ix86_match_ccmode (insn, CCNOmode)"
8803   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8804 {
8805   rtx val = operands[2];
8806   HOST_WIDE_INT len = INTVAL (operands[3]);
8807   HOST_WIDE_INT pos = INTVAL (operands[4]);
8808   HOST_WIDE_INT mask;
8809   enum machine_mode mode, submode;
8810
8811   mode = GET_MODE (val);
8812   if (MEM_P (val))
8813     {
8814       /* ??? Combine likes to put non-volatile mem extractions in QImode
8815          no matter the size of the test.  So find a mode that works.  */
8816       if (! MEM_VOLATILE_P (val))
8817         {
8818           mode = smallest_mode_for_size (pos + len, MODE_INT);
8819           val = adjust_address (val, mode, 0);
8820         }
8821     }
8822   else if (GET_CODE (val) == SUBREG
8823            && (submode = GET_MODE (SUBREG_REG (val)),
8824                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8825            && pos + len <= GET_MODE_BITSIZE (submode))
8826     {
8827       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8828       mode = submode;
8829       val = SUBREG_REG (val);
8830     }
8831   else if (mode == HImode && pos + len <= 8)
8832     {
8833       /* Small HImode tests can be converted to QImode.  */
8834       mode = QImode;
8835       val = gen_lowpart (QImode, val);
8836     }
8837
8838   if (len == HOST_BITS_PER_WIDE_INT)
8839     mask = -1;
8840   else
8841     mask = ((HOST_WIDE_INT)1 << len) - 1;
8842   mask <<= pos;
8843
8844   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8845 })
8846
8847 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8848 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8849 ;; this is relatively important trick.
8850 ;; Do the conversion only post-reload to avoid limiting of the register class
8851 ;; to QI regs.
8852 (define_split
8853   [(set (match_operand 0 "flags_reg_operand" "")
8854         (match_operator 1 "compare_operator"
8855           [(and (match_operand 2 "register_operand" "")
8856                 (match_operand 3 "const_int_operand" ""))
8857            (const_int 0)]))]
8858    "reload_completed
8859     && QI_REG_P (operands[2])
8860     && GET_MODE (operands[2]) != QImode
8861     && ((ix86_match_ccmode (insn, CCZmode)
8862          && !(INTVAL (operands[3]) & ~(255 << 8)))
8863         || (ix86_match_ccmode (insn, CCNOmode)
8864             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8865   [(set (match_dup 0)
8866         (match_op_dup 1
8867           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8868                    (match_dup 3))
8869            (const_int 0)]))]
8870   "operands[2] = gen_lowpart (SImode, operands[2]);
8871    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8872
8873 (define_split
8874   [(set (match_operand 0 "flags_reg_operand" "")
8875         (match_operator 1 "compare_operator"
8876           [(and (match_operand 2 "nonimmediate_operand" "")
8877                 (match_operand 3 "const_int_operand" ""))
8878            (const_int 0)]))]
8879    "reload_completed
8880     && GET_MODE (operands[2]) != QImode
8881     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8882     && ((ix86_match_ccmode (insn, CCZmode)
8883          && !(INTVAL (operands[3]) & ~255))
8884         || (ix86_match_ccmode (insn, CCNOmode)
8885             && !(INTVAL (operands[3]) & ~127)))"
8886   [(set (match_dup 0)
8887         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8888                          (const_int 0)]))]
8889   "operands[2] = gen_lowpart (QImode, operands[2]);
8890    operands[3] = gen_lowpart (QImode, operands[3]);")
8891
8892
8893 ;; %%% This used to optimize known byte-wide and operations to memory,
8894 ;; and sometimes to QImode registers.  If this is considered useful,
8895 ;; it should be done with splitters.
8896
8897 (define_expand "anddi3"
8898   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8899         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8900                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8901   "TARGET_64BIT"
8902   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8903
8904 (define_insn "*anddi_1_rex64"
8905   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8906         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8907                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8908    (clobber (reg:CC FLAGS_REG))]
8909   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8910 {
8911   switch (get_attr_type (insn))
8912     {
8913     case TYPE_IMOVX:
8914       {
8915         enum machine_mode mode;
8916
8917         gcc_assert (CONST_INT_P (operands[2]));
8918         if (INTVAL (operands[2]) == 0xff)
8919           mode = QImode;
8920         else
8921           {
8922             gcc_assert (INTVAL (operands[2]) == 0xffff);
8923             mode = HImode;
8924           }
8925
8926         operands[1] = gen_lowpart (mode, operands[1]);
8927         if (mode == QImode)
8928           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8929         else
8930           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8931       }
8932
8933     default:
8934       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8935       if (get_attr_mode (insn) == MODE_SI)
8936         return "and{l}\t{%k2, %k0|%k0, %k2}";
8937       else
8938         return "and{q}\t{%2, %0|%0, %2}";
8939     }
8940 }
8941   [(set_attr "type" "alu,alu,alu,imovx")
8942    (set_attr "length_immediate" "*,*,*,0")
8943    (set (attr "prefix_rex")
8944      (if_then_else
8945        (and (eq_attr "type" "imovx")
8946             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8947                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8948        (const_string "1")
8949        (const_string "*")))
8950    (set_attr "mode" "SI,DI,DI,SI")])
8951
8952 (define_insn "*anddi_2"
8953   [(set (reg FLAGS_REG)
8954         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8955                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8956                  (const_int 0)))
8957    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8958         (and:DI (match_dup 1) (match_dup 2)))]
8959   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8960    && ix86_binary_operator_ok (AND, DImode, operands)"
8961   "@
8962    and{l}\t{%k2, %k0|%k0, %k2}
8963    and{q}\t{%2, %0|%0, %2}
8964    and{q}\t{%2, %0|%0, %2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "SI,DI,DI")])
8967
8968 (define_expand "andsi3"
8969   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8970         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8971                 (match_operand:SI 2 "general_operand" "")))]
8972   ""
8973   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8974
8975 (define_insn "*andsi_1"
8976   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8977         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8978                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8979    (clobber (reg:CC FLAGS_REG))]
8980   "ix86_binary_operator_ok (AND, SImode, operands)"
8981 {
8982   switch (get_attr_type (insn))
8983     {
8984     case TYPE_IMOVX:
8985       {
8986         enum machine_mode mode;
8987
8988         gcc_assert (CONST_INT_P (operands[2]));
8989         if (INTVAL (operands[2]) == 0xff)
8990           mode = QImode;
8991         else
8992           {
8993             gcc_assert (INTVAL (operands[2]) == 0xffff);
8994             mode = HImode;
8995           }
8996
8997         operands[1] = gen_lowpart (mode, operands[1]);
8998         if (mode == QImode)
8999           return "movz{bl|x}\t{%1, %0|%0, %1}";
9000         else
9001           return "movz{wl|x}\t{%1, %0|%0, %1}";
9002       }
9003
9004     default:
9005       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9006       return "and{l}\t{%2, %0|%0, %2}";
9007     }
9008 }
9009   [(set_attr "type" "alu,alu,imovx")
9010    (set (attr "prefix_rex")
9011      (if_then_else
9012        (and (eq_attr "type" "imovx")
9013             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9014                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
9015        (const_string "1")
9016        (const_string "*")))
9017    (set_attr "length_immediate" "*,*,0")
9018    (set_attr "mode" "SI")])
9019
9020 (define_split
9021   [(set (match_operand 0 "register_operand" "")
9022         (and (match_dup 0)
9023              (const_int -65536)))
9024    (clobber (reg:CC FLAGS_REG))]
9025   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9026   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9027   "operands[1] = gen_lowpart (HImode, operands[0]);")
9028
9029 (define_split
9030   [(set (match_operand 0 "ext_register_operand" "")
9031         (and (match_dup 0)
9032              (const_int -256)))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9035   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9036   "operands[1] = gen_lowpart (QImode, operands[0]);")
9037
9038 (define_split
9039   [(set (match_operand 0 "ext_register_operand" "")
9040         (and (match_dup 0)
9041              (const_int -65281)))
9042    (clobber (reg:CC FLAGS_REG))]
9043   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9044   [(parallel [(set (zero_extract:SI (match_dup 0)
9045                                     (const_int 8)
9046                                     (const_int 8))
9047                    (xor:SI
9048                      (zero_extract:SI (match_dup 0)
9049                                       (const_int 8)
9050                                       (const_int 8))
9051                      (zero_extract:SI (match_dup 0)
9052                                       (const_int 8)
9053                                       (const_int 8))))
9054               (clobber (reg:CC FLAGS_REG))])]
9055   "operands[0] = gen_lowpart (SImode, operands[0]);")
9056
9057 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9058 (define_insn "*andsi_1_zext"
9059   [(set (match_operand:DI 0 "register_operand" "=r")
9060         (zero_extend:DI
9061           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9062                   (match_operand:SI 2 "general_operand" "g"))))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9065   "and{l}\t{%2, %k0|%k0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9068
9069 (define_insn "*andsi_2"
9070   [(set (reg FLAGS_REG)
9071         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9072                          (match_operand:SI 2 "general_operand" "g,ri"))
9073                  (const_int 0)))
9074    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9075         (and:SI (match_dup 1) (match_dup 2)))]
9076   "ix86_match_ccmode (insn, CCNOmode)
9077    && ix86_binary_operator_ok (AND, SImode, operands)"
9078   "and{l}\t{%2, %0|%0, %2}"
9079   [(set_attr "type" "alu")
9080    (set_attr "mode" "SI")])
9081
9082 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9083 (define_insn "*andsi_2_zext"
9084   [(set (reg FLAGS_REG)
9085         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9086                          (match_operand:SI 2 "general_operand" "g"))
9087                  (const_int 0)))
9088    (set (match_operand:DI 0 "register_operand" "=r")
9089         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9090   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9091    && ix86_binary_operator_ok (AND, SImode, operands)"
9092   "and{l}\t{%2, %k0|%k0, %2}"
9093   [(set_attr "type" "alu")
9094    (set_attr "mode" "SI")])
9095
9096 (define_expand "andhi3"
9097   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9098         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9099                 (match_operand:HI 2 "general_operand" "")))]
9100   "TARGET_HIMODE_MATH"
9101   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9102
9103 (define_insn "*andhi_1"
9104   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9105         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9106                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9107    (clobber (reg:CC FLAGS_REG))]
9108   "ix86_binary_operator_ok (AND, HImode, operands)"
9109 {
9110   switch (get_attr_type (insn))
9111     {
9112     case TYPE_IMOVX:
9113       gcc_assert (CONST_INT_P (operands[2]));
9114       gcc_assert (INTVAL (operands[2]) == 0xff);
9115       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9116
9117     default:
9118       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9119
9120       return "and{w}\t{%2, %0|%0, %2}";
9121     }
9122 }
9123   [(set_attr "type" "alu,alu,imovx")
9124    (set_attr "length_immediate" "*,*,0")
9125    (set (attr "prefix_rex")
9126      (if_then_else
9127        (and (eq_attr "type" "imovx")
9128             (match_operand 1 "ext_QIreg_nomode_operand" ""))
9129        (const_string "1")
9130        (const_string "*")))
9131    (set_attr "mode" "HI,HI,SI")])
9132
9133 (define_insn "*andhi_2"
9134   [(set (reg FLAGS_REG)
9135         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9137                  (const_int 0)))
9138    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9139         (and:HI (match_dup 1) (match_dup 2)))]
9140   "ix86_match_ccmode (insn, CCNOmode)
9141    && ix86_binary_operator_ok (AND, HImode, operands)"
9142   "and{w}\t{%2, %0|%0, %2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "HI")])
9145
9146 (define_expand "andqi3"
9147   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9148         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9149                 (match_operand:QI 2 "general_operand" "")))]
9150   "TARGET_QIMODE_MATH"
9151   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9152
9153 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9154 (define_insn "*andqi_1"
9155   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9156         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9157                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9158    (clobber (reg:CC FLAGS_REG))]
9159   "ix86_binary_operator_ok (AND, QImode, operands)"
9160   "@
9161    and{b}\t{%2, %0|%0, %2}
9162    and{b}\t{%2, %0|%0, %2}
9163    and{l}\t{%k2, %k0|%k0, %k2}"
9164   [(set_attr "type" "alu")
9165    (set_attr "mode" "QI,QI,SI")])
9166
9167 (define_insn "*andqi_1_slp"
9168   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9169         (and:QI (match_dup 0)
9170                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9171    (clobber (reg:CC FLAGS_REG))]
9172   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9173    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9174   "and{b}\t{%1, %0|%0, %1}"
9175   [(set_attr "type" "alu1")
9176    (set_attr "mode" "QI")])
9177
9178 (define_insn "*andqi_2_maybe_si"
9179   [(set (reg FLAGS_REG)
9180         (compare (and:QI
9181                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9182                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9183                  (const_int 0)))
9184    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9185         (and:QI (match_dup 1) (match_dup 2)))]
9186   "ix86_binary_operator_ok (AND, QImode, operands)
9187    && ix86_match_ccmode (insn,
9188                          CONST_INT_P (operands[2])
9189                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9190 {
9191   if (which_alternative == 2)
9192     {
9193       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9194         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9195       return "and{l}\t{%2, %k0|%k0, %2}";
9196     }
9197   return "and{b}\t{%2, %0|%0, %2}";
9198 }
9199   [(set_attr "type" "alu")
9200    (set_attr "mode" "QI,QI,SI")])
9201
9202 (define_insn "*andqi_2"
9203   [(set (reg FLAGS_REG)
9204         (compare (and:QI
9205                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9206                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9207                  (const_int 0)))
9208    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9209         (and:QI (match_dup 1) (match_dup 2)))]
9210   "ix86_match_ccmode (insn, CCNOmode)
9211    && ix86_binary_operator_ok (AND, QImode, operands)"
9212   "and{b}\t{%2, %0|%0, %2}"
9213   [(set_attr "type" "alu")
9214    (set_attr "mode" "QI")])
9215
9216 (define_insn "*andqi_2_slp"
9217   [(set (reg FLAGS_REG)
9218         (compare (and:QI
9219                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9220                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9221                  (const_int 0)))
9222    (set (strict_low_part (match_dup 0))
9223         (and:QI (match_dup 0) (match_dup 1)))]
9224   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9225    && ix86_match_ccmode (insn, CCNOmode)
9226    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9227   "and{b}\t{%1, %0|%0, %1}"
9228   [(set_attr "type" "alu1")
9229    (set_attr "mode" "QI")])
9230
9231 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9232 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9233 ;; for a QImode operand, which of course failed.
9234
9235 (define_insn "andqi_ext_0"
9236   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9237                          (const_int 8)
9238                          (const_int 8))
9239         (and:SI
9240           (zero_extract:SI
9241             (match_operand 1 "ext_register_operand" "0")
9242             (const_int 8)
9243             (const_int 8))
9244           (match_operand 2 "const_int_operand" "n")))
9245    (clobber (reg:CC FLAGS_REG))]
9246   ""
9247   "and{b}\t{%2, %h0|%h0, %2}"
9248   [(set_attr "type" "alu")
9249    (set_attr "length_immediate" "1")
9250    (set_attr "modrm" "1")
9251    (set_attr "mode" "QI")])
9252
9253 ;; Generated by peephole translating test to and.  This shows up
9254 ;; often in fp comparisons.
9255
9256 (define_insn "*andqi_ext_0_cc"
9257   [(set (reg FLAGS_REG)
9258         (compare
9259           (and:SI
9260             (zero_extract:SI
9261               (match_operand 1 "ext_register_operand" "0")
9262               (const_int 8)
9263               (const_int 8))
9264             (match_operand 2 "const_int_operand" "n"))
9265           (const_int 0)))
9266    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9267                          (const_int 8)
9268                          (const_int 8))
9269         (and:SI
9270           (zero_extract:SI
9271             (match_dup 1)
9272             (const_int 8)
9273             (const_int 8))
9274           (match_dup 2)))]
9275   "ix86_match_ccmode (insn, CCNOmode)"
9276   "and{b}\t{%2, %h0|%h0, %2}"
9277   [(set_attr "type" "alu")
9278    (set_attr "length_immediate" "1")
9279    (set_attr "modrm" "1")
9280    (set_attr "mode" "QI")])
9281
9282 (define_insn "*andqi_ext_1"
9283   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9284                          (const_int 8)
9285                          (const_int 8))
9286         (and:SI
9287           (zero_extract:SI
9288             (match_operand 1 "ext_register_operand" "0")
9289             (const_int 8)
9290             (const_int 8))
9291           (zero_extend:SI
9292             (match_operand:QI 2 "general_operand" "Qm"))))
9293    (clobber (reg:CC FLAGS_REG))]
9294   "!TARGET_64BIT"
9295   "and{b}\t{%2, %h0|%h0, %2}"
9296   [(set_attr "type" "alu")
9297    (set_attr "length_immediate" "0")
9298    (set_attr "mode" "QI")])
9299
9300 (define_insn "*andqi_ext_1_rex64"
9301   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9302                          (const_int 8)
9303                          (const_int 8))
9304         (and:SI
9305           (zero_extract:SI
9306             (match_operand 1 "ext_register_operand" "0")
9307             (const_int 8)
9308             (const_int 8))
9309           (zero_extend:SI
9310             (match_operand 2 "ext_register_operand" "Q"))))
9311    (clobber (reg:CC FLAGS_REG))]
9312   "TARGET_64BIT"
9313   "and{b}\t{%2, %h0|%h0, %2}"
9314   [(set_attr "type" "alu")
9315    (set_attr "length_immediate" "0")
9316    (set_attr "mode" "QI")])
9317
9318 (define_insn "*andqi_ext_2"
9319   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9320                          (const_int 8)
9321                          (const_int 8))
9322         (and:SI
9323           (zero_extract:SI
9324             (match_operand 1 "ext_register_operand" "%0")
9325             (const_int 8)
9326             (const_int 8))
9327           (zero_extract:SI
9328             (match_operand 2 "ext_register_operand" "Q")
9329             (const_int 8)
9330             (const_int 8))))
9331    (clobber (reg:CC FLAGS_REG))]
9332   ""
9333   "and{b}\t{%h2, %h0|%h0, %h2}"
9334   [(set_attr "type" "alu")
9335    (set_attr "length_immediate" "0")
9336    (set_attr "mode" "QI")])
9337
9338 ;; Convert wide AND instructions with immediate operand to shorter QImode
9339 ;; equivalents when possible.
9340 ;; Don't do the splitting with memory operands, since it introduces risk
9341 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9342 ;; for size, but that can (should?) be handled by generic code instead.
9343 (define_split
9344   [(set (match_operand 0 "register_operand" "")
9345         (and (match_operand 1 "register_operand" "")
9346              (match_operand 2 "const_int_operand" "")))
9347    (clobber (reg:CC FLAGS_REG))]
9348    "reload_completed
9349     && QI_REG_P (operands[0])
9350     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9351     && !(~INTVAL (operands[2]) & ~(255 << 8))
9352     && GET_MODE (operands[0]) != QImode"
9353   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9354                    (and:SI (zero_extract:SI (match_dup 1)
9355                                             (const_int 8) (const_int 8))
9356                            (match_dup 2)))
9357               (clobber (reg:CC FLAGS_REG))])]
9358   "operands[0] = gen_lowpart (SImode, operands[0]);
9359    operands[1] = gen_lowpart (SImode, operands[1]);
9360    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9361
9362 ;; Since AND can be encoded with sign extended immediate, this is only
9363 ;; profitable when 7th bit is not set.
9364 (define_split
9365   [(set (match_operand 0 "register_operand" "")
9366         (and (match_operand 1 "general_operand" "")
9367              (match_operand 2 "const_int_operand" "")))
9368    (clobber (reg:CC FLAGS_REG))]
9369    "reload_completed
9370     && ANY_QI_REG_P (operands[0])
9371     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9372     && !(~INTVAL (operands[2]) & ~255)
9373     && !(INTVAL (operands[2]) & 128)
9374     && GET_MODE (operands[0]) != QImode"
9375   [(parallel [(set (strict_low_part (match_dup 0))
9376                    (and:QI (match_dup 1)
9377                            (match_dup 2)))
9378               (clobber (reg:CC FLAGS_REG))])]
9379   "operands[0] = gen_lowpart (QImode, operands[0]);
9380    operands[1] = gen_lowpart (QImode, operands[1]);
9381    operands[2] = gen_lowpart (QImode, operands[2]);")
9382 \f
9383 ;; Logical inclusive OR instructions
9384
9385 ;; %%% This used to optimize known byte-wide and operations to memory.
9386 ;; If this is considered useful, it should be done with splitters.
9387
9388 (define_expand "iordi3"
9389   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9390         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9391                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9392   "TARGET_64BIT"
9393   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9394
9395 (define_insn "*iordi_1_rex64"
9396   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9397         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9398                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9399    (clobber (reg:CC FLAGS_REG))]
9400   "TARGET_64BIT
9401    && ix86_binary_operator_ok (IOR, DImode, operands)"
9402   "or{q}\t{%2, %0|%0, %2}"
9403   [(set_attr "type" "alu")
9404    (set_attr "mode" "DI")])
9405
9406 (define_insn "*iordi_2_rex64"
9407   [(set (reg FLAGS_REG)
9408         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9409                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9410                  (const_int 0)))
9411    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9412         (ior:DI (match_dup 1) (match_dup 2)))]
9413   "TARGET_64BIT
9414    && ix86_match_ccmode (insn, CCNOmode)
9415    && ix86_binary_operator_ok (IOR, DImode, operands)"
9416   "or{q}\t{%2, %0|%0, %2}"
9417   [(set_attr "type" "alu")
9418    (set_attr "mode" "DI")])
9419
9420 (define_insn "*iordi_3_rex64"
9421   [(set (reg FLAGS_REG)
9422         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9423                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9424                  (const_int 0)))
9425    (clobber (match_scratch:DI 0 "=r"))]
9426   "TARGET_64BIT
9427    && ix86_match_ccmode (insn, CCNOmode)
9428    && ix86_binary_operator_ok (IOR, DImode, operands)"
9429   "or{q}\t{%2, %0|%0, %2}"
9430   [(set_attr "type" "alu")
9431    (set_attr "mode" "DI")])
9432
9433
9434 (define_expand "iorsi3"
9435   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9436         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9437                 (match_operand:SI 2 "general_operand" "")))]
9438   ""
9439   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9440
9441 (define_insn "*iorsi_1"
9442   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9443         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9444                 (match_operand:SI 2 "general_operand" "ri,g")))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "ix86_binary_operator_ok (IOR, SImode, operands)"
9447   "or{l}\t{%2, %0|%0, %2}"
9448   [(set_attr "type" "alu")
9449    (set_attr "mode" "SI")])
9450
9451 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9452 (define_insn "*iorsi_1_zext"
9453   [(set (match_operand:DI 0 "register_operand" "=r")
9454         (zero_extend:DI
9455           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9456                   (match_operand:SI 2 "general_operand" "g"))))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9459   "or{l}\t{%2, %k0|%k0, %2}"
9460   [(set_attr "type" "alu")
9461    (set_attr "mode" "SI")])
9462
9463 (define_insn "*iorsi_1_zext_imm"
9464   [(set (match_operand:DI 0 "register_operand" "=r")
9465         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9466                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9467    (clobber (reg:CC FLAGS_REG))]
9468   "TARGET_64BIT"
9469   "or{l}\t{%2, %k0|%k0, %2}"
9470   [(set_attr "type" "alu")
9471    (set_attr "mode" "SI")])
9472
9473 (define_insn "*iorsi_2"
9474   [(set (reg FLAGS_REG)
9475         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9476                          (match_operand:SI 2 "general_operand" "g,ri"))
9477                  (const_int 0)))
9478    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9479         (ior:SI (match_dup 1) (match_dup 2)))]
9480   "ix86_match_ccmode (insn, CCNOmode)
9481    && ix86_binary_operator_ok (IOR, SImode, operands)"
9482   "or{l}\t{%2, %0|%0, %2}"
9483   [(set_attr "type" "alu")
9484    (set_attr "mode" "SI")])
9485
9486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9487 ;; ??? Special case for immediate operand is missing - it is tricky.
9488 (define_insn "*iorsi_2_zext"
9489   [(set (reg FLAGS_REG)
9490         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9491                          (match_operand:SI 2 "general_operand" "g"))
9492                  (const_int 0)))
9493    (set (match_operand:DI 0 "register_operand" "=r")
9494         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9495   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9496    && ix86_binary_operator_ok (IOR, SImode, operands)"
9497   "or{l}\t{%2, %k0|%k0, %2}"
9498   [(set_attr "type" "alu")
9499    (set_attr "mode" "SI")])
9500
9501 (define_insn "*iorsi_2_zext_imm"
9502   [(set (reg FLAGS_REG)
9503         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9504                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9505                  (const_int 0)))
9506    (set (match_operand:DI 0 "register_operand" "=r")
9507         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9508   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9509    && ix86_binary_operator_ok (IOR, SImode, operands)"
9510   "or{l}\t{%2, %k0|%k0, %2}"
9511   [(set_attr "type" "alu")
9512    (set_attr "mode" "SI")])
9513
9514 (define_insn "*iorsi_3"
9515   [(set (reg FLAGS_REG)
9516         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9517                          (match_operand:SI 2 "general_operand" "g"))
9518                  (const_int 0)))
9519    (clobber (match_scratch:SI 0 "=r"))]
9520   "ix86_match_ccmode (insn, CCNOmode)
9521    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9522   "or{l}\t{%2, %0|%0, %2}"
9523   [(set_attr "type" "alu")
9524    (set_attr "mode" "SI")])
9525
9526 (define_expand "iorhi3"
9527   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9528         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9529                 (match_operand:HI 2 "general_operand" "")))]
9530   "TARGET_HIMODE_MATH"
9531   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9532
9533 (define_insn "*iorhi_1"
9534   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9535         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9536                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9537    (clobber (reg:CC FLAGS_REG))]
9538   "ix86_binary_operator_ok (IOR, HImode, operands)"
9539   "or{w}\t{%2, %0|%0, %2}"
9540   [(set_attr "type" "alu")
9541    (set_attr "mode" "HI")])
9542
9543 (define_insn "*iorhi_2"
9544   [(set (reg FLAGS_REG)
9545         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9546                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9547                  (const_int 0)))
9548    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9549         (ior:HI (match_dup 1) (match_dup 2)))]
9550   "ix86_match_ccmode (insn, CCNOmode)
9551    && ix86_binary_operator_ok (IOR, HImode, operands)"
9552   "or{w}\t{%2, %0|%0, %2}"
9553   [(set_attr "type" "alu")
9554    (set_attr "mode" "HI")])
9555
9556 (define_insn "*iorhi_3"
9557   [(set (reg FLAGS_REG)
9558         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9559                          (match_operand:HI 2 "general_operand" "rmn"))
9560                  (const_int 0)))
9561    (clobber (match_scratch:HI 0 "=r"))]
9562   "ix86_match_ccmode (insn, CCNOmode)
9563    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9564   "or{w}\t{%2, %0|%0, %2}"
9565   [(set_attr "type" "alu")
9566    (set_attr "mode" "HI")])
9567
9568 (define_expand "iorqi3"
9569   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9570         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9571                 (match_operand:QI 2 "general_operand" "")))]
9572   "TARGET_QIMODE_MATH"
9573   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9574
9575 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9576 (define_insn "*iorqi_1"
9577   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9578         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9579                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9580    (clobber (reg:CC FLAGS_REG))]
9581   "ix86_binary_operator_ok (IOR, QImode, operands)"
9582   "@
9583    or{b}\t{%2, %0|%0, %2}
9584    or{b}\t{%2, %0|%0, %2}
9585    or{l}\t{%k2, %k0|%k0, %k2}"
9586   [(set_attr "type" "alu")
9587    (set_attr "mode" "QI,QI,SI")])
9588
9589 (define_insn "*iorqi_1_slp"
9590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9591         (ior:QI (match_dup 0)
9592                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9593    (clobber (reg:CC FLAGS_REG))]
9594   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9595    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9596   "or{b}\t{%1, %0|%0, %1}"
9597   [(set_attr "type" "alu1")
9598    (set_attr "mode" "QI")])
9599
9600 (define_insn "*iorqi_2"
9601   [(set (reg FLAGS_REG)
9602         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9603                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9604                  (const_int 0)))
9605    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9606         (ior:QI (match_dup 1) (match_dup 2)))]
9607   "ix86_match_ccmode (insn, CCNOmode)
9608    && ix86_binary_operator_ok (IOR, QImode, operands)"
9609   "or{b}\t{%2, %0|%0, %2}"
9610   [(set_attr "type" "alu")
9611    (set_attr "mode" "QI")])
9612
9613 (define_insn "*iorqi_2_slp"
9614   [(set (reg FLAGS_REG)
9615         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9616                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9617                  (const_int 0)))
9618    (set (strict_low_part (match_dup 0))
9619         (ior:QI (match_dup 0) (match_dup 1)))]
9620   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9621    && ix86_match_ccmode (insn, CCNOmode)
9622    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9623   "or{b}\t{%1, %0|%0, %1}"
9624   [(set_attr "type" "alu1")
9625    (set_attr "mode" "QI")])
9626
9627 (define_insn "*iorqi_3"
9628   [(set (reg FLAGS_REG)
9629         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9630                          (match_operand:QI 2 "general_operand" "qmn"))
9631                  (const_int 0)))
9632    (clobber (match_scratch:QI 0 "=q"))]
9633   "ix86_match_ccmode (insn, CCNOmode)
9634    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9635   "or{b}\t{%2, %0|%0, %2}"
9636   [(set_attr "type" "alu")
9637    (set_attr "mode" "QI")])
9638
9639 (define_insn "*iorqi_ext_0"
9640   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9641                          (const_int 8)
9642                          (const_int 8))
9643         (ior:SI
9644           (zero_extract:SI
9645             (match_operand 1 "ext_register_operand" "0")
9646             (const_int 8)
9647             (const_int 8))
9648           (match_operand 2 "const_int_operand" "n")))
9649    (clobber (reg:CC FLAGS_REG))]
9650   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9651   "or{b}\t{%2, %h0|%h0, %2}"
9652   [(set_attr "type" "alu")
9653    (set_attr "length_immediate" "1")
9654    (set_attr "modrm" "1")
9655    (set_attr "mode" "QI")])
9656
9657 (define_insn "*iorqi_ext_1"
9658   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9659                          (const_int 8)
9660                          (const_int 8))
9661         (ior:SI
9662           (zero_extract:SI
9663             (match_operand 1 "ext_register_operand" "0")
9664             (const_int 8)
9665             (const_int 8))
9666           (zero_extend:SI
9667             (match_operand:QI 2 "general_operand" "Qm"))))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "!TARGET_64BIT
9670    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9671   "or{b}\t{%2, %h0|%h0, %2}"
9672   [(set_attr "type" "alu")
9673    (set_attr "length_immediate" "0")
9674    (set_attr "mode" "QI")])
9675
9676 (define_insn "*iorqi_ext_1_rex64"
9677   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9678                          (const_int 8)
9679                          (const_int 8))
9680         (ior:SI
9681           (zero_extract:SI
9682             (match_operand 1 "ext_register_operand" "0")
9683             (const_int 8)
9684             (const_int 8))
9685           (zero_extend:SI
9686             (match_operand 2 "ext_register_operand" "Q"))))
9687    (clobber (reg:CC FLAGS_REG))]
9688   "TARGET_64BIT
9689    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9690   "or{b}\t{%2, %h0|%h0, %2}"
9691   [(set_attr "type" "alu")
9692    (set_attr "length_immediate" "0")
9693    (set_attr "mode" "QI")])
9694
9695 (define_insn "*iorqi_ext_2"
9696   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9697                          (const_int 8)
9698                          (const_int 8))
9699         (ior:SI
9700           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9701                            (const_int 8)
9702                            (const_int 8))
9703           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9704                            (const_int 8)
9705                            (const_int 8))))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9708   "ior{b}\t{%h2, %h0|%h0, %h2}"
9709   [(set_attr "type" "alu")
9710    (set_attr "length_immediate" "0")
9711    (set_attr "mode" "QI")])
9712
9713 (define_split
9714   [(set (match_operand 0 "register_operand" "")
9715         (ior (match_operand 1 "register_operand" "")
9716              (match_operand 2 "const_int_operand" "")))
9717    (clobber (reg:CC FLAGS_REG))]
9718    "reload_completed
9719     && QI_REG_P (operands[0])
9720     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9721     && !(INTVAL (operands[2]) & ~(255 << 8))
9722     && GET_MODE (operands[0]) != QImode"
9723   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9724                    (ior:SI (zero_extract:SI (match_dup 1)
9725                                             (const_int 8) (const_int 8))
9726                            (match_dup 2)))
9727               (clobber (reg:CC FLAGS_REG))])]
9728   "operands[0] = gen_lowpart (SImode, operands[0]);
9729    operands[1] = gen_lowpart (SImode, operands[1]);
9730    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9731
9732 ;; Since OR can be encoded with sign extended immediate, this is only
9733 ;; profitable when 7th bit is set.
9734 (define_split
9735   [(set (match_operand 0 "register_operand" "")
9736         (ior (match_operand 1 "general_operand" "")
9737              (match_operand 2 "const_int_operand" "")))
9738    (clobber (reg:CC FLAGS_REG))]
9739    "reload_completed
9740     && ANY_QI_REG_P (operands[0])
9741     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9742     && !(INTVAL (operands[2]) & ~255)
9743     && (INTVAL (operands[2]) & 128)
9744     && GET_MODE (operands[0]) != QImode"
9745   [(parallel [(set (strict_low_part (match_dup 0))
9746                    (ior:QI (match_dup 1)
9747                            (match_dup 2)))
9748               (clobber (reg:CC FLAGS_REG))])]
9749   "operands[0] = gen_lowpart (QImode, operands[0]);
9750    operands[1] = gen_lowpart (QImode, operands[1]);
9751    operands[2] = gen_lowpart (QImode, operands[2]);")
9752 \f
9753 ;; Logical XOR instructions
9754
9755 ;; %%% This used to optimize known byte-wide and operations to memory.
9756 ;; If this is considered useful, it should be done with splitters.
9757
9758 (define_expand "xordi3"
9759   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9760         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9761                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9762   "TARGET_64BIT"
9763   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9764
9765 (define_insn "*xordi_1_rex64"
9766   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9767         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9768                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9769    (clobber (reg:CC FLAGS_REG))]
9770   "TARGET_64BIT
9771    && ix86_binary_operator_ok (XOR, DImode, operands)"
9772   "xor{q}\t{%2, %0|%0, %2}"
9773   [(set_attr "type" "alu")
9774    (set_attr "mode" "DI")])
9775
9776 (define_insn "*xordi_2_rex64"
9777   [(set (reg FLAGS_REG)
9778         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9779                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9780                  (const_int 0)))
9781    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9782         (xor:DI (match_dup 1) (match_dup 2)))]
9783   "TARGET_64BIT
9784    && ix86_match_ccmode (insn, CCNOmode)
9785    && ix86_binary_operator_ok (XOR, DImode, operands)"
9786   "xor{q}\t{%2, %0|%0, %2}"
9787   [(set_attr "type" "alu")
9788    (set_attr "mode" "DI")])
9789
9790 (define_insn "*xordi_3_rex64"
9791   [(set (reg FLAGS_REG)
9792         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9793                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9794                  (const_int 0)))
9795    (clobber (match_scratch:DI 0 "=r"))]
9796   "TARGET_64BIT
9797    && ix86_match_ccmode (insn, CCNOmode)
9798    && ix86_binary_operator_ok (XOR, DImode, operands)"
9799   "xor{q}\t{%2, %0|%0, %2}"
9800   [(set_attr "type" "alu")
9801    (set_attr "mode" "DI")])
9802
9803 (define_expand "xorsi3"
9804   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9805         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9806                 (match_operand:SI 2 "general_operand" "")))]
9807   ""
9808   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9809
9810 (define_insn "*xorsi_1"
9811   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9812         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9813                 (match_operand:SI 2 "general_operand" "ri,rm")))
9814    (clobber (reg:CC FLAGS_REG))]
9815   "ix86_binary_operator_ok (XOR, SImode, operands)"
9816   "xor{l}\t{%2, %0|%0, %2}"
9817   [(set_attr "type" "alu")
9818    (set_attr "mode" "SI")])
9819
9820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9821 ;; Add speccase for immediates
9822 (define_insn "*xorsi_1_zext"
9823   [(set (match_operand:DI 0 "register_operand" "=r")
9824         (zero_extend:DI
9825           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9826                   (match_operand:SI 2 "general_operand" "g"))))
9827    (clobber (reg:CC FLAGS_REG))]
9828   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9829   "xor{l}\t{%2, %k0|%k0, %2}"
9830   [(set_attr "type" "alu")
9831    (set_attr "mode" "SI")])
9832
9833 (define_insn "*xorsi_1_zext_imm"
9834   [(set (match_operand:DI 0 "register_operand" "=r")
9835         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9836                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9839   "xor{l}\t{%2, %k0|%k0, %2}"
9840   [(set_attr "type" "alu")
9841    (set_attr "mode" "SI")])
9842
9843 (define_insn "*xorsi_2"
9844   [(set (reg FLAGS_REG)
9845         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9846                          (match_operand:SI 2 "general_operand" "g,ri"))
9847                  (const_int 0)))
9848    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9849         (xor:SI (match_dup 1) (match_dup 2)))]
9850   "ix86_match_ccmode (insn, CCNOmode)
9851    && ix86_binary_operator_ok (XOR, SImode, operands)"
9852   "xor{l}\t{%2, %0|%0, %2}"
9853   [(set_attr "type" "alu")
9854    (set_attr "mode" "SI")])
9855
9856 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9857 ;; ??? Special case for immediate operand is missing - it is tricky.
9858 (define_insn "*xorsi_2_zext"
9859   [(set (reg FLAGS_REG)
9860         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9861                          (match_operand:SI 2 "general_operand" "g"))
9862                  (const_int 0)))
9863    (set (match_operand:DI 0 "register_operand" "=r")
9864         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9865   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9866    && ix86_binary_operator_ok (XOR, SImode, operands)"
9867   "xor{l}\t{%2, %k0|%k0, %2}"
9868   [(set_attr "type" "alu")
9869    (set_attr "mode" "SI")])
9870
9871 (define_insn "*xorsi_2_zext_imm"
9872   [(set (reg FLAGS_REG)
9873         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9874                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9875                  (const_int 0)))
9876    (set (match_operand:DI 0 "register_operand" "=r")
9877         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9878   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9879    && ix86_binary_operator_ok (XOR, SImode, operands)"
9880   "xor{l}\t{%2, %k0|%k0, %2}"
9881   [(set_attr "type" "alu")
9882    (set_attr "mode" "SI")])
9883
9884 (define_insn "*xorsi_3"
9885   [(set (reg FLAGS_REG)
9886         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9887                          (match_operand:SI 2 "general_operand" "g"))
9888                  (const_int 0)))
9889    (clobber (match_scratch:SI 0 "=r"))]
9890   "ix86_match_ccmode (insn, CCNOmode)
9891    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9892   "xor{l}\t{%2, %0|%0, %2}"
9893   [(set_attr "type" "alu")
9894    (set_attr "mode" "SI")])
9895
9896 (define_expand "xorhi3"
9897   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9898         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9899                 (match_operand:HI 2 "general_operand" "")))]
9900   "TARGET_HIMODE_MATH"
9901   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9902
9903 (define_insn "*xorhi_1"
9904   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9905         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9906                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "ix86_binary_operator_ok (XOR, HImode, operands)"
9909   "xor{w}\t{%2, %0|%0, %2}"
9910   [(set_attr "type" "alu")
9911    (set_attr "mode" "HI")])
9912
9913 (define_insn "*xorhi_2"
9914   [(set (reg FLAGS_REG)
9915         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9916                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9917                  (const_int 0)))
9918    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9919         (xor:HI (match_dup 1) (match_dup 2)))]
9920   "ix86_match_ccmode (insn, CCNOmode)
9921    && ix86_binary_operator_ok (XOR, HImode, operands)"
9922   "xor{w}\t{%2, %0|%0, %2}"
9923   [(set_attr "type" "alu")
9924    (set_attr "mode" "HI")])
9925
9926 (define_insn "*xorhi_3"
9927   [(set (reg FLAGS_REG)
9928         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9929                          (match_operand:HI 2 "general_operand" "rmn"))
9930                  (const_int 0)))
9931    (clobber (match_scratch:HI 0 "=r"))]
9932   "ix86_match_ccmode (insn, CCNOmode)
9933    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9934   "xor{w}\t{%2, %0|%0, %2}"
9935   [(set_attr "type" "alu")
9936    (set_attr "mode" "HI")])
9937
9938 (define_expand "xorqi3"
9939   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9940         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9941                 (match_operand:QI 2 "general_operand" "")))]
9942   "TARGET_QIMODE_MATH"
9943   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9944
9945 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9946 (define_insn "*xorqi_1"
9947   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9948         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9949                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9950    (clobber (reg:CC FLAGS_REG))]
9951   "ix86_binary_operator_ok (XOR, QImode, operands)"
9952   "@
9953    xor{b}\t{%2, %0|%0, %2}
9954    xor{b}\t{%2, %0|%0, %2}
9955    xor{l}\t{%k2, %k0|%k0, %k2}"
9956   [(set_attr "type" "alu")
9957    (set_attr "mode" "QI,QI,SI")])
9958
9959 (define_insn "*xorqi_1_slp"
9960   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9961         (xor:QI (match_dup 0)
9962                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9963    (clobber (reg:CC FLAGS_REG))]
9964   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9965    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9966   "xor{b}\t{%1, %0|%0, %1}"
9967   [(set_attr "type" "alu1")
9968    (set_attr "mode" "QI")])
9969
9970 (define_insn "*xorqi_ext_0"
9971   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9972                          (const_int 8)
9973                          (const_int 8))
9974         (xor:SI
9975           (zero_extract:SI
9976             (match_operand 1 "ext_register_operand" "0")
9977             (const_int 8)
9978             (const_int 8))
9979           (match_operand 2 "const_int_operand" "n")))
9980    (clobber (reg:CC FLAGS_REG))]
9981   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9982   "xor{b}\t{%2, %h0|%h0, %2}"
9983   [(set_attr "type" "alu")
9984    (set_attr "length_immediate" "1")
9985    (set_attr "modrm" "1")
9986    (set_attr "mode" "QI")])
9987
9988 (define_insn "*xorqi_ext_1"
9989   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9990                          (const_int 8)
9991                          (const_int 8))
9992         (xor:SI
9993           (zero_extract:SI
9994             (match_operand 1 "ext_register_operand" "0")
9995             (const_int 8)
9996             (const_int 8))
9997           (zero_extend:SI
9998             (match_operand:QI 2 "general_operand" "Qm"))))
9999    (clobber (reg:CC FLAGS_REG))]
10000   "!TARGET_64BIT
10001    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10002   "xor{b}\t{%2, %h0|%h0, %2}"
10003   [(set_attr "type" "alu")
10004    (set_attr "length_immediate" "0")
10005    (set_attr "mode" "QI")])
10006
10007 (define_insn "*xorqi_ext_1_rex64"
10008   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10009                          (const_int 8)
10010                          (const_int 8))
10011         (xor:SI
10012           (zero_extract:SI
10013             (match_operand 1 "ext_register_operand" "0")
10014             (const_int 8)
10015             (const_int 8))
10016           (zero_extend:SI
10017             (match_operand 2 "ext_register_operand" "Q"))))
10018    (clobber (reg:CC FLAGS_REG))]
10019   "TARGET_64BIT
10020    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10021   "xor{b}\t{%2, %h0|%h0, %2}"
10022   [(set_attr "type" "alu")
10023    (set_attr "length_immediate" "0")
10024    (set_attr "mode" "QI")])
10025
10026 (define_insn "*xorqi_ext_2"
10027   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10028                          (const_int 8)
10029                          (const_int 8))
10030         (xor:SI
10031           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10032                            (const_int 8)
10033                            (const_int 8))
10034           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10035                            (const_int 8)
10036                            (const_int 8))))
10037    (clobber (reg:CC FLAGS_REG))]
10038   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10039   "xor{b}\t{%h2, %h0|%h0, %h2}"
10040   [(set_attr "type" "alu")
10041    (set_attr "length_immediate" "0")
10042    (set_attr "mode" "QI")])
10043
10044 (define_insn "*xorqi_cc_1"
10045   [(set (reg FLAGS_REG)
10046         (compare
10047           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10048                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10049           (const_int 0)))
10050    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10051         (xor:QI (match_dup 1) (match_dup 2)))]
10052   "ix86_match_ccmode (insn, CCNOmode)
10053    && ix86_binary_operator_ok (XOR, QImode, operands)"
10054   "xor{b}\t{%2, %0|%0, %2}"
10055   [(set_attr "type" "alu")
10056    (set_attr "mode" "QI")])
10057
10058 (define_insn "*xorqi_2_slp"
10059   [(set (reg FLAGS_REG)
10060         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10061                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10062                  (const_int 0)))
10063    (set (strict_low_part (match_dup 0))
10064         (xor:QI (match_dup 0) (match_dup 1)))]
10065   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10066    && ix86_match_ccmode (insn, CCNOmode)
10067    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10068   "xor{b}\t{%1, %0|%0, %1}"
10069   [(set_attr "type" "alu1")
10070    (set_attr "mode" "QI")])
10071
10072 (define_insn "*xorqi_cc_2"
10073   [(set (reg FLAGS_REG)
10074         (compare
10075           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10076                   (match_operand:QI 2 "general_operand" "qmn"))
10077           (const_int 0)))
10078    (clobber (match_scratch:QI 0 "=q"))]
10079   "ix86_match_ccmode (insn, CCNOmode)
10080    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10081   "xor{b}\t{%2, %0|%0, %2}"
10082   [(set_attr "type" "alu")
10083    (set_attr "mode" "QI")])
10084
10085 (define_insn "*xorqi_cc_ext_1"
10086   [(set (reg FLAGS_REG)
10087         (compare
10088           (xor:SI
10089             (zero_extract:SI
10090               (match_operand 1 "ext_register_operand" "0")
10091               (const_int 8)
10092               (const_int 8))
10093             (match_operand:QI 2 "general_operand" "qmn"))
10094           (const_int 0)))
10095    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10096                          (const_int 8)
10097                          (const_int 8))
10098         (xor:SI
10099           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10100           (match_dup 2)))]
10101   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10102   "xor{b}\t{%2, %h0|%h0, %2}"
10103   [(set_attr "type" "alu")
10104    (set_attr "modrm" "1")
10105    (set_attr "mode" "QI")])
10106
10107 (define_insn "*xorqi_cc_ext_1_rex64"
10108   [(set (reg FLAGS_REG)
10109         (compare
10110           (xor:SI
10111             (zero_extract:SI
10112               (match_operand 1 "ext_register_operand" "0")
10113               (const_int 8)
10114               (const_int 8))
10115             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10116           (const_int 0)))
10117    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10118                          (const_int 8)
10119                          (const_int 8))
10120         (xor:SI
10121           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10122           (match_dup 2)))]
10123   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10124   "xor{b}\t{%2, %h0|%h0, %2}"
10125   [(set_attr "type" "alu")
10126    (set_attr "modrm" "1")
10127    (set_attr "mode" "QI")])
10128
10129 (define_expand "xorqi_cc_ext_1"
10130   [(parallel [
10131      (set (reg:CCNO FLAGS_REG)
10132           (compare:CCNO
10133             (xor:SI
10134               (zero_extract:SI
10135                 (match_operand 1 "ext_register_operand" "")
10136                 (const_int 8)
10137                 (const_int 8))
10138               (match_operand:QI 2 "general_operand" ""))
10139             (const_int 0)))
10140      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10141                            (const_int 8)
10142                            (const_int 8))
10143           (xor:SI
10144             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10145             (match_dup 2)))])]
10146   ""
10147   "")
10148
10149 (define_split
10150   [(set (match_operand 0 "register_operand" "")
10151         (xor (match_operand 1 "register_operand" "")
10152              (match_operand 2 "const_int_operand" "")))
10153    (clobber (reg:CC FLAGS_REG))]
10154    "reload_completed
10155     && QI_REG_P (operands[0])
10156     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10157     && !(INTVAL (operands[2]) & ~(255 << 8))
10158     && GET_MODE (operands[0]) != QImode"
10159   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10160                    (xor:SI (zero_extract:SI (match_dup 1)
10161                                             (const_int 8) (const_int 8))
10162                            (match_dup 2)))
10163               (clobber (reg:CC FLAGS_REG))])]
10164   "operands[0] = gen_lowpart (SImode, operands[0]);
10165    operands[1] = gen_lowpart (SImode, operands[1]);
10166    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10167
10168 ;; Since XOR can be encoded with sign extended immediate, this is only
10169 ;; profitable when 7th bit is set.
10170 (define_split
10171   [(set (match_operand 0 "register_operand" "")
10172         (xor (match_operand 1 "general_operand" "")
10173              (match_operand 2 "const_int_operand" "")))
10174    (clobber (reg:CC FLAGS_REG))]
10175    "reload_completed
10176     && ANY_QI_REG_P (operands[0])
10177     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10178     && !(INTVAL (operands[2]) & ~255)
10179     && (INTVAL (operands[2]) & 128)
10180     && GET_MODE (operands[0]) != QImode"
10181   [(parallel [(set (strict_low_part (match_dup 0))
10182                    (xor:QI (match_dup 1)
10183                            (match_dup 2)))
10184               (clobber (reg:CC FLAGS_REG))])]
10185   "operands[0] = gen_lowpart (QImode, operands[0]);
10186    operands[1] = gen_lowpart (QImode, operands[1]);
10187    operands[2] = gen_lowpart (QImode, operands[2]);")
10188 \f
10189 ;; Negation instructions
10190
10191 (define_expand "negti2"
10192   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10193         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10194   "TARGET_64BIT"
10195   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10196
10197 (define_insn "*negti2_1"
10198   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10199         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10200    (clobber (reg:CC FLAGS_REG))]
10201   "TARGET_64BIT
10202    && ix86_unary_operator_ok (NEG, TImode, operands)"
10203   "#")
10204
10205 (define_split
10206   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10207         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10208    (clobber (reg:CC FLAGS_REG))]
10209   "TARGET_64BIT && reload_completed"
10210   [(parallel
10211     [(set (reg:CCZ FLAGS_REG)
10212           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10213      (set (match_dup 0) (neg:DI (match_dup 1)))])
10214    (parallel
10215     [(set (match_dup 2)
10216           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10217                             (match_dup 3))
10218                    (const_int 0)))
10219      (clobber (reg:CC FLAGS_REG))])
10220    (parallel
10221     [(set (match_dup 2)
10222           (neg:DI (match_dup 2)))
10223      (clobber (reg:CC FLAGS_REG))])]
10224   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10225
10226 (define_expand "negdi2"
10227   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10228         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10229   ""
10230   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10231
10232 (define_insn "*negdi2_1"
10233   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10234         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10235    (clobber (reg:CC FLAGS_REG))]
10236   "!TARGET_64BIT
10237    && ix86_unary_operator_ok (NEG, DImode, operands)"
10238   "#")
10239
10240 (define_split
10241   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10242         (neg:DI (match_operand:DI 1 "general_operand" "")))
10243    (clobber (reg:CC FLAGS_REG))]
10244   "!TARGET_64BIT && reload_completed"
10245   [(parallel
10246     [(set (reg:CCZ FLAGS_REG)
10247           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10248      (set (match_dup 0) (neg:SI (match_dup 1)))])
10249    (parallel
10250     [(set (match_dup 2)
10251           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10252                             (match_dup 3))
10253                    (const_int 0)))
10254      (clobber (reg:CC FLAGS_REG))])
10255    (parallel
10256     [(set (match_dup 2)
10257           (neg:SI (match_dup 2)))
10258      (clobber (reg:CC FLAGS_REG))])]
10259   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10260
10261 (define_insn "*negdi2_1_rex64"
10262   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10263         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10264    (clobber (reg:CC FLAGS_REG))]
10265   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10266   "neg{q}\t%0"
10267   [(set_attr "type" "negnot")
10268    (set_attr "mode" "DI")])
10269
10270 ;; The problem with neg is that it does not perform (compare x 0),
10271 ;; it really performs (compare 0 x), which leaves us with the zero
10272 ;; flag being the only useful item.
10273
10274 (define_insn "*negdi2_cmpz_rex64"
10275   [(set (reg:CCZ FLAGS_REG)
10276         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10277                      (const_int 0)))
10278    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10279         (neg:DI (match_dup 1)))]
10280   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10281   "neg{q}\t%0"
10282   [(set_attr "type" "negnot")
10283    (set_attr "mode" "DI")])
10284
10285
10286 (define_expand "negsi2"
10287   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10288         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10289   ""
10290   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10291
10292 (define_insn "*negsi2_1"
10293   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10294         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10295    (clobber (reg:CC FLAGS_REG))]
10296   "ix86_unary_operator_ok (NEG, SImode, operands)"
10297   "neg{l}\t%0"
10298   [(set_attr "type" "negnot")
10299    (set_attr "mode" "SI")])
10300
10301 ;; Combine is quite creative about this pattern.
10302 (define_insn "*negsi2_1_zext"
10303   [(set (match_operand:DI 0 "register_operand" "=r")
10304         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10305                                         (const_int 32)))
10306                      (const_int 32)))
10307    (clobber (reg:CC FLAGS_REG))]
10308   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10309   "neg{l}\t%k0"
10310   [(set_attr "type" "negnot")
10311    (set_attr "mode" "SI")])
10312
10313 ;; The problem with neg is that it does not perform (compare x 0),
10314 ;; it really performs (compare 0 x), which leaves us with the zero
10315 ;; flag being the only useful item.
10316
10317 (define_insn "*negsi2_cmpz"
10318   [(set (reg:CCZ FLAGS_REG)
10319         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10320                      (const_int 0)))
10321    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10322         (neg:SI (match_dup 1)))]
10323   "ix86_unary_operator_ok (NEG, SImode, operands)"
10324   "neg{l}\t%0"
10325   [(set_attr "type" "negnot")
10326    (set_attr "mode" "SI")])
10327
10328 (define_insn "*negsi2_cmpz_zext"
10329   [(set (reg:CCZ FLAGS_REG)
10330         (compare:CCZ (lshiftrt:DI
10331                        (neg:DI (ashift:DI
10332                                  (match_operand:DI 1 "register_operand" "0")
10333                                  (const_int 32)))
10334                        (const_int 32))
10335                      (const_int 0)))
10336    (set (match_operand:DI 0 "register_operand" "=r")
10337         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10338                                         (const_int 32)))
10339                      (const_int 32)))]
10340   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10341   "neg{l}\t%k0"
10342   [(set_attr "type" "negnot")
10343    (set_attr "mode" "SI")])
10344
10345 (define_expand "neghi2"
10346   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10347         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10348   "TARGET_HIMODE_MATH"
10349   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10350
10351 (define_insn "*neghi2_1"
10352   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10353         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10354    (clobber (reg:CC FLAGS_REG))]
10355   "ix86_unary_operator_ok (NEG, HImode, operands)"
10356   "neg{w}\t%0"
10357   [(set_attr "type" "negnot")
10358    (set_attr "mode" "HI")])
10359
10360 (define_insn "*neghi2_cmpz"
10361   [(set (reg:CCZ FLAGS_REG)
10362         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10363                      (const_int 0)))
10364    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10365         (neg:HI (match_dup 1)))]
10366   "ix86_unary_operator_ok (NEG, HImode, operands)"
10367   "neg{w}\t%0"
10368   [(set_attr "type" "negnot")
10369    (set_attr "mode" "HI")])
10370
10371 (define_expand "negqi2"
10372   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10373         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10374   "TARGET_QIMODE_MATH"
10375   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10376
10377 (define_insn "*negqi2_1"
10378   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10379         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10380    (clobber (reg:CC FLAGS_REG))]
10381   "ix86_unary_operator_ok (NEG, QImode, operands)"
10382   "neg{b}\t%0"
10383   [(set_attr "type" "negnot")
10384    (set_attr "mode" "QI")])
10385
10386 (define_insn "*negqi2_cmpz"
10387   [(set (reg:CCZ FLAGS_REG)
10388         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10389                      (const_int 0)))
10390    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10391         (neg:QI (match_dup 1)))]
10392   "ix86_unary_operator_ok (NEG, QImode, operands)"
10393   "neg{b}\t%0"
10394   [(set_attr "type" "negnot")
10395    (set_attr "mode" "QI")])
10396
10397 ;; Changing of sign for FP values is doable using integer unit too.
10398
10399 (define_expand "<code><mode>2"
10400   [(set (match_operand:X87MODEF 0 "register_operand" "")
10401         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10402   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10403   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10404
10405 (define_insn "*absneg<mode>2_mixed"
10406   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10407         (match_operator:MODEF 3 "absneg_operator"
10408           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10409    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10410    (clobber (reg:CC FLAGS_REG))]
10411   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10412   "#")
10413
10414 (define_insn "*absneg<mode>2_sse"
10415   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10416         (match_operator:MODEF 3 "absneg_operator"
10417           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10418    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10421   "#")
10422
10423 (define_insn "*absneg<mode>2_i387"
10424   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10425         (match_operator:X87MODEF 3 "absneg_operator"
10426           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10427    (use (match_operand 2 "" ""))
10428    (clobber (reg:CC FLAGS_REG))]
10429   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10430   "#")
10431
10432 (define_expand "<code>tf2"
10433   [(set (match_operand:TF 0 "register_operand" "")
10434         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10435   "TARGET_SSE2"
10436   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10437
10438 (define_insn "*absnegtf2_sse"
10439   [(set (match_operand:TF 0 "register_operand" "=x,x")
10440         (match_operator:TF 3 "absneg_operator"
10441           [(match_operand:TF 1 "register_operand" "0,x")]))
10442    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10443    (clobber (reg:CC FLAGS_REG))]
10444   "TARGET_SSE2"
10445   "#")
10446
10447 ;; Splitters for fp abs and neg.
10448
10449 (define_split
10450   [(set (match_operand 0 "fp_register_operand" "")
10451         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10452    (use (match_operand 2 "" ""))
10453    (clobber (reg:CC FLAGS_REG))]
10454   "reload_completed"
10455   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10456
10457 (define_split
10458   [(set (match_operand 0 "register_operand" "")
10459         (match_operator 3 "absneg_operator"
10460           [(match_operand 1 "register_operand" "")]))
10461    (use (match_operand 2 "nonimmediate_operand" ""))
10462    (clobber (reg:CC FLAGS_REG))]
10463   "reload_completed && SSE_REG_P (operands[0])"
10464   [(set (match_dup 0) (match_dup 3))]
10465 {
10466   enum machine_mode mode = GET_MODE (operands[0]);
10467   enum machine_mode vmode = GET_MODE (operands[2]);
10468   rtx tmp;
10469
10470   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10471   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10472   if (operands_match_p (operands[0], operands[2]))
10473     {
10474       tmp = operands[1];
10475       operands[1] = operands[2];
10476       operands[2] = tmp;
10477     }
10478   if (GET_CODE (operands[3]) == ABS)
10479     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10480   else
10481     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10482   operands[3] = tmp;
10483 })
10484
10485 (define_split
10486   [(set (match_operand:SF 0 "register_operand" "")
10487         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10488    (use (match_operand:V4SF 2 "" ""))
10489    (clobber (reg:CC FLAGS_REG))]
10490   "reload_completed"
10491   [(parallel [(set (match_dup 0) (match_dup 1))
10492               (clobber (reg:CC FLAGS_REG))])]
10493 {
10494   rtx tmp;
10495   operands[0] = gen_lowpart (SImode, operands[0]);
10496   if (GET_CODE (operands[1]) == ABS)
10497     {
10498       tmp = gen_int_mode (0x7fffffff, SImode);
10499       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10500     }
10501   else
10502     {
10503       tmp = gen_int_mode (0x80000000, SImode);
10504       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10505     }
10506   operands[1] = tmp;
10507 })
10508
10509 (define_split
10510   [(set (match_operand:DF 0 "register_operand" "")
10511         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10512    (use (match_operand 2 "" ""))
10513    (clobber (reg:CC FLAGS_REG))]
10514   "reload_completed"
10515   [(parallel [(set (match_dup 0) (match_dup 1))
10516               (clobber (reg:CC FLAGS_REG))])]
10517 {
10518   rtx tmp;
10519   if (TARGET_64BIT)
10520     {
10521       tmp = gen_lowpart (DImode, operands[0]);
10522       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10523       operands[0] = tmp;
10524
10525       if (GET_CODE (operands[1]) == ABS)
10526         tmp = const0_rtx;
10527       else
10528         tmp = gen_rtx_NOT (DImode, tmp);
10529     }
10530   else
10531     {
10532       operands[0] = gen_highpart (SImode, operands[0]);
10533       if (GET_CODE (operands[1]) == ABS)
10534         {
10535           tmp = gen_int_mode (0x7fffffff, SImode);
10536           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10537         }
10538       else
10539         {
10540           tmp = gen_int_mode (0x80000000, SImode);
10541           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10542         }
10543     }
10544   operands[1] = tmp;
10545 })
10546
10547 (define_split
10548   [(set (match_operand:XF 0 "register_operand" "")
10549         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10550    (use (match_operand 2 "" ""))
10551    (clobber (reg:CC FLAGS_REG))]
10552   "reload_completed"
10553   [(parallel [(set (match_dup 0) (match_dup 1))
10554               (clobber (reg:CC FLAGS_REG))])]
10555 {
10556   rtx tmp;
10557   operands[0] = gen_rtx_REG (SImode,
10558                              true_regnum (operands[0])
10559                              + (TARGET_64BIT ? 1 : 2));
10560   if (GET_CODE (operands[1]) == ABS)
10561     {
10562       tmp = GEN_INT (0x7fff);
10563       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10564     }
10565   else
10566     {
10567       tmp = GEN_INT (0x8000);
10568       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10569     }
10570   operands[1] = tmp;
10571 })
10572
10573 ;; Conditionalize these after reload. If they match before reload, we
10574 ;; lose the clobber and ability to use integer instructions.
10575
10576 (define_insn "*<code><mode>2_1"
10577   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10578         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10579   "TARGET_80387
10580    && (reload_completed
10581        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10582   "f<absnegprefix>"
10583   [(set_attr "type" "fsgn")
10584    (set_attr "mode" "<MODE>")])
10585
10586 (define_insn "*<code>extendsfdf2"
10587   [(set (match_operand:DF 0 "register_operand" "=f")
10588         (absneg:DF (float_extend:DF
10589                      (match_operand:SF 1 "register_operand" "0"))))]
10590   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10591   "f<absnegprefix>"
10592   [(set_attr "type" "fsgn")
10593    (set_attr "mode" "DF")])
10594
10595 (define_insn "*<code>extendsfxf2"
10596   [(set (match_operand:XF 0 "register_operand" "=f")
10597         (absneg:XF (float_extend:XF
10598                      (match_operand:SF 1 "register_operand" "0"))))]
10599   "TARGET_80387"
10600   "f<absnegprefix>"
10601   [(set_attr "type" "fsgn")
10602    (set_attr "mode" "XF")])
10603
10604 (define_insn "*<code>extenddfxf2"
10605   [(set (match_operand:XF 0 "register_operand" "=f")
10606         (absneg:XF (float_extend:XF
10607                       (match_operand:DF 1 "register_operand" "0"))))]
10608   "TARGET_80387"
10609   "f<absnegprefix>"
10610   [(set_attr "type" "fsgn")
10611    (set_attr "mode" "XF")])
10612
10613 ;; Copysign instructions
10614
10615 (define_mode_iterator CSGNMODE [SF DF TF])
10616 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10617
10618 (define_expand "copysign<mode>3"
10619   [(match_operand:CSGNMODE 0 "register_operand" "")
10620    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10621    (match_operand:CSGNMODE 2 "register_operand" "")]
10622   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10623    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10624 {
10625   ix86_expand_copysign (operands);
10626   DONE;
10627 })
10628
10629 (define_insn_and_split "copysign<mode>3_const"
10630   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10631         (unspec:CSGNMODE
10632           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10633            (match_operand:CSGNMODE 2 "register_operand" "0")
10634            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10635           UNSPEC_COPYSIGN))]
10636   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10637    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10638   "#"
10639   "&& reload_completed"
10640   [(const_int 0)]
10641 {
10642   ix86_split_copysign_const (operands);
10643   DONE;
10644 })
10645
10646 (define_insn "copysign<mode>3_var"
10647   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10648         (unspec:CSGNMODE
10649           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10650            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10651            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10652            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10653           UNSPEC_COPYSIGN))
10654    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10655   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10656    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10657   "#")
10658
10659 (define_split
10660   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10661         (unspec:CSGNMODE
10662           [(match_operand:CSGNMODE 2 "register_operand" "")
10663            (match_operand:CSGNMODE 3 "register_operand" "")
10664            (match_operand:<CSGNVMODE> 4 "" "")
10665            (match_operand:<CSGNVMODE> 5 "" "")]
10666           UNSPEC_COPYSIGN))
10667    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10668   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10669     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10670    && reload_completed"
10671   [(const_int 0)]
10672 {
10673   ix86_split_copysign_var (operands);
10674   DONE;
10675 })
10676 \f
10677 ;; One complement instructions
10678
10679 (define_expand "one_cmpldi2"
10680   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10681         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10682   "TARGET_64BIT"
10683   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10684
10685 (define_insn "*one_cmpldi2_1_rex64"
10686   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10687         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10688   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10689   "not{q}\t%0"
10690   [(set_attr "type" "negnot")
10691    (set_attr "mode" "DI")])
10692
10693 (define_insn "*one_cmpldi2_2_rex64"
10694   [(set (reg FLAGS_REG)
10695         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10696                  (const_int 0)))
10697    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10698         (not:DI (match_dup 1)))]
10699   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10700    && ix86_unary_operator_ok (NOT, DImode, operands)"
10701   "#"
10702   [(set_attr "type" "alu1")
10703    (set_attr "mode" "DI")])
10704
10705 (define_split
10706   [(set (match_operand 0 "flags_reg_operand" "")
10707         (match_operator 2 "compare_operator"
10708           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10709            (const_int 0)]))
10710    (set (match_operand:DI 1 "nonimmediate_operand" "")
10711         (not:DI (match_dup 3)))]
10712   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10713   [(parallel [(set (match_dup 0)
10714                    (match_op_dup 2
10715                      [(xor:DI (match_dup 3) (const_int -1))
10716                       (const_int 0)]))
10717               (set (match_dup 1)
10718                    (xor:DI (match_dup 3) (const_int -1)))])]
10719   "")
10720
10721 (define_expand "one_cmplsi2"
10722   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10723         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10724   ""
10725   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10726
10727 (define_insn "*one_cmplsi2_1"
10728   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10729         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10730   "ix86_unary_operator_ok (NOT, SImode, operands)"
10731   "not{l}\t%0"
10732   [(set_attr "type" "negnot")
10733    (set_attr "mode" "SI")])
10734
10735 ;; ??? Currently never generated - xor is used instead.
10736 (define_insn "*one_cmplsi2_1_zext"
10737   [(set (match_operand:DI 0 "register_operand" "=r")
10738         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10739   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10740   "not{l}\t%k0"
10741   [(set_attr "type" "negnot")
10742    (set_attr "mode" "SI")])
10743
10744 (define_insn "*one_cmplsi2_2"
10745   [(set (reg FLAGS_REG)
10746         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10747                  (const_int 0)))
10748    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10749         (not:SI (match_dup 1)))]
10750   "ix86_match_ccmode (insn, CCNOmode)
10751    && ix86_unary_operator_ok (NOT, SImode, operands)"
10752   "#"
10753   [(set_attr "type" "alu1")
10754    (set_attr "mode" "SI")])
10755
10756 (define_split
10757   [(set (match_operand 0 "flags_reg_operand" "")
10758         (match_operator 2 "compare_operator"
10759           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10760            (const_int 0)]))
10761    (set (match_operand:SI 1 "nonimmediate_operand" "")
10762         (not:SI (match_dup 3)))]
10763   "ix86_match_ccmode (insn, CCNOmode)"
10764   [(parallel [(set (match_dup 0)
10765                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10766                                     (const_int 0)]))
10767               (set (match_dup 1)
10768                    (xor:SI (match_dup 3) (const_int -1)))])]
10769   "")
10770
10771 ;; ??? Currently never generated - xor is used instead.
10772 (define_insn "*one_cmplsi2_2_zext"
10773   [(set (reg FLAGS_REG)
10774         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10775                  (const_int 0)))
10776    (set (match_operand:DI 0 "register_operand" "=r")
10777         (zero_extend:DI (not:SI (match_dup 1))))]
10778   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10779    && ix86_unary_operator_ok (NOT, SImode, operands)"
10780   "#"
10781   [(set_attr "type" "alu1")
10782    (set_attr "mode" "SI")])
10783
10784 (define_split
10785   [(set (match_operand 0 "flags_reg_operand" "")
10786         (match_operator 2 "compare_operator"
10787           [(not:SI (match_operand:SI 3 "register_operand" ""))
10788            (const_int 0)]))
10789    (set (match_operand:DI 1 "register_operand" "")
10790         (zero_extend:DI (not:SI (match_dup 3))))]
10791   "ix86_match_ccmode (insn, CCNOmode)"
10792   [(parallel [(set (match_dup 0)
10793                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10794                                     (const_int 0)]))
10795               (set (match_dup 1)
10796                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10797   "")
10798
10799 (define_expand "one_cmplhi2"
10800   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10801         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10802   "TARGET_HIMODE_MATH"
10803   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10804
10805 (define_insn "*one_cmplhi2_1"
10806   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10807         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10808   "ix86_unary_operator_ok (NOT, HImode, operands)"
10809   "not{w}\t%0"
10810   [(set_attr "type" "negnot")
10811    (set_attr "mode" "HI")])
10812
10813 (define_insn "*one_cmplhi2_2"
10814   [(set (reg FLAGS_REG)
10815         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10816                  (const_int 0)))
10817    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10818         (not:HI (match_dup 1)))]
10819   "ix86_match_ccmode (insn, CCNOmode)
10820    && ix86_unary_operator_ok (NEG, HImode, operands)"
10821   "#"
10822   [(set_attr "type" "alu1")
10823    (set_attr "mode" "HI")])
10824
10825 (define_split
10826   [(set (match_operand 0 "flags_reg_operand" "")
10827         (match_operator 2 "compare_operator"
10828           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10829            (const_int 0)]))
10830    (set (match_operand:HI 1 "nonimmediate_operand" "")
10831         (not:HI (match_dup 3)))]
10832   "ix86_match_ccmode (insn, CCNOmode)"
10833   [(parallel [(set (match_dup 0)
10834                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10835                                     (const_int 0)]))
10836               (set (match_dup 1)
10837                    (xor:HI (match_dup 3) (const_int -1)))])]
10838   "")
10839
10840 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10841 (define_expand "one_cmplqi2"
10842   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10843         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10844   "TARGET_QIMODE_MATH"
10845   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10846
10847 (define_insn "*one_cmplqi2_1"
10848   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10849         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10850   "ix86_unary_operator_ok (NOT, QImode, operands)"
10851   "@
10852    not{b}\t%0
10853    not{l}\t%k0"
10854   [(set_attr "type" "negnot")
10855    (set_attr "mode" "QI,SI")])
10856
10857 (define_insn "*one_cmplqi2_2"
10858   [(set (reg FLAGS_REG)
10859         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10860                  (const_int 0)))
10861    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10862         (not:QI (match_dup 1)))]
10863   "ix86_match_ccmode (insn, CCNOmode)
10864    && ix86_unary_operator_ok (NOT, QImode, operands)"
10865   "#"
10866   [(set_attr "type" "alu1")
10867    (set_attr "mode" "QI")])
10868
10869 (define_split
10870   [(set (match_operand 0 "flags_reg_operand" "")
10871         (match_operator 2 "compare_operator"
10872           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10873            (const_int 0)]))
10874    (set (match_operand:QI 1 "nonimmediate_operand" "")
10875         (not:QI (match_dup 3)))]
10876   "ix86_match_ccmode (insn, CCNOmode)"
10877   [(parallel [(set (match_dup 0)
10878                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10879                                     (const_int 0)]))
10880               (set (match_dup 1)
10881                    (xor:QI (match_dup 3) (const_int -1)))])]
10882   "")
10883 \f
10884 ;; Arithmetic shift instructions
10885
10886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10889 ;; from the assembler input.
10890 ;;
10891 ;; This instruction shifts the target reg/mem as usual, but instead of
10892 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10893 ;; is a left shift double, bits are taken from the high order bits of
10894 ;; reg, else if the insn is a shift right double, bits are taken from the
10895 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10897 ;;
10898 ;; Since sh[lr]d does not change the `reg' operand, that is done
10899 ;; separately, making all shifts emit pairs of shift double and normal
10900 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10901 ;; support a 63 bit shift, each shift where the count is in a reg expands
10902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10903 ;;
10904 ;; If the shift count is a constant, we need never emit more than one
10905 ;; shift pair, instead using moves and sign extension for counts greater
10906 ;; than 31.
10907
10908 (define_expand "ashlti3"
10909   [(set (match_operand:TI 0 "register_operand" "")
10910         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10911                    (match_operand:QI 2 "nonmemory_operand" "")))]
10912   "TARGET_64BIT"
10913   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10914
10915 ;; This pattern must be defined before *ashlti3_1 to prevent
10916 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10917
10918 (define_insn "*avx_ashlti3"
10919   [(set (match_operand:TI 0 "register_operand" "=x")
10920         (ashift:TI (match_operand:TI 1 "register_operand" "x")
10921                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10922   "TARGET_AVX"
10923 {
10924   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10925   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10926 }
10927   [(set_attr "type" "sseishft")
10928    (set_attr "prefix" "vex")
10929    (set_attr "length_immediate" "1")
10930    (set_attr "mode" "TI")])
10931
10932 (define_insn "sse2_ashlti3"
10933   [(set (match_operand:TI 0 "register_operand" "=x")
10934         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10935                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10936   "TARGET_SSE2"
10937 {
10938   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10939   return "pslldq\t{%2, %0|%0, %2}";
10940 }
10941   [(set_attr "type" "sseishft")
10942    (set_attr "prefix_data16" "1")
10943    (set_attr "length_immediate" "1")
10944    (set_attr "mode" "TI")])
10945
10946 (define_insn "*ashlti3_1"
10947   [(set (match_operand:TI 0 "register_operand" "=&r,r")
10948         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10949                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10950    (clobber (reg:CC FLAGS_REG))]
10951   "TARGET_64BIT"
10952   "#"
10953   [(set_attr "type" "multi")])
10954
10955 (define_peephole2
10956   [(match_scratch:DI 3 "r")
10957    (parallel [(set (match_operand:TI 0 "register_operand" "")
10958                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10959                               (match_operand:QI 2 "nonmemory_operand" "")))
10960               (clobber (reg:CC FLAGS_REG))])
10961    (match_dup 3)]
10962   "TARGET_64BIT"
10963   [(const_int 0)]
10964   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10965
10966 (define_split
10967   [(set (match_operand:TI 0 "register_operand" "")
10968         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10969                    (match_operand:QI 2 "nonmemory_operand" "")))
10970    (clobber (reg:CC FLAGS_REG))]
10971   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10972                     ? epilogue_completed : reload_completed)"
10973   [(const_int 0)]
10974   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10975
10976 (define_insn "x86_64_shld"
10977   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10978         (ior:DI (ashift:DI (match_dup 0)
10979                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10980                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10981                   (minus:QI (const_int 64) (match_dup 2)))))
10982    (clobber (reg:CC FLAGS_REG))]
10983   "TARGET_64BIT"
10984   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10985   [(set_attr "type" "ishift")
10986    (set_attr "prefix_0f" "1")
10987    (set_attr "mode" "DI")
10988    (set_attr "athlon_decode" "vector")
10989    (set_attr "amdfam10_decode" "vector")])
10990
10991 (define_expand "x86_64_shift_adj_1"
10992   [(set (reg:CCZ FLAGS_REG)
10993         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10994                              (const_int 64))
10995                      (const_int 0)))
10996    (set (match_operand:DI 0 "register_operand" "")
10997         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10998                          (match_operand:DI 1 "register_operand" "")
10999                          (match_dup 0)))
11000    (set (match_dup 1)
11001         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11002                          (match_operand:DI 3 "register_operand" "r")
11003                          (match_dup 1)))]
11004   "TARGET_64BIT"
11005   "")
11006
11007 (define_expand "x86_64_shift_adj_2"
11008   [(use (match_operand:DI 0 "register_operand" ""))
11009    (use (match_operand:DI 1 "register_operand" ""))
11010    (use (match_operand:QI 2 "register_operand" ""))]
11011   "TARGET_64BIT"
11012 {
11013   rtx label = gen_label_rtx ();
11014   rtx tmp;
11015
11016   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11017
11018   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11019   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11020   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11021                               gen_rtx_LABEL_REF (VOIDmode, label),
11022                               pc_rtx);
11023   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11024   JUMP_LABEL (tmp) = label;
11025
11026   emit_move_insn (operands[0], operands[1]);
11027   ix86_expand_clear (operands[1]);
11028
11029   emit_label (label);
11030   LABEL_NUSES (label) = 1;
11031
11032   DONE;
11033 })
11034
11035 (define_expand "ashldi3"
11036   [(set (match_operand:DI 0 "shiftdi_operand" "")
11037         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11038                    (match_operand:QI 2 "nonmemory_operand" "")))]
11039   ""
11040   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11041
11042 (define_insn "*ashldi3_1_rex64"
11043   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11044         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11045                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11046    (clobber (reg:CC FLAGS_REG))]
11047   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11048 {
11049   switch (get_attr_type (insn))
11050     {
11051     case TYPE_ALU:
11052       gcc_assert (operands[2] == const1_rtx);
11053       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11054       return "add{q}\t%0, %0";
11055
11056     case TYPE_LEA:
11057       gcc_assert (CONST_INT_P (operands[2]));
11058       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11059       operands[1] = gen_rtx_MULT (DImode, operands[1],
11060                                   GEN_INT (1 << INTVAL (operands[2])));
11061       return "lea{q}\t{%a1, %0|%0, %a1}";
11062
11063     default:
11064       if (REG_P (operands[2]))
11065         return "sal{q}\t{%b2, %0|%0, %b2}";
11066       else if (operands[2] == const1_rtx
11067                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11068         return "sal{q}\t%0";
11069       else
11070         return "sal{q}\t{%2, %0|%0, %2}";
11071     }
11072 }
11073   [(set (attr "type")
11074      (cond [(eq_attr "alternative" "1")
11075               (const_string "lea")
11076             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11077                           (const_int 0))
11078                       (match_operand 0 "register_operand" ""))
11079                  (match_operand 2 "const1_operand" ""))
11080               (const_string "alu")
11081            ]
11082            (const_string "ishift")))
11083    (set (attr "length_immediate")
11084      (if_then_else
11085        (ior (eq_attr "type" "alu")
11086             (and (eq_attr "type" "ishift")
11087                  (and (match_operand 2 "const1_operand" "")
11088                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11089                           (const_int 0)))))
11090        (const_string "0")
11091        (const_string "*")))
11092    (set_attr "mode" "DI")])
11093
11094 ;; Convert lea to the lea pattern to avoid flags dependency.
11095 (define_split
11096   [(set (match_operand:DI 0 "register_operand" "")
11097         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11098                    (match_operand:QI 2 "immediate_operand" "")))
11099    (clobber (reg:CC FLAGS_REG))]
11100   "TARGET_64BIT && reload_completed
11101    && true_regnum (operands[0]) != true_regnum (operands[1])"
11102   [(set (match_dup 0)
11103         (mult:DI (match_dup 1)
11104                  (match_dup 2)))]
11105   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11106
11107 ;; This pattern can't accept a variable shift count, since shifts by
11108 ;; zero don't affect the flags.  We assume that shifts by constant
11109 ;; zero are optimized away.
11110 (define_insn "*ashldi3_cmp_rex64"
11111   [(set (reg FLAGS_REG)
11112         (compare
11113           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11114                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11115           (const_int 0)))
11116    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11117         (ashift:DI (match_dup 1) (match_dup 2)))]
11118   "TARGET_64BIT
11119    && (optimize_function_for_size_p (cfun)
11120        || !TARGET_PARTIAL_FLAG_REG_STALL
11121        || (operands[2] == const1_rtx
11122            && (TARGET_SHIFT1
11123                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11124    && ix86_match_ccmode (insn, CCGOCmode)
11125    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11126 {
11127   switch (get_attr_type (insn))
11128     {
11129     case TYPE_ALU:
11130       gcc_assert (operands[2] == const1_rtx);
11131       return "add{q}\t%0, %0";
11132
11133     default:
11134       if (REG_P (operands[2]))
11135         return "sal{q}\t{%b2, %0|%0, %b2}";
11136       else if (operands[2] == const1_rtx
11137                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11138         return "sal{q}\t%0";
11139       else
11140         return "sal{q}\t{%2, %0|%0, %2}";
11141     }
11142 }
11143   [(set (attr "type")
11144      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11145                           (const_int 0))
11146                       (match_operand 0 "register_operand" ""))
11147                  (match_operand 2 "const1_operand" ""))
11148               (const_string "alu")
11149            ]
11150            (const_string "ishift")))
11151    (set (attr "length_immediate")
11152      (if_then_else
11153        (ior (eq_attr "type" "alu")
11154             (and (eq_attr "type" "ishift")
11155                  (and (match_operand 2 "const1_operand" "")
11156                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11157                           (const_int 0)))))
11158        (const_string "0")
11159        (const_string "*")))
11160    (set_attr "mode" "DI")])
11161
11162 (define_insn "*ashldi3_cconly_rex64"
11163   [(set (reg FLAGS_REG)
11164         (compare
11165           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11166                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11167           (const_int 0)))
11168    (clobber (match_scratch:DI 0 "=r"))]
11169   "TARGET_64BIT
11170    && (optimize_function_for_size_p (cfun)
11171        || !TARGET_PARTIAL_FLAG_REG_STALL
11172        || (operands[2] == const1_rtx
11173            && (TARGET_SHIFT1
11174                || TARGET_DOUBLE_WITH_ADD)))
11175    && ix86_match_ccmode (insn, CCGOCmode)
11176    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11177 {
11178   switch (get_attr_type (insn))
11179     {
11180     case TYPE_ALU:
11181       gcc_assert (operands[2] == const1_rtx);
11182       return "add{q}\t%0, %0";
11183
11184     default:
11185       if (REG_P (operands[2]))
11186         return "sal{q}\t{%b2, %0|%0, %b2}";
11187       else if (operands[2] == const1_rtx
11188                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11189         return "sal{q}\t%0";
11190       else
11191         return "sal{q}\t{%2, %0|%0, %2}";
11192     }
11193 }
11194   [(set (attr "type")
11195      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11196                           (const_int 0))
11197                       (match_operand 0 "register_operand" ""))
11198                  (match_operand 2 "const1_operand" ""))
11199               (const_string "alu")
11200            ]
11201            (const_string "ishift")))
11202    (set (attr "length_immediate")
11203      (if_then_else
11204        (ior (eq_attr "type" "alu")
11205             (and (eq_attr "type" "ishift")
11206                  (and (match_operand 2 "const1_operand" "")
11207                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11208                           (const_int 0)))))
11209        (const_string "0")
11210        (const_string "*")))
11211    (set_attr "mode" "DI")])
11212
11213 (define_insn "*ashldi3_1"
11214   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11215         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11216                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11217    (clobber (reg:CC FLAGS_REG))]
11218   "!TARGET_64BIT"
11219   "#"
11220   [(set_attr "type" "multi")])
11221
11222 ;; By default we don't ask for a scratch register, because when DImode
11223 ;; values are manipulated, registers are already at a premium.  But if
11224 ;; we have one handy, we won't turn it away.
11225 (define_peephole2
11226   [(match_scratch:SI 3 "r")
11227    (parallel [(set (match_operand:DI 0 "register_operand" "")
11228                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11229                               (match_operand:QI 2 "nonmemory_operand" "")))
11230               (clobber (reg:CC FLAGS_REG))])
11231    (match_dup 3)]
11232   "!TARGET_64BIT && TARGET_CMOVE"
11233   [(const_int 0)]
11234   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11235
11236 (define_split
11237   [(set (match_operand:DI 0 "register_operand" "")
11238         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11239                    (match_operand:QI 2 "nonmemory_operand" "")))
11240    (clobber (reg:CC FLAGS_REG))]
11241   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11242                      ? epilogue_completed : reload_completed)"
11243   [(const_int 0)]
11244   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11245
11246 (define_insn "x86_shld"
11247   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11248         (ior:SI (ashift:SI (match_dup 0)
11249                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11250                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11251                   (minus:QI (const_int 32) (match_dup 2)))))
11252    (clobber (reg:CC FLAGS_REG))]
11253   ""
11254   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11255   [(set_attr "type" "ishift")
11256    (set_attr "prefix_0f" "1")
11257    (set_attr "mode" "SI")
11258    (set_attr "pent_pair" "np")
11259    (set_attr "athlon_decode" "vector")
11260    (set_attr "amdfam10_decode" "vector")])
11261
11262 (define_expand "x86_shift_adj_1"
11263   [(set (reg:CCZ FLAGS_REG)
11264         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11265                              (const_int 32))
11266                      (const_int 0)))
11267    (set (match_operand:SI 0 "register_operand" "")
11268         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11269                          (match_operand:SI 1 "register_operand" "")
11270                          (match_dup 0)))
11271    (set (match_dup 1)
11272         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11273                          (match_operand:SI 3 "register_operand" "r")
11274                          (match_dup 1)))]
11275   "TARGET_CMOVE"
11276   "")
11277
11278 (define_expand "x86_shift_adj_2"
11279   [(use (match_operand:SI 0 "register_operand" ""))
11280    (use (match_operand:SI 1 "register_operand" ""))
11281    (use (match_operand:QI 2 "register_operand" ""))]
11282   ""
11283 {
11284   rtx label = gen_label_rtx ();
11285   rtx tmp;
11286
11287   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11288
11289   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11290   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11291   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11292                               gen_rtx_LABEL_REF (VOIDmode, label),
11293                               pc_rtx);
11294   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11295   JUMP_LABEL (tmp) = label;
11296
11297   emit_move_insn (operands[0], operands[1]);
11298   ix86_expand_clear (operands[1]);
11299
11300   emit_label (label);
11301   LABEL_NUSES (label) = 1;
11302
11303   DONE;
11304 })
11305
11306 (define_expand "ashlsi3"
11307   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11308         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11309                    (match_operand:QI 2 "nonmemory_operand" "")))]
11310   ""
11311   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11312
11313 (define_insn "*ashlsi3_1"
11314   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11315         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11316                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11319 {
11320   switch (get_attr_type (insn))
11321     {
11322     case TYPE_ALU:
11323       gcc_assert (operands[2] == const1_rtx);
11324       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11325       return "add{l}\t%0, %0";
11326
11327     case TYPE_LEA:
11328       return "#";
11329
11330     default:
11331       if (REG_P (operands[2]))
11332         return "sal{l}\t{%b2, %0|%0, %b2}";
11333       else if (operands[2] == const1_rtx
11334                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11335         return "sal{l}\t%0";
11336       else
11337         return "sal{l}\t{%2, %0|%0, %2}";
11338     }
11339 }
11340   [(set (attr "type")
11341      (cond [(eq_attr "alternative" "1")
11342               (const_string "lea")
11343             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11344                           (const_int 0))
11345                       (match_operand 0 "register_operand" ""))
11346                  (match_operand 2 "const1_operand" ""))
11347               (const_string "alu")
11348            ]
11349            (const_string "ishift")))
11350    (set (attr "length_immediate")
11351      (if_then_else
11352        (ior (eq_attr "type" "alu")
11353             (and (eq_attr "type" "ishift")
11354                  (and (match_operand 2 "const1_operand" "")
11355                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11356                           (const_int 0)))))
11357        (const_string "0")
11358        (const_string "*")))
11359    (set_attr "mode" "SI")])
11360
11361 ;; Convert lea to the lea pattern to avoid flags dependency.
11362 (define_split
11363   [(set (match_operand 0 "register_operand" "")
11364         (ashift (match_operand 1 "index_register_operand" "")
11365                 (match_operand:QI 2 "const_int_operand" "")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "reload_completed
11368    && true_regnum (operands[0]) != true_regnum (operands[1])
11369    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11370   [(const_int 0)]
11371 {
11372   rtx pat;
11373   enum machine_mode mode = GET_MODE (operands[0]);
11374
11375   if (GET_MODE_SIZE (mode) < 4)
11376     operands[0] = gen_lowpart (SImode, operands[0]);
11377   if (mode != Pmode)
11378     operands[1] = gen_lowpart (Pmode, operands[1]);
11379   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11380
11381   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11382   if (Pmode != SImode)
11383     pat = gen_rtx_SUBREG (SImode, pat, 0);
11384   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11385   DONE;
11386 })
11387
11388 ;; Rare case of shifting RSP is handled by generating move and shift
11389 (define_split
11390   [(set (match_operand 0 "register_operand" "")
11391         (ashift (match_operand 1 "register_operand" "")
11392                 (match_operand:QI 2 "const_int_operand" "")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "reload_completed
11395    && true_regnum (operands[0]) != true_regnum (operands[1])"
11396   [(const_int 0)]
11397 {
11398   rtx pat, clob;
11399   emit_move_insn (operands[0], operands[1]);
11400   pat = gen_rtx_SET (VOIDmode, operands[0],
11401                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11402                                      operands[0], operands[2]));
11403   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11404   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11405   DONE;
11406 })
11407
11408 (define_insn "*ashlsi3_1_zext"
11409   [(set (match_operand:DI 0 "register_operand" "=r,r")
11410         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11411                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11412    (clobber (reg:CC FLAGS_REG))]
11413   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11414 {
11415   switch (get_attr_type (insn))
11416     {
11417     case TYPE_ALU:
11418       gcc_assert (operands[2] == const1_rtx);
11419       return "add{l}\t%k0, %k0";
11420
11421     case TYPE_LEA:
11422       return "#";
11423
11424     default:
11425       if (REG_P (operands[2]))
11426         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11427       else if (operands[2] == const1_rtx
11428                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11429         return "sal{l}\t%k0";
11430       else
11431         return "sal{l}\t{%2, %k0|%k0, %2}";
11432     }
11433 }
11434   [(set (attr "type")
11435      (cond [(eq_attr "alternative" "1")
11436               (const_string "lea")
11437             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11438                      (const_int 0))
11439                  (match_operand 2 "const1_operand" ""))
11440               (const_string "alu")
11441            ]
11442            (const_string "ishift")))
11443    (set (attr "length_immediate")
11444      (if_then_else
11445        (ior (eq_attr "type" "alu")
11446             (and (eq_attr "type" "ishift")
11447                  (and (match_operand 2 "const1_operand" "")
11448                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11449                           (const_int 0)))))
11450        (const_string "0")
11451        (const_string "*")))
11452    (set_attr "mode" "SI")])
11453
11454 ;; Convert lea to the lea pattern to avoid flags dependency.
11455 (define_split
11456   [(set (match_operand:DI 0 "register_operand" "")
11457         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11458                                 (match_operand:QI 2 "const_int_operand" ""))))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "TARGET_64BIT && reload_completed
11461    && true_regnum (operands[0]) != true_regnum (operands[1])"
11462   [(set (match_dup 0) (zero_extend:DI
11463                         (subreg:SI (mult:SI (match_dup 1)
11464                                             (match_dup 2)) 0)))]
11465 {
11466   operands[1] = gen_lowpart (Pmode, operands[1]);
11467   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11468 })
11469
11470 ;; This pattern can't accept a variable shift count, since shifts by
11471 ;; zero don't affect the flags.  We assume that shifts by constant
11472 ;; zero are optimized away.
11473 (define_insn "*ashlsi3_cmp"
11474   [(set (reg FLAGS_REG)
11475         (compare
11476           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11477                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11478           (const_int 0)))
11479    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11480         (ashift:SI (match_dup 1) (match_dup 2)))]
11481    "(optimize_function_for_size_p (cfun)
11482      || !TARGET_PARTIAL_FLAG_REG_STALL
11483      || (operands[2] == const1_rtx
11484          && (TARGET_SHIFT1
11485              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11486    && ix86_match_ccmode (insn, CCGOCmode)
11487    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11488 {
11489   switch (get_attr_type (insn))
11490     {
11491     case TYPE_ALU:
11492       gcc_assert (operands[2] == const1_rtx);
11493       return "add{l}\t%0, %0";
11494
11495     default:
11496       if (REG_P (operands[2]))
11497         return "sal{l}\t{%b2, %0|%0, %b2}";
11498       else if (operands[2] == const1_rtx
11499                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11500         return "sal{l}\t%0";
11501       else
11502         return "sal{l}\t{%2, %0|%0, %2}";
11503     }
11504 }
11505   [(set (attr "type")
11506      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11507                           (const_int 0))
11508                       (match_operand 0 "register_operand" ""))
11509                  (match_operand 2 "const1_operand" ""))
11510               (const_string "alu")
11511            ]
11512            (const_string "ishift")))
11513    (set (attr "length_immediate")
11514      (if_then_else
11515        (ior (eq_attr "type" "alu")
11516             (and (eq_attr "type" "ishift")
11517                  (and (match_operand 2 "const1_operand" "")
11518                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11519                           (const_int 0)))))
11520        (const_string "0")
11521        (const_string "*")))
11522    (set_attr "mode" "SI")])
11523
11524 (define_insn "*ashlsi3_cconly"
11525   [(set (reg FLAGS_REG)
11526         (compare
11527           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11528                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11529           (const_int 0)))
11530    (clobber (match_scratch:SI 0 "=r"))]
11531   "(optimize_function_for_size_p (cfun)
11532     || !TARGET_PARTIAL_FLAG_REG_STALL
11533     || (operands[2] == const1_rtx
11534         && (TARGET_SHIFT1
11535             || TARGET_DOUBLE_WITH_ADD)))
11536    && ix86_match_ccmode (insn, CCGOCmode)
11537    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11538 {
11539   switch (get_attr_type (insn))
11540     {
11541     case TYPE_ALU:
11542       gcc_assert (operands[2] == const1_rtx);
11543       return "add{l}\t%0, %0";
11544
11545     default:
11546       if (REG_P (operands[2]))
11547         return "sal{l}\t{%b2, %0|%0, %b2}";
11548       else if (operands[2] == const1_rtx
11549                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11550         return "sal{l}\t%0";
11551       else
11552         return "sal{l}\t{%2, %0|%0, %2}";
11553     }
11554 }
11555   [(set (attr "type")
11556      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11557                           (const_int 0))
11558                       (match_operand 0 "register_operand" ""))
11559                  (match_operand 2 "const1_operand" ""))
11560               (const_string "alu")
11561            ]
11562            (const_string "ishift")))
11563    (set (attr "length_immediate")
11564      (if_then_else
11565        (ior (eq_attr "type" "alu")
11566             (and (eq_attr "type" "ishift")
11567                  (and (match_operand 2 "const1_operand" "")
11568                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11569                           (const_int 0)))))
11570        (const_string "0")
11571        (const_string "*")))
11572    (set_attr "mode" "SI")])
11573
11574 (define_insn "*ashlsi3_cmp_zext"
11575   [(set (reg FLAGS_REG)
11576         (compare
11577           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11578                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11579           (const_int 0)))
11580    (set (match_operand:DI 0 "register_operand" "=r")
11581         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11582   "TARGET_64BIT
11583    && (optimize_function_for_size_p (cfun)
11584        || !TARGET_PARTIAL_FLAG_REG_STALL
11585        || (operands[2] == const1_rtx
11586            && (TARGET_SHIFT1
11587                || TARGET_DOUBLE_WITH_ADD)))
11588    && ix86_match_ccmode (insn, CCGOCmode)
11589    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11590 {
11591   switch (get_attr_type (insn))
11592     {
11593     case TYPE_ALU:
11594       gcc_assert (operands[2] == const1_rtx);
11595       return "add{l}\t%k0, %k0";
11596
11597     default:
11598       if (REG_P (operands[2]))
11599         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11600       else if (operands[2] == const1_rtx
11601                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11602         return "sal{l}\t%k0";
11603       else
11604         return "sal{l}\t{%2, %k0|%k0, %2}";
11605     }
11606 }
11607   [(set (attr "type")
11608      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11609                      (const_int 0))
11610                  (match_operand 2 "const1_operand" ""))
11611               (const_string "alu")
11612            ]
11613            (const_string "ishift")))
11614    (set (attr "length_immediate")
11615      (if_then_else
11616        (ior (eq_attr "type" "alu")
11617             (and (eq_attr "type" "ishift")
11618                  (and (match_operand 2 "const1_operand" "")
11619                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11620                           (const_int 0)))))
11621        (const_string "0")
11622        (const_string "*")))
11623    (set_attr "mode" "SI")])
11624
11625 (define_expand "ashlhi3"
11626   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11627         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11628                    (match_operand:QI 2 "nonmemory_operand" "")))]
11629   "TARGET_HIMODE_MATH"
11630   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11631
11632 (define_insn "*ashlhi3_1_lea"
11633   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11634         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11635                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "!TARGET_PARTIAL_REG_STALL
11638    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11639 {
11640   switch (get_attr_type (insn))
11641     {
11642     case TYPE_LEA:
11643       return "#";
11644     case TYPE_ALU:
11645       gcc_assert (operands[2] == const1_rtx);
11646       return "add{w}\t%0, %0";
11647
11648     default:
11649       if (REG_P (operands[2]))
11650         return "sal{w}\t{%b2, %0|%0, %b2}";
11651       else if (operands[2] == const1_rtx
11652                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11653         return "sal{w}\t%0";
11654       else
11655         return "sal{w}\t{%2, %0|%0, %2}";
11656     }
11657 }
11658   [(set (attr "type")
11659      (cond [(eq_attr "alternative" "1")
11660               (const_string "lea")
11661             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11662                           (const_int 0))
11663                       (match_operand 0 "register_operand" ""))
11664                  (match_operand 2 "const1_operand" ""))
11665               (const_string "alu")
11666            ]
11667            (const_string "ishift")))
11668    (set (attr "length_immediate")
11669      (if_then_else
11670        (ior (eq_attr "type" "alu")
11671             (and (eq_attr "type" "ishift")
11672                  (and (match_operand 2 "const1_operand" "")
11673                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11674                           (const_int 0)))))
11675        (const_string "0")
11676        (const_string "*")))
11677    (set_attr "mode" "HI,SI")])
11678
11679 (define_insn "*ashlhi3_1"
11680   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11681         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11682                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11683    (clobber (reg:CC FLAGS_REG))]
11684   "TARGET_PARTIAL_REG_STALL
11685    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11686 {
11687   switch (get_attr_type (insn))
11688     {
11689     case TYPE_ALU:
11690       gcc_assert (operands[2] == const1_rtx);
11691       return "add{w}\t%0, %0";
11692
11693     default:
11694       if (REG_P (operands[2]))
11695         return "sal{w}\t{%b2, %0|%0, %b2}";
11696       else if (operands[2] == const1_rtx
11697                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11698         return "sal{w}\t%0";
11699       else
11700         return "sal{w}\t{%2, %0|%0, %2}";
11701     }
11702 }
11703   [(set (attr "type")
11704      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11705                           (const_int 0))
11706                       (match_operand 0 "register_operand" ""))
11707                  (match_operand 2 "const1_operand" ""))
11708               (const_string "alu")
11709            ]
11710            (const_string "ishift")))
11711    (set (attr "length_immediate")
11712      (if_then_else
11713        (ior (eq_attr "type" "alu")
11714             (and (eq_attr "type" "ishift")
11715                  (and (match_operand 2 "const1_operand" "")
11716                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11717                           (const_int 0)))))
11718        (const_string "0")
11719        (const_string "*")))
11720    (set_attr "mode" "HI")])
11721
11722 ;; This pattern can't accept a variable shift count, since shifts by
11723 ;; zero don't affect the flags.  We assume that shifts by constant
11724 ;; zero are optimized away.
11725 (define_insn "*ashlhi3_cmp"
11726   [(set (reg FLAGS_REG)
11727         (compare
11728           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11729                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11730           (const_int 0)))
11731    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11732         (ashift:HI (match_dup 1) (match_dup 2)))]
11733   "(optimize_function_for_size_p (cfun)
11734     || !TARGET_PARTIAL_FLAG_REG_STALL
11735     || (operands[2] == const1_rtx
11736         && (TARGET_SHIFT1
11737             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11738    && ix86_match_ccmode (insn, CCGOCmode)
11739    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11740 {
11741   switch (get_attr_type (insn))
11742     {
11743     case TYPE_ALU:
11744       gcc_assert (operands[2] == const1_rtx);
11745       return "add{w}\t%0, %0";
11746
11747     default:
11748       if (REG_P (operands[2]))
11749         return "sal{w}\t{%b2, %0|%0, %b2}";
11750       else if (operands[2] == const1_rtx
11751                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11752         return "sal{w}\t%0";
11753       else
11754         return "sal{w}\t{%2, %0|%0, %2}";
11755     }
11756 }
11757   [(set (attr "type")
11758      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11759                           (const_int 0))
11760                       (match_operand 0 "register_operand" ""))
11761                  (match_operand 2 "const1_operand" ""))
11762               (const_string "alu")
11763            ]
11764            (const_string "ishift")))
11765    (set (attr "length_immediate")
11766      (if_then_else
11767        (ior (eq_attr "type" "alu")
11768             (and (eq_attr "type" "ishift")
11769                  (and (match_operand 2 "const1_operand" "")
11770                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11771                           (const_int 0)))))
11772        (const_string "0")
11773        (const_string "*")))
11774    (set_attr "mode" "HI")])
11775
11776 (define_insn "*ashlhi3_cconly"
11777   [(set (reg FLAGS_REG)
11778         (compare
11779           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11780                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11781           (const_int 0)))
11782    (clobber (match_scratch:HI 0 "=r"))]
11783   "(optimize_function_for_size_p (cfun)
11784     || !TARGET_PARTIAL_FLAG_REG_STALL
11785     || (operands[2] == const1_rtx
11786         && (TARGET_SHIFT1
11787             || TARGET_DOUBLE_WITH_ADD)))
11788    && ix86_match_ccmode (insn, CCGOCmode)
11789    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11790 {
11791   switch (get_attr_type (insn))
11792     {
11793     case TYPE_ALU:
11794       gcc_assert (operands[2] == const1_rtx);
11795       return "add{w}\t%0, %0";
11796
11797     default:
11798       if (REG_P (operands[2]))
11799         return "sal{w}\t{%b2, %0|%0, %b2}";
11800       else if (operands[2] == const1_rtx
11801                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11802         return "sal{w}\t%0";
11803       else
11804         return "sal{w}\t{%2, %0|%0, %2}";
11805     }
11806 }
11807   [(set (attr "type")
11808      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11809                           (const_int 0))
11810                       (match_operand 0 "register_operand" ""))
11811                  (match_operand 2 "const1_operand" ""))
11812               (const_string "alu")
11813            ]
11814            (const_string "ishift")))
11815    (set (attr "length_immediate")
11816      (if_then_else
11817        (ior (eq_attr "type" "alu")
11818             (and (eq_attr "type" "ishift")
11819                  (and (match_operand 2 "const1_operand" "")
11820                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11821                           (const_int 0)))))
11822        (const_string "0")
11823        (const_string "*")))
11824    (set_attr "mode" "HI")])
11825
11826 (define_expand "ashlqi3"
11827   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11828         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11829                    (match_operand:QI 2 "nonmemory_operand" "")))]
11830   "TARGET_QIMODE_MATH"
11831   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11832
11833 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11834
11835 (define_insn "*ashlqi3_1_lea"
11836   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11837         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11838                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11839    (clobber (reg:CC FLAGS_REG))]
11840   "!TARGET_PARTIAL_REG_STALL
11841    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11842 {
11843   switch (get_attr_type (insn))
11844     {
11845     case TYPE_LEA:
11846       return "#";
11847     case TYPE_ALU:
11848       gcc_assert (operands[2] == const1_rtx);
11849       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11850         return "add{l}\t%k0, %k0";
11851       else
11852         return "add{b}\t%0, %0";
11853
11854     default:
11855       if (REG_P (operands[2]))
11856         {
11857           if (get_attr_mode (insn) == MODE_SI)
11858             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11859           else
11860             return "sal{b}\t{%b2, %0|%0, %b2}";
11861         }
11862       else if (operands[2] == const1_rtx
11863                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11864         {
11865           if (get_attr_mode (insn) == MODE_SI)
11866             return "sal{l}\t%0";
11867           else
11868             return "sal{b}\t%0";
11869         }
11870       else
11871         {
11872           if (get_attr_mode (insn) == MODE_SI)
11873             return "sal{l}\t{%2, %k0|%k0, %2}";
11874           else
11875             return "sal{b}\t{%2, %0|%0, %2}";
11876         }
11877     }
11878 }
11879   [(set (attr "type")
11880      (cond [(eq_attr "alternative" "2")
11881               (const_string "lea")
11882             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11883                           (const_int 0))
11884                       (match_operand 0 "register_operand" ""))
11885                  (match_operand 2 "const1_operand" ""))
11886               (const_string "alu")
11887            ]
11888            (const_string "ishift")))
11889    (set (attr "length_immediate")
11890      (if_then_else
11891        (ior (eq_attr "type" "alu")
11892             (and (eq_attr "type" "ishift")
11893                  (and (match_operand 2 "const1_operand" "")
11894                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11895                           (const_int 0)))))
11896        (const_string "0")
11897        (const_string "*")))
11898    (set_attr "mode" "QI,SI,SI")])
11899
11900 (define_insn "*ashlqi3_1"
11901   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11902         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11903                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11904    (clobber (reg:CC FLAGS_REG))]
11905   "TARGET_PARTIAL_REG_STALL
11906    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11907 {
11908   switch (get_attr_type (insn))
11909     {
11910     case TYPE_ALU:
11911       gcc_assert (operands[2] == const1_rtx);
11912       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11913         return "add{l}\t%k0, %k0";
11914       else
11915         return "add{b}\t%0, %0";
11916
11917     default:
11918       if (REG_P (operands[2]))
11919         {
11920           if (get_attr_mode (insn) == MODE_SI)
11921             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11922           else
11923             return "sal{b}\t{%b2, %0|%0, %b2}";
11924         }
11925       else if (operands[2] == const1_rtx
11926                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11927         {
11928           if (get_attr_mode (insn) == MODE_SI)
11929             return "sal{l}\t%0";
11930           else
11931             return "sal{b}\t%0";
11932         }
11933       else
11934         {
11935           if (get_attr_mode (insn) == MODE_SI)
11936             return "sal{l}\t{%2, %k0|%k0, %2}";
11937           else
11938             return "sal{b}\t{%2, %0|%0, %2}";
11939         }
11940     }
11941 }
11942   [(set (attr "type")
11943      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11944                           (const_int 0))
11945                       (match_operand 0 "register_operand" ""))
11946                  (match_operand 2 "const1_operand" ""))
11947               (const_string "alu")
11948            ]
11949            (const_string "ishift")))
11950    (set (attr "length_immediate")
11951      (if_then_else
11952        (ior (eq_attr "type" "alu")
11953             (and (eq_attr "type" "ishift")
11954                  (and (match_operand 2 "const1_operand" "")
11955                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11956                           (const_int 0)))))
11957        (const_string "0")
11958        (const_string "*")))
11959    (set_attr "mode" "QI,SI")])
11960
11961 ;; This pattern can't accept a variable shift count, since shifts by
11962 ;; zero don't affect the flags.  We assume that shifts by constant
11963 ;; zero are optimized away.
11964 (define_insn "*ashlqi3_cmp"
11965   [(set (reg FLAGS_REG)
11966         (compare
11967           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11968                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11969           (const_int 0)))
11970    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11971         (ashift:QI (match_dup 1) (match_dup 2)))]
11972   "(optimize_function_for_size_p (cfun)
11973     || !TARGET_PARTIAL_FLAG_REG_STALL
11974     || (operands[2] == const1_rtx
11975         && (TARGET_SHIFT1
11976             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11977    && ix86_match_ccmode (insn, CCGOCmode)
11978    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11979 {
11980   switch (get_attr_type (insn))
11981     {
11982     case TYPE_ALU:
11983       gcc_assert (operands[2] == const1_rtx);
11984       return "add{b}\t%0, %0";
11985
11986     default:
11987       if (REG_P (operands[2]))
11988         return "sal{b}\t{%b2, %0|%0, %b2}";
11989       else if (operands[2] == const1_rtx
11990                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11991         return "sal{b}\t%0";
11992       else
11993         return "sal{b}\t{%2, %0|%0, %2}";
11994     }
11995 }
11996   [(set (attr "type")
11997      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11998                           (const_int 0))
11999                       (match_operand 0 "register_operand" ""))
12000                  (match_operand 2 "const1_operand" ""))
12001               (const_string "alu")
12002            ]
12003            (const_string "ishift")))
12004    (set (attr "length_immediate")
12005      (if_then_else
12006        (ior (eq_attr "type" "alu")
12007             (and (eq_attr "type" "ishift")
12008                  (and (match_operand 2 "const1_operand" "")
12009                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12010                           (const_int 0)))))
12011        (const_string "0")
12012        (const_string "*")))
12013    (set_attr "mode" "QI")])
12014
12015 (define_insn "*ashlqi3_cconly"
12016   [(set (reg FLAGS_REG)
12017         (compare
12018           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12019                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12020           (const_int 0)))
12021    (clobber (match_scratch:QI 0 "=q"))]
12022   "(optimize_function_for_size_p (cfun)
12023     || !TARGET_PARTIAL_FLAG_REG_STALL
12024     || (operands[2] == const1_rtx
12025         && (TARGET_SHIFT1
12026             || TARGET_DOUBLE_WITH_ADD)))
12027    && ix86_match_ccmode (insn, CCGOCmode)
12028    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12029 {
12030   switch (get_attr_type (insn))
12031     {
12032     case TYPE_ALU:
12033       gcc_assert (operands[2] == const1_rtx);
12034       return "add{b}\t%0, %0";
12035
12036     default:
12037       if (REG_P (operands[2]))
12038         return "sal{b}\t{%b2, %0|%0, %b2}";
12039       else if (operands[2] == const1_rtx
12040                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12041         return "sal{b}\t%0";
12042       else
12043         return "sal{b}\t{%2, %0|%0, %2}";
12044     }
12045 }
12046   [(set (attr "type")
12047      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12048                           (const_int 0))
12049                       (match_operand 0 "register_operand" ""))
12050                  (match_operand 2 "const1_operand" ""))
12051               (const_string "alu")
12052            ]
12053            (const_string "ishift")))
12054    (set (attr "length_immediate")
12055      (if_then_else
12056        (ior (eq_attr "type" "alu")
12057             (and (eq_attr "type" "ishift")
12058                  (and (match_operand 2 "const1_operand" "")
12059                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12060                           (const_int 0)))))
12061        (const_string "0")
12062        (const_string "*")))
12063    (set_attr "mode" "QI")])
12064
12065 ;; See comment above `ashldi3' about how this works.
12066
12067 (define_expand "ashrti3"
12068   [(set (match_operand:TI 0 "register_operand" "")
12069         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12070                      (match_operand:QI 2 "nonmemory_operand" "")))]
12071   "TARGET_64BIT"
12072   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12073
12074 (define_insn "*ashrti3_1"
12075   [(set (match_operand:TI 0 "register_operand" "=r")
12076         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12077                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "TARGET_64BIT"
12080   "#"
12081   [(set_attr "type" "multi")])
12082
12083 (define_peephole2
12084   [(match_scratch:DI 3 "r")
12085    (parallel [(set (match_operand:TI 0 "register_operand" "")
12086                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12087                                 (match_operand:QI 2 "nonmemory_operand" "")))
12088               (clobber (reg:CC FLAGS_REG))])
12089    (match_dup 3)]
12090   "TARGET_64BIT"
12091   [(const_int 0)]
12092   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12093
12094 (define_split
12095   [(set (match_operand:TI 0 "register_operand" "")
12096         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12097                      (match_operand:QI 2 "nonmemory_operand" "")))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12100                     ? epilogue_completed : reload_completed)"
12101   [(const_int 0)]
12102   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12103
12104 (define_insn "x86_64_shrd"
12105   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12106         (ior:DI (ashiftrt:DI (match_dup 0)
12107                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12108                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12109                   (minus:QI (const_int 64) (match_dup 2)))))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_64BIT"
12112   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12113   [(set_attr "type" "ishift")
12114    (set_attr "prefix_0f" "1")
12115    (set_attr "mode" "DI")
12116    (set_attr "athlon_decode" "vector")
12117    (set_attr "amdfam10_decode" "vector")])
12118
12119 (define_expand "ashrdi3"
12120   [(set (match_operand:DI 0 "shiftdi_operand" "")
12121         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12122                      (match_operand:QI 2 "nonmemory_operand" "")))]
12123   ""
12124   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12125
12126 (define_expand "x86_64_shift_adj_3"
12127   [(use (match_operand:DI 0 "register_operand" ""))
12128    (use (match_operand:DI 1 "register_operand" ""))
12129    (use (match_operand:QI 2 "register_operand" ""))]
12130   ""
12131 {
12132   rtx label = gen_label_rtx ();
12133   rtx tmp;
12134
12135   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12136
12137   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12138   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12139   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12140                               gen_rtx_LABEL_REF (VOIDmode, label),
12141                               pc_rtx);
12142   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12143   JUMP_LABEL (tmp) = label;
12144
12145   emit_move_insn (operands[0], operands[1]);
12146   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12147
12148   emit_label (label);
12149   LABEL_NUSES (label) = 1;
12150
12151   DONE;
12152 })
12153
12154 (define_insn "ashrdi3_63_rex64"
12155   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12156         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12157                      (match_operand:DI 2 "const_int_operand" "i,i")))
12158    (clobber (reg:CC FLAGS_REG))]
12159   "TARGET_64BIT && INTVAL (operands[2]) == 63
12160    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12161    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12162   "@
12163    {cqto|cqo}
12164    sar{q}\t{%2, %0|%0, %2}"
12165   [(set_attr "type" "imovx,ishift")
12166    (set_attr "prefix_0f" "0,*")
12167    (set_attr "length_immediate" "0,*")
12168    (set_attr "modrm" "0,1")
12169    (set_attr "mode" "DI")])
12170
12171 (define_insn "*ashrdi3_1_one_bit_rex64"
12172   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12173         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12174                      (match_operand:QI 2 "const1_operand" "")))
12175    (clobber (reg:CC FLAGS_REG))]
12176   "TARGET_64BIT
12177    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12178    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12179   "sar{q}\t%0"
12180   [(set_attr "type" "ishift")
12181    (set_attr "length_immediate" "0")
12182    (set_attr "mode" "DI")])
12183
12184 (define_insn "*ashrdi3_1_rex64"
12185   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12186         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12187                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12190   "@
12191    sar{q}\t{%2, %0|%0, %2}
12192    sar{q}\t{%b2, %0|%0, %b2}"
12193   [(set_attr "type" "ishift")
12194    (set_attr "mode" "DI")])
12195
12196 ;; This pattern can't accept a variable shift count, since shifts by
12197 ;; zero don't affect the flags.  We assume that shifts by constant
12198 ;; zero are optimized away.
12199 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12200   [(set (reg FLAGS_REG)
12201         (compare
12202           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12203                        (match_operand:QI 2 "const1_operand" ""))
12204           (const_int 0)))
12205    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12206         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12207   "TARGET_64BIT
12208    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12209    && ix86_match_ccmode (insn, CCGOCmode)
12210    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12211   "sar{q}\t%0"
12212   [(set_attr "type" "ishift")
12213    (set_attr "length_immediate" "0")
12214    (set_attr "mode" "DI")])
12215
12216 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12217   [(set (reg FLAGS_REG)
12218         (compare
12219           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12220                        (match_operand:QI 2 "const1_operand" ""))
12221           (const_int 0)))
12222    (clobber (match_scratch:DI 0 "=r"))]
12223   "TARGET_64BIT
12224    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12225    && ix86_match_ccmode (insn, CCGOCmode)
12226    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12227   "sar{q}\t%0"
12228   [(set_attr "type" "ishift")
12229    (set_attr "length_immediate" "0")
12230    (set_attr "mode" "DI")])
12231
12232 ;; This pattern can't accept a variable shift count, since shifts by
12233 ;; zero don't affect the flags.  We assume that shifts by constant
12234 ;; zero are optimized away.
12235 (define_insn "*ashrdi3_cmp_rex64"
12236   [(set (reg FLAGS_REG)
12237         (compare
12238           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12239                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12240           (const_int 0)))
12241    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12242         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12243   "TARGET_64BIT
12244    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12245    && ix86_match_ccmode (insn, CCGOCmode)
12246    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12247   "sar{q}\t{%2, %0|%0, %2}"
12248   [(set_attr "type" "ishift")
12249    (set_attr "mode" "DI")])
12250
12251 (define_insn "*ashrdi3_cconly_rex64"
12252   [(set (reg FLAGS_REG)
12253         (compare
12254           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12255                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12256           (const_int 0)))
12257    (clobber (match_scratch:DI 0 "=r"))]
12258   "TARGET_64BIT
12259    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12260    && ix86_match_ccmode (insn, CCGOCmode)
12261    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12262   "sar{q}\t{%2, %0|%0, %2}"
12263   [(set_attr "type" "ishift")
12264    (set_attr "mode" "DI")])
12265
12266 (define_insn "*ashrdi3_1"
12267   [(set (match_operand:DI 0 "register_operand" "=r")
12268         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12269                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12270    (clobber (reg:CC FLAGS_REG))]
12271   "!TARGET_64BIT"
12272   "#"
12273   [(set_attr "type" "multi")])
12274
12275 ;; By default we don't ask for a scratch register, because when DImode
12276 ;; values are manipulated, registers are already at a premium.  But if
12277 ;; we have one handy, we won't turn it away.
12278 (define_peephole2
12279   [(match_scratch:SI 3 "r")
12280    (parallel [(set (match_operand:DI 0 "register_operand" "")
12281                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12282                                 (match_operand:QI 2 "nonmemory_operand" "")))
12283               (clobber (reg:CC FLAGS_REG))])
12284    (match_dup 3)]
12285   "!TARGET_64BIT && TARGET_CMOVE"
12286   [(const_int 0)]
12287   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12288
12289 (define_split
12290   [(set (match_operand:DI 0 "register_operand" "")
12291         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12292                      (match_operand:QI 2 "nonmemory_operand" "")))
12293    (clobber (reg:CC FLAGS_REG))]
12294   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12295                      ? epilogue_completed : reload_completed)"
12296   [(const_int 0)]
12297   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12298
12299 (define_insn "x86_shrd"
12300   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12301         (ior:SI (ashiftrt:SI (match_dup 0)
12302                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12303                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12304                   (minus:QI (const_int 32) (match_dup 2)))))
12305    (clobber (reg:CC FLAGS_REG))]
12306   ""
12307   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12308   [(set_attr "type" "ishift")
12309    (set_attr "prefix_0f" "1")
12310    (set_attr "pent_pair" "np")
12311    (set_attr "mode" "SI")])
12312
12313 (define_expand "x86_shift_adj_3"
12314   [(use (match_operand:SI 0 "register_operand" ""))
12315    (use (match_operand:SI 1 "register_operand" ""))
12316    (use (match_operand:QI 2 "register_operand" ""))]
12317   ""
12318 {
12319   rtx label = gen_label_rtx ();
12320   rtx tmp;
12321
12322   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12323
12324   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12325   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12326   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12327                               gen_rtx_LABEL_REF (VOIDmode, label),
12328                               pc_rtx);
12329   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12330   JUMP_LABEL (tmp) = label;
12331
12332   emit_move_insn (operands[0], operands[1]);
12333   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12334
12335   emit_label (label);
12336   LABEL_NUSES (label) = 1;
12337
12338   DONE;
12339 })
12340
12341 (define_expand "ashrsi3_31"
12342   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12343                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12344                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12345               (clobber (reg:CC FLAGS_REG))])]
12346   "")
12347
12348 (define_insn "*ashrsi3_31"
12349   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12350         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12351                      (match_operand:SI 2 "const_int_operand" "i,i")))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "INTVAL (operands[2]) == 31
12354    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12355    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12356   "@
12357    {cltd|cdq}
12358    sar{l}\t{%2, %0|%0, %2}"
12359   [(set_attr "type" "imovx,ishift")
12360    (set_attr "prefix_0f" "0,*")
12361    (set_attr "length_immediate" "0,*")
12362    (set_attr "modrm" "0,1")
12363    (set_attr "mode" "SI")])
12364
12365 (define_insn "*ashrsi3_31_zext"
12366   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12367         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12368                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12371    && INTVAL (operands[2]) == 31
12372    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12373   "@
12374    {cltd|cdq}
12375    sar{l}\t{%2, %k0|%k0, %2}"
12376   [(set_attr "type" "imovx,ishift")
12377    (set_attr "prefix_0f" "0,*")
12378    (set_attr "length_immediate" "0,*")
12379    (set_attr "modrm" "0,1")
12380    (set_attr "mode" "SI")])
12381
12382 (define_expand "ashrsi3"
12383   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12384         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12385                      (match_operand:QI 2 "nonmemory_operand" "")))]
12386   ""
12387   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12388
12389 (define_insn "*ashrsi3_1_one_bit"
12390   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12391         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12392                      (match_operand:QI 2 "const1_operand" "")))
12393    (clobber (reg:CC FLAGS_REG))]
12394   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12395    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12396   "sar{l}\t%0"
12397   [(set_attr "type" "ishift")
12398    (set_attr "length_immediate" "0")
12399    (set_attr "mode" "SI")])
12400
12401 (define_insn "*ashrsi3_1_one_bit_zext"
12402   [(set (match_operand:DI 0 "register_operand" "=r")
12403         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12404                                      (match_operand:QI 2 "const1_operand" ""))))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "TARGET_64BIT
12407    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12409   "sar{l}\t%k0"
12410   [(set_attr "type" "ishift")
12411    (set_attr "length_immediate" "0")
12412    (set_attr "mode" "SI")])
12413
12414 (define_insn "*ashrsi3_1"
12415   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12416         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12417                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12418    (clobber (reg:CC FLAGS_REG))]
12419   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12420   "@
12421    sar{l}\t{%2, %0|%0, %2}
12422    sar{l}\t{%b2, %0|%0, %b2}"
12423   [(set_attr "type" "ishift")
12424    (set_attr "mode" "SI")])
12425
12426 (define_insn "*ashrsi3_1_zext"
12427   [(set (match_operand:DI 0 "register_operand" "=r,r")
12428         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12429                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12432   "@
12433    sar{l}\t{%2, %k0|%k0, %2}
12434    sar{l}\t{%b2, %k0|%k0, %b2}"
12435   [(set_attr "type" "ishift")
12436    (set_attr "mode" "SI")])
12437
12438 ;; This pattern can't accept a variable shift count, since shifts by
12439 ;; zero don't affect the flags.  We assume that shifts by constant
12440 ;; zero are optimized away.
12441 (define_insn "*ashrsi3_one_bit_cmp"
12442   [(set (reg FLAGS_REG)
12443         (compare
12444           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12445                        (match_operand:QI 2 "const1_operand" ""))
12446           (const_int 0)))
12447    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12448         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12449   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12450    && ix86_match_ccmode (insn, CCGOCmode)
12451    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12452   "sar{l}\t%0"
12453   [(set_attr "type" "ishift")
12454    (set_attr "length_immediate" "0")
12455    (set_attr "mode" "SI")])
12456
12457 (define_insn "*ashrsi3_one_bit_cconly"
12458   [(set (reg FLAGS_REG)
12459         (compare
12460           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12461                        (match_operand:QI 2 "const1_operand" ""))
12462           (const_int 0)))
12463    (clobber (match_scratch:SI 0 "=r"))]
12464   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12465    && ix86_match_ccmode (insn, CCGOCmode)
12466    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12467   "sar{l}\t%0"
12468   [(set_attr "type" "ishift")
12469    (set_attr "length_immediate" "0")
12470    (set_attr "mode" "SI")])
12471
12472 (define_insn "*ashrsi3_one_bit_cmp_zext"
12473   [(set (reg FLAGS_REG)
12474         (compare
12475           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12476                        (match_operand:QI 2 "const1_operand" ""))
12477           (const_int 0)))
12478    (set (match_operand:DI 0 "register_operand" "=r")
12479         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12480   "TARGET_64BIT
12481    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12482    && ix86_match_ccmode (insn, CCmode)
12483    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12484   "sar{l}\t%k0"
12485   [(set_attr "type" "ishift")
12486    (set_attr "length_immediate" "0")
12487    (set_attr "mode" "SI")])
12488
12489 ;; This pattern can't accept a variable shift count, since shifts by
12490 ;; zero don't affect the flags.  We assume that shifts by constant
12491 ;; zero are optimized away.
12492 (define_insn "*ashrsi3_cmp"
12493   [(set (reg FLAGS_REG)
12494         (compare
12495           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12496                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12497           (const_int 0)))
12498    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12499         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12500   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12501    && ix86_match_ccmode (insn, CCGOCmode)
12502    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12503   "sar{l}\t{%2, %0|%0, %2}"
12504   [(set_attr "type" "ishift")
12505    (set_attr "mode" "SI")])
12506
12507 (define_insn "*ashrsi3_cconly"
12508   [(set (reg FLAGS_REG)
12509         (compare
12510           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12511                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12512           (const_int 0)))
12513    (clobber (match_scratch:SI 0 "=r"))]
12514   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515    && ix86_match_ccmode (insn, CCGOCmode)
12516    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12517   "sar{l}\t{%2, %0|%0, %2}"
12518   [(set_attr "type" "ishift")
12519    (set_attr "mode" "SI")])
12520
12521 (define_insn "*ashrsi3_cmp_zext"
12522   [(set (reg FLAGS_REG)
12523         (compare
12524           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12525                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526           (const_int 0)))
12527    (set (match_operand:DI 0 "register_operand" "=r")
12528         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12529   "TARGET_64BIT
12530    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12531    && ix86_match_ccmode (insn, CCGOCmode)
12532    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12533   "sar{l}\t{%2, %k0|%k0, %2}"
12534   [(set_attr "type" "ishift")
12535    (set_attr "mode" "SI")])
12536
12537 (define_expand "ashrhi3"
12538   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12539         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12540                      (match_operand:QI 2 "nonmemory_operand" "")))]
12541   "TARGET_HIMODE_MATH"
12542   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12543
12544 (define_insn "*ashrhi3_1_one_bit"
12545   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12546         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12547                      (match_operand:QI 2 "const1_operand" "")))
12548    (clobber (reg:CC FLAGS_REG))]
12549   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12550    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12551   "sar{w}\t%0"
12552   [(set_attr "type" "ishift")
12553    (set_attr "length_immediate" "0")
12554    (set_attr "mode" "HI")])
12555
12556 (define_insn "*ashrhi3_1"
12557   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12558         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12559                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12560    (clobber (reg:CC FLAGS_REG))]
12561   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12562   "@
12563    sar{w}\t{%2, %0|%0, %2}
12564    sar{w}\t{%b2, %0|%0, %b2}"
12565   [(set_attr "type" "ishift")
12566    (set_attr "mode" "HI")])
12567
12568 ;; This pattern can't accept a variable shift count, since shifts by
12569 ;; zero don't affect the flags.  We assume that shifts by constant
12570 ;; zero are optimized away.
12571 (define_insn "*ashrhi3_one_bit_cmp"
12572   [(set (reg FLAGS_REG)
12573         (compare
12574           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12575                        (match_operand:QI 2 "const1_operand" ""))
12576           (const_int 0)))
12577    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12578         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12579   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12580    && ix86_match_ccmode (insn, CCGOCmode)
12581    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12582   "sar{w}\t%0"
12583   [(set_attr "type" "ishift")
12584    (set_attr "length_immediate" "0")
12585    (set_attr "mode" "HI")])
12586
12587 (define_insn "*ashrhi3_one_bit_cconly"
12588   [(set (reg FLAGS_REG)
12589         (compare
12590           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12591                        (match_operand:QI 2 "const1_operand" ""))
12592           (const_int 0)))
12593    (clobber (match_scratch:HI 0 "=r"))]
12594   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12595    && ix86_match_ccmode (insn, CCGOCmode)
12596    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12597   "sar{w}\t%0"
12598   [(set_attr "type" "ishift")
12599    (set_attr "length_immediate" "0")
12600    (set_attr "mode" "HI")])
12601
12602 ;; This pattern can't accept a variable shift count, since shifts by
12603 ;; zero don't affect the flags.  We assume that shifts by constant
12604 ;; zero are optimized away.
12605 (define_insn "*ashrhi3_cmp"
12606   [(set (reg FLAGS_REG)
12607         (compare
12608           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12609                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12610           (const_int 0)))
12611    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12612         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12613   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12614    && ix86_match_ccmode (insn, CCGOCmode)
12615    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12616   "sar{w}\t{%2, %0|%0, %2}"
12617   [(set_attr "type" "ishift")
12618    (set_attr "mode" "HI")])
12619
12620 (define_insn "*ashrhi3_cconly"
12621   [(set (reg FLAGS_REG)
12622         (compare
12623           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12624                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12625           (const_int 0)))
12626    (clobber (match_scratch:HI 0 "=r"))]
12627   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12628    && ix86_match_ccmode (insn, CCGOCmode)
12629    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12630   "sar{w}\t{%2, %0|%0, %2}"
12631   [(set_attr "type" "ishift")
12632    (set_attr "mode" "HI")])
12633
12634 (define_expand "ashrqi3"
12635   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12636         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12637                      (match_operand:QI 2 "nonmemory_operand" "")))]
12638   "TARGET_QIMODE_MATH"
12639   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12640
12641 (define_insn "*ashrqi3_1_one_bit"
12642   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12643         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12644                      (match_operand:QI 2 "const1_operand" "")))
12645    (clobber (reg:CC FLAGS_REG))]
12646   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12647    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12648   "sar{b}\t%0"
12649   [(set_attr "type" "ishift")
12650    (set_attr "length_immediate" "0")
12651    (set_attr "mode" "QI")])
12652
12653 (define_insn "*ashrqi3_1_one_bit_slp"
12654   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12655         (ashiftrt:QI (match_dup 0)
12656                      (match_operand:QI 1 "const1_operand" "")))
12657    (clobber (reg:CC FLAGS_REG))]
12658   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12659    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12660    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12661   "sar{b}\t%0"
12662   [(set_attr "type" "ishift1")
12663    (set_attr "length_immediate" "0")
12664    (set_attr "mode" "QI")])
12665
12666 (define_insn "*ashrqi3_1"
12667   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12668         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12669                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12670    (clobber (reg:CC FLAGS_REG))]
12671   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12672   "@
12673    sar{b}\t{%2, %0|%0, %2}
12674    sar{b}\t{%b2, %0|%0, %b2}"
12675   [(set_attr "type" "ishift")
12676    (set_attr "mode" "QI")])
12677
12678 (define_insn "*ashrqi3_1_slp"
12679   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12680         (ashiftrt:QI (match_dup 0)
12681                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12682    (clobber (reg:CC FLAGS_REG))]
12683   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12684    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12685   "@
12686    sar{b}\t{%1, %0|%0, %1}
12687    sar{b}\t{%b1, %0|%0, %b1}"
12688   [(set_attr "type" "ishift1")
12689    (set_attr "mode" "QI")])
12690
12691 ;; This pattern can't accept a variable shift count, since shifts by
12692 ;; zero don't affect the flags.  We assume that shifts by constant
12693 ;; zero are optimized away.
12694 (define_insn "*ashrqi3_one_bit_cmp"
12695   [(set (reg FLAGS_REG)
12696         (compare
12697           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12698                        (match_operand:QI 2 "const1_operand" "I"))
12699           (const_int 0)))
12700    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12701         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12702   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12703    && ix86_match_ccmode (insn, CCGOCmode)
12704    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12705   "sar{b}\t%0"
12706   [(set_attr "type" "ishift")
12707    (set_attr "length_immediate" "0")
12708    (set_attr "mode" "QI")])
12709
12710 (define_insn "*ashrqi3_one_bit_cconly"
12711   [(set (reg FLAGS_REG)
12712         (compare
12713           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12714                        (match_operand:QI 2 "const1_operand" ""))
12715           (const_int 0)))
12716    (clobber (match_scratch:QI 0 "=q"))]
12717   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12718    && ix86_match_ccmode (insn, CCGOCmode)
12719    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12720   "sar{b}\t%0"
12721   [(set_attr "type" "ishift")
12722    (set_attr "length_immediate" "0")
12723    (set_attr "mode" "QI")])
12724
12725 ;; This pattern can't accept a variable shift count, since shifts by
12726 ;; zero don't affect the flags.  We assume that shifts by constant
12727 ;; zero are optimized away.
12728 (define_insn "*ashrqi3_cmp"
12729   [(set (reg FLAGS_REG)
12730         (compare
12731           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12732                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12733           (const_int 0)))
12734    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12735         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12736   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12737    && ix86_match_ccmode (insn, CCGOCmode)
12738    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12739   "sar{b}\t{%2, %0|%0, %2}"
12740   [(set_attr "type" "ishift")
12741    (set_attr "mode" "QI")])
12742
12743 (define_insn "*ashrqi3_cconly"
12744   [(set (reg FLAGS_REG)
12745         (compare
12746           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12747                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12748           (const_int 0)))
12749    (clobber (match_scratch:QI 0 "=q"))]
12750   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12751    && ix86_match_ccmode (insn, CCGOCmode)
12752    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12753   "sar{b}\t{%2, %0|%0, %2}"
12754   [(set_attr "type" "ishift")
12755    (set_attr "mode" "QI")])
12756
12757 \f
12758 ;; Logical shift instructions
12759
12760 ;; See comment above `ashldi3' about how this works.
12761
12762 (define_expand "lshrti3"
12763   [(set (match_operand:TI 0 "register_operand" "")
12764         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12765                      (match_operand:QI 2 "nonmemory_operand" "")))]
12766   "TARGET_64BIT"
12767   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12768
12769 ;; This pattern must be defined before *lshrti3_1 to prevent
12770 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12771
12772 (define_insn "*avx_lshrti3"
12773   [(set (match_operand:TI 0 "register_operand" "=x")
12774         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12775                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12776   "TARGET_AVX"
12777 {
12778   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12779   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12780 }
12781   [(set_attr "type" "sseishft")
12782    (set_attr "prefix" "vex")
12783    (set_attr "length_immediate" "1")
12784    (set_attr "mode" "TI")])
12785
12786 (define_insn "sse2_lshrti3"
12787   [(set (match_operand:TI 0 "register_operand" "=x")
12788         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12789                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12790   "TARGET_SSE2"
12791 {
12792   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12793   return "psrldq\t{%2, %0|%0, %2}";
12794 }
12795   [(set_attr "type" "sseishft")
12796    (set_attr "prefix_data16" "1")
12797    (set_attr "length_immediate" "1")
12798    (set_attr "mode" "TI")])
12799
12800 (define_insn "*lshrti3_1"
12801   [(set (match_operand:TI 0 "register_operand" "=r")
12802         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12803                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12804    (clobber (reg:CC FLAGS_REG))]
12805   "TARGET_64BIT"
12806   "#"
12807   [(set_attr "type" "multi")])
12808
12809 (define_peephole2
12810   [(match_scratch:DI 3 "r")
12811    (parallel [(set (match_operand:TI 0 "register_operand" "")
12812                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12813                                 (match_operand:QI 2 "nonmemory_operand" "")))
12814               (clobber (reg:CC FLAGS_REG))])
12815    (match_dup 3)]
12816   "TARGET_64BIT"
12817   [(const_int 0)]
12818   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12819
12820 (define_split
12821   [(set (match_operand:TI 0 "register_operand" "")
12822         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12823                      (match_operand:QI 2 "nonmemory_operand" "")))
12824    (clobber (reg:CC FLAGS_REG))]
12825   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12826                     ? epilogue_completed : reload_completed)"
12827   [(const_int 0)]
12828   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12829
12830 (define_expand "lshrdi3"
12831   [(set (match_operand:DI 0 "shiftdi_operand" "")
12832         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12833                      (match_operand:QI 2 "nonmemory_operand" "")))]
12834   ""
12835   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12836
12837 (define_insn "*lshrdi3_1_one_bit_rex64"
12838   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12839         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12840                      (match_operand:QI 2 "const1_operand" "")))
12841    (clobber (reg:CC FLAGS_REG))]
12842   "TARGET_64BIT
12843    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12844    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12845   "shr{q}\t%0"
12846   [(set_attr "type" "ishift")
12847    (set_attr "length_immediate" "0")
12848    (set_attr "mode" "DI")])
12849
12850 (define_insn "*lshrdi3_1_rex64"
12851   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12852         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12853                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12854    (clobber (reg:CC FLAGS_REG))]
12855   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12856   "@
12857    shr{q}\t{%2, %0|%0, %2}
12858    shr{q}\t{%b2, %0|%0, %b2}"
12859   [(set_attr "type" "ishift")
12860    (set_attr "mode" "DI")])
12861
12862 ;; This pattern can't accept a variable shift count, since shifts by
12863 ;; zero don't affect the flags.  We assume that shifts by constant
12864 ;; zero are optimized away.
12865 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12866   [(set (reg FLAGS_REG)
12867         (compare
12868           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12869                        (match_operand:QI 2 "const1_operand" ""))
12870           (const_int 0)))
12871    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12872         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12873   "TARGET_64BIT
12874    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12875    && ix86_match_ccmode (insn, CCGOCmode)
12876    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877   "shr{q}\t%0"
12878   [(set_attr "type" "ishift")
12879    (set_attr "length_immediate" "0")
12880    (set_attr "mode" "DI")])
12881
12882 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12883   [(set (reg FLAGS_REG)
12884         (compare
12885           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12886                        (match_operand:QI 2 "const1_operand" ""))
12887           (const_int 0)))
12888    (clobber (match_scratch:DI 0 "=r"))]
12889   "TARGET_64BIT
12890    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12891    && ix86_match_ccmode (insn, CCGOCmode)
12892    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12893   "shr{q}\t%0"
12894   [(set_attr "type" "ishift")
12895    (set_attr "length_immediate" "0")
12896    (set_attr "mode" "DI")])
12897
12898 ;; This pattern can't accept a variable shift count, since shifts by
12899 ;; zero don't affect the flags.  We assume that shifts by constant
12900 ;; zero are optimized away.
12901 (define_insn "*lshrdi3_cmp_rex64"
12902   [(set (reg FLAGS_REG)
12903         (compare
12904           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12905                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12906           (const_int 0)))
12907    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12908         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12909   "TARGET_64BIT
12910    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12911    && ix86_match_ccmode (insn, CCGOCmode)
12912    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12913   "shr{q}\t{%2, %0|%0, %2}"
12914   [(set_attr "type" "ishift")
12915    (set_attr "mode" "DI")])
12916
12917 (define_insn "*lshrdi3_cconly_rex64"
12918   [(set (reg FLAGS_REG)
12919         (compare
12920           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12921                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12922           (const_int 0)))
12923    (clobber (match_scratch:DI 0 "=r"))]
12924   "TARGET_64BIT
12925    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12926    && ix86_match_ccmode (insn, CCGOCmode)
12927    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12928   "shr{q}\t{%2, %0|%0, %2}"
12929   [(set_attr "type" "ishift")
12930    (set_attr "mode" "DI")])
12931
12932 (define_insn "*lshrdi3_1"
12933   [(set (match_operand:DI 0 "register_operand" "=r")
12934         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12935                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12936    (clobber (reg:CC FLAGS_REG))]
12937   "!TARGET_64BIT"
12938   "#"
12939   [(set_attr "type" "multi")])
12940
12941 ;; By default we don't ask for a scratch register, because when DImode
12942 ;; values are manipulated, registers are already at a premium.  But if
12943 ;; we have one handy, we won't turn it away.
12944 (define_peephole2
12945   [(match_scratch:SI 3 "r")
12946    (parallel [(set (match_operand:DI 0 "register_operand" "")
12947                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12948                                 (match_operand:QI 2 "nonmemory_operand" "")))
12949               (clobber (reg:CC FLAGS_REG))])
12950    (match_dup 3)]
12951   "!TARGET_64BIT && TARGET_CMOVE"
12952   [(const_int 0)]
12953   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12954
12955 (define_split
12956   [(set (match_operand:DI 0 "register_operand" "")
12957         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12958                      (match_operand:QI 2 "nonmemory_operand" "")))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12961                      ? epilogue_completed : reload_completed)"
12962   [(const_int 0)]
12963   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12964
12965 (define_expand "lshrsi3"
12966   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12967         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12968                      (match_operand:QI 2 "nonmemory_operand" "")))]
12969   ""
12970   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12971
12972 (define_insn "*lshrsi3_1_one_bit"
12973   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12974         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12975                      (match_operand:QI 2 "const1_operand" "")))
12976    (clobber (reg:CC FLAGS_REG))]
12977   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12978    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12979   "shr{l}\t%0"
12980   [(set_attr "type" "ishift")
12981    (set_attr "length_immediate" "0")
12982    (set_attr "mode" "SI")])
12983
12984 (define_insn "*lshrsi3_1_one_bit_zext"
12985   [(set (match_operand:DI 0 "register_operand" "=r")
12986         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12987                      (match_operand:QI 2 "const1_operand" "")))
12988    (clobber (reg:CC FLAGS_REG))]
12989   "TARGET_64BIT
12990    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12991    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12992   "shr{l}\t%k0"
12993   [(set_attr "type" "ishift")
12994    (set_attr "length_immediate" "0")
12995    (set_attr "mode" "SI")])
12996
12997 (define_insn "*lshrsi3_1"
12998   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12999         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13000                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13001    (clobber (reg:CC FLAGS_REG))]
13002   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13003   "@
13004    shr{l}\t{%2, %0|%0, %2}
13005    shr{l}\t{%b2, %0|%0, %b2}"
13006   [(set_attr "type" "ishift")
13007    (set_attr "mode" "SI")])
13008
13009 (define_insn "*lshrsi3_1_zext"
13010   [(set (match_operand:DI 0 "register_operand" "=r,r")
13011         (zero_extend:DI
13012           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13013                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13014    (clobber (reg:CC FLAGS_REG))]
13015   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13016   "@
13017    shr{l}\t{%2, %k0|%k0, %2}
13018    shr{l}\t{%b2, %k0|%k0, %b2}"
13019   [(set_attr "type" "ishift")
13020    (set_attr "mode" "SI")])
13021
13022 ;; This pattern can't accept a variable shift count, since shifts by
13023 ;; zero don't affect the flags.  We assume that shifts by constant
13024 ;; zero are optimized away.
13025 (define_insn "*lshrsi3_one_bit_cmp"
13026   [(set (reg FLAGS_REG)
13027         (compare
13028           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13029                        (match_operand:QI 2 "const1_operand" ""))
13030           (const_int 0)))
13031    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13032         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13033   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13034    && ix86_match_ccmode (insn, CCGOCmode)
13035    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13036   "shr{l}\t%0"
13037   [(set_attr "type" "ishift")
13038    (set_attr "length_immediate" "0")
13039    (set_attr "mode" "SI")])
13040
13041 (define_insn "*lshrsi3_one_bit_cconly"
13042   [(set (reg FLAGS_REG)
13043         (compare
13044           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13045                        (match_operand:QI 2 "const1_operand" ""))
13046           (const_int 0)))
13047    (clobber (match_scratch:SI 0 "=r"))]
13048   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13049    && ix86_match_ccmode (insn, CCGOCmode)
13050    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13051   "shr{l}\t%0"
13052   [(set_attr "type" "ishift")
13053    (set_attr "length_immediate" "0")
13054    (set_attr "mode" "SI")])
13055
13056 (define_insn "*lshrsi3_cmp_one_bit_zext"
13057   [(set (reg FLAGS_REG)
13058         (compare
13059           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13060                        (match_operand:QI 2 "const1_operand" ""))
13061           (const_int 0)))
13062    (set (match_operand:DI 0 "register_operand" "=r")
13063         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13064   "TARGET_64BIT
13065    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13066    && ix86_match_ccmode (insn, CCGOCmode)
13067    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13068   "shr{l}\t%k0"
13069   [(set_attr "type" "ishift")
13070    (set_attr "length_immediate" "0")
13071    (set_attr "mode" "SI")])
13072
13073 ;; This pattern can't accept a variable shift count, since shifts by
13074 ;; zero don't affect the flags.  We assume that shifts by constant
13075 ;; zero are optimized away.
13076 (define_insn "*lshrsi3_cmp"
13077   [(set (reg FLAGS_REG)
13078         (compare
13079           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13080                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13081           (const_int 0)))
13082    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13083         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13084   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13085    && ix86_match_ccmode (insn, CCGOCmode)
13086    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13087   "shr{l}\t{%2, %0|%0, %2}"
13088   [(set_attr "type" "ishift")
13089    (set_attr "mode" "SI")])
13090
13091 (define_insn "*lshrsi3_cconly"
13092   [(set (reg FLAGS_REG)
13093       (compare
13094         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13095                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13096         (const_int 0)))
13097    (clobber (match_scratch:SI 0 "=r"))]
13098   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13099    && ix86_match_ccmode (insn, CCGOCmode)
13100    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13101   "shr{l}\t{%2, %0|%0, %2}"
13102   [(set_attr "type" "ishift")
13103    (set_attr "mode" "SI")])
13104
13105 (define_insn "*lshrsi3_cmp_zext"
13106   [(set (reg FLAGS_REG)
13107         (compare
13108           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13109                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13110           (const_int 0)))
13111    (set (match_operand:DI 0 "register_operand" "=r")
13112         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13113   "TARGET_64BIT
13114    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13115    && ix86_match_ccmode (insn, CCGOCmode)
13116    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13117   "shr{l}\t{%2, %k0|%k0, %2}"
13118   [(set_attr "type" "ishift")
13119    (set_attr "mode" "SI")])
13120
13121 (define_expand "lshrhi3"
13122   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13123         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13124                      (match_operand:QI 2 "nonmemory_operand" "")))]
13125   "TARGET_HIMODE_MATH"
13126   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13127
13128 (define_insn "*lshrhi3_1_one_bit"
13129   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13130         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13131                      (match_operand:QI 2 "const1_operand" "")))
13132    (clobber (reg:CC FLAGS_REG))]
13133   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13134    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13135   "shr{w}\t%0"
13136   [(set_attr "type" "ishift")
13137    (set_attr "length_immediate" "0")
13138    (set_attr "mode" "HI")])
13139
13140 (define_insn "*lshrhi3_1"
13141   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13142         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13143                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13144    (clobber (reg:CC FLAGS_REG))]
13145   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13146   "@
13147    shr{w}\t{%2, %0|%0, %2}
13148    shr{w}\t{%b2, %0|%0, %b2}"
13149   [(set_attr "type" "ishift")
13150    (set_attr "mode" "HI")])
13151
13152 ;; This pattern can't accept a variable shift count, since shifts by
13153 ;; zero don't affect the flags.  We assume that shifts by constant
13154 ;; zero are optimized away.
13155 (define_insn "*lshrhi3_one_bit_cmp"
13156   [(set (reg FLAGS_REG)
13157         (compare
13158           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13159                        (match_operand:QI 2 "const1_operand" ""))
13160           (const_int 0)))
13161    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13162         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13163   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13164    && ix86_match_ccmode (insn, CCGOCmode)
13165    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13166   "shr{w}\t%0"
13167   [(set_attr "type" "ishift")
13168    (set_attr "length_immediate" "0")
13169    (set_attr "mode" "HI")])
13170
13171 (define_insn "*lshrhi3_one_bit_cconly"
13172   [(set (reg FLAGS_REG)
13173         (compare
13174           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13175                        (match_operand:QI 2 "const1_operand" ""))
13176           (const_int 0)))
13177    (clobber (match_scratch:HI 0 "=r"))]
13178   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13179    && ix86_match_ccmode (insn, CCGOCmode)
13180    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13181   "shr{w}\t%0"
13182   [(set_attr "type" "ishift")
13183    (set_attr "length_immediate" "0")
13184    (set_attr "mode" "HI")])
13185
13186 ;; This pattern can't accept a variable shift count, since shifts by
13187 ;; zero don't affect the flags.  We assume that shifts by constant
13188 ;; zero are optimized away.
13189 (define_insn "*lshrhi3_cmp"
13190   [(set (reg FLAGS_REG)
13191         (compare
13192           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13193                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13194           (const_int 0)))
13195    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13196         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13197   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13198    && ix86_match_ccmode (insn, CCGOCmode)
13199    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13200   "shr{w}\t{%2, %0|%0, %2}"
13201   [(set_attr "type" "ishift")
13202    (set_attr "mode" "HI")])
13203
13204 (define_insn "*lshrhi3_cconly"
13205   [(set (reg FLAGS_REG)
13206         (compare
13207           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13208                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13209           (const_int 0)))
13210    (clobber (match_scratch:HI 0 "=r"))]
13211   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13212    && ix86_match_ccmode (insn, CCGOCmode)
13213    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13214   "shr{w}\t{%2, %0|%0, %2}"
13215   [(set_attr "type" "ishift")
13216    (set_attr "mode" "HI")])
13217
13218 (define_expand "lshrqi3"
13219   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13220         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13221                      (match_operand:QI 2 "nonmemory_operand" "")))]
13222   "TARGET_QIMODE_MATH"
13223   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13224
13225 (define_insn "*lshrqi3_1_one_bit"
13226   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13227         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13228                      (match_operand:QI 2 "const1_operand" "")))
13229    (clobber (reg:CC FLAGS_REG))]
13230   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13231    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13232   "shr{b}\t%0"
13233   [(set_attr "type" "ishift")
13234    (set_attr "length_immediate" "0")
13235    (set_attr "mode" "QI")])
13236
13237 (define_insn "*lshrqi3_1_one_bit_slp"
13238   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13239         (lshiftrt:QI (match_dup 0)
13240                      (match_operand:QI 1 "const1_operand" "")))
13241    (clobber (reg:CC FLAGS_REG))]
13242   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13243    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13244   "shr{b}\t%0"
13245   [(set_attr "type" "ishift1")
13246    (set_attr "length_immediate" "0")
13247    (set_attr "mode" "QI")])
13248
13249 (define_insn "*lshrqi3_1"
13250   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13251         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13252                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13253    (clobber (reg:CC FLAGS_REG))]
13254   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13255   "@
13256    shr{b}\t{%2, %0|%0, %2}
13257    shr{b}\t{%b2, %0|%0, %b2}"
13258   [(set_attr "type" "ishift")
13259    (set_attr "mode" "QI")])
13260
13261 (define_insn "*lshrqi3_1_slp"
13262   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13263         (lshiftrt:QI (match_dup 0)
13264                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13265    (clobber (reg:CC FLAGS_REG))]
13266   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13267    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13268   "@
13269    shr{b}\t{%1, %0|%0, %1}
13270    shr{b}\t{%b1, %0|%0, %b1}"
13271   [(set_attr "type" "ishift1")
13272    (set_attr "mode" "QI")])
13273
13274 ;; This pattern can't accept a variable shift count, since shifts by
13275 ;; zero don't affect the flags.  We assume that shifts by constant
13276 ;; zero are optimized away.
13277 (define_insn "*lshrqi2_one_bit_cmp"
13278   [(set (reg FLAGS_REG)
13279         (compare
13280           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13281                        (match_operand:QI 2 "const1_operand" ""))
13282           (const_int 0)))
13283    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13284         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13285   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13286    && ix86_match_ccmode (insn, CCGOCmode)
13287    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13288   "shr{b}\t%0"
13289   [(set_attr "type" "ishift")
13290    (set_attr "length_immediate" "0")
13291    (set_attr "mode" "QI")])
13292
13293 (define_insn "*lshrqi2_one_bit_cconly"
13294   [(set (reg FLAGS_REG)
13295         (compare
13296           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13297                        (match_operand:QI 2 "const1_operand" ""))
13298           (const_int 0)))
13299    (clobber (match_scratch:QI 0 "=q"))]
13300   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13301    && ix86_match_ccmode (insn, CCGOCmode)
13302    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13303   "shr{b}\t%0"
13304   [(set_attr "type" "ishift")
13305    (set_attr "length_immediate" "0")
13306    (set_attr "mode" "QI")])
13307
13308 ;; This pattern can't accept a variable shift count, since shifts by
13309 ;; zero don't affect the flags.  We assume that shifts by constant
13310 ;; zero are optimized away.
13311 (define_insn "*lshrqi2_cmp"
13312   [(set (reg FLAGS_REG)
13313         (compare
13314           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13315                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13316           (const_int 0)))
13317    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13318         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13319   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13320    && ix86_match_ccmode (insn, CCGOCmode)
13321    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13322   "shr{b}\t{%2, %0|%0, %2}"
13323   [(set_attr "type" "ishift")
13324    (set_attr "mode" "QI")])
13325
13326 (define_insn "*lshrqi2_cconly"
13327   [(set (reg FLAGS_REG)
13328         (compare
13329           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13331           (const_int 0)))
13332    (clobber (match_scratch:QI 0 "=q"))]
13333   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13334    && ix86_match_ccmode (insn, CCGOCmode)
13335    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336   "shr{b}\t{%2, %0|%0, %2}"
13337   [(set_attr "type" "ishift")
13338    (set_attr "mode" "QI")])
13339 \f
13340 ;; Rotate instructions
13341
13342 (define_expand "rotldi3"
13343   [(set (match_operand:DI 0 "shiftdi_operand" "")
13344         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13345                    (match_operand:QI 2 "nonmemory_operand" "")))]
13346  ""
13347 {
13348   if (TARGET_64BIT)
13349     {
13350       ix86_expand_binary_operator (ROTATE, DImode, operands);
13351       DONE;
13352     }
13353   if (!const_1_to_31_operand (operands[2], VOIDmode))
13354     FAIL;
13355   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13356   DONE;
13357 })
13358
13359 ;; Implement rotation using two double-precision shift instructions
13360 ;; and a scratch register.
13361 (define_insn_and_split "ix86_rotldi3"
13362  [(set (match_operand:DI 0 "register_operand" "=r")
13363        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13364                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13365   (clobber (reg:CC FLAGS_REG))
13366   (clobber (match_scratch:SI 3 "=&r"))]
13367  "!TARGET_64BIT"
13368  ""
13369  "&& reload_completed"
13370  [(set (match_dup 3) (match_dup 4))
13371   (parallel
13372    [(set (match_dup 4)
13373          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13374                  (lshiftrt:SI (match_dup 5)
13375                               (minus:QI (const_int 32) (match_dup 2)))))
13376     (clobber (reg:CC FLAGS_REG))])
13377   (parallel
13378    [(set (match_dup 5)
13379          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13380                  (lshiftrt:SI (match_dup 3)
13381                               (minus:QI (const_int 32) (match_dup 2)))))
13382     (clobber (reg:CC FLAGS_REG))])]
13383  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13384
13385 (define_insn "*rotlsi3_1_one_bit_rex64"
13386   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13387         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13388                    (match_operand:QI 2 "const1_operand" "")))
13389    (clobber (reg:CC FLAGS_REG))]
13390   "TARGET_64BIT
13391    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13392    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13393   "rol{q}\t%0"
13394   [(set_attr "type" "rotate")
13395    (set_attr "length_immediate" "0")
13396    (set_attr "mode" "DI")])
13397
13398 (define_insn "*rotldi3_1_rex64"
13399   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13400         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13401                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13402    (clobber (reg:CC FLAGS_REG))]
13403   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13404   "@
13405    rol{q}\t{%2, %0|%0, %2}
13406    rol{q}\t{%b2, %0|%0, %b2}"
13407   [(set_attr "type" "rotate")
13408    (set_attr "mode" "DI")])
13409
13410 (define_expand "rotlsi3"
13411   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13412         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13413                    (match_operand:QI 2 "nonmemory_operand" "")))]
13414   ""
13415   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13416
13417 (define_insn "*rotlsi3_1_one_bit"
13418   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13419         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13420                    (match_operand:QI 2 "const1_operand" "")))
13421    (clobber (reg:CC FLAGS_REG))]
13422   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13423    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13424   "rol{l}\t%0"
13425   [(set_attr "type" "rotate")
13426    (set_attr "length_immediate" "0")
13427    (set_attr "mode" "SI")])
13428
13429 (define_insn "*rotlsi3_1_one_bit_zext"
13430   [(set (match_operand:DI 0 "register_operand" "=r")
13431         (zero_extend:DI
13432           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13433                      (match_operand:QI 2 "const1_operand" ""))))
13434    (clobber (reg:CC FLAGS_REG))]
13435   "TARGET_64BIT
13436    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13437    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13438   "rol{l}\t%k0"
13439   [(set_attr "type" "rotate")
13440    (set_attr "length_immediate" "0")
13441    (set_attr "mode" "SI")])
13442
13443 (define_insn "*rotlsi3_1"
13444   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13445         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13446                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13447    (clobber (reg:CC FLAGS_REG))]
13448   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13449   "@
13450    rol{l}\t{%2, %0|%0, %2}
13451    rol{l}\t{%b2, %0|%0, %b2}"
13452   [(set_attr "type" "rotate")
13453    (set_attr "mode" "SI")])
13454
13455 (define_insn "*rotlsi3_1_zext"
13456   [(set (match_operand:DI 0 "register_operand" "=r,r")
13457         (zero_extend:DI
13458           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13459                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13460    (clobber (reg:CC FLAGS_REG))]
13461   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13462   "@
13463    rol{l}\t{%2, %k0|%k0, %2}
13464    rol{l}\t{%b2, %k0|%k0, %b2}"
13465   [(set_attr "type" "rotate")
13466    (set_attr "mode" "SI")])
13467
13468 (define_expand "rotlhi3"
13469   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13470         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13471                    (match_operand:QI 2 "nonmemory_operand" "")))]
13472   "TARGET_HIMODE_MATH"
13473   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13474
13475 (define_insn "*rotlhi3_1_one_bit"
13476   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13477         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13478                    (match_operand:QI 2 "const1_operand" "")))
13479    (clobber (reg:CC FLAGS_REG))]
13480   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13481    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13482   "rol{w}\t%0"
13483   [(set_attr "type" "rotate")
13484    (set_attr "length_immediate" "0")
13485    (set_attr "mode" "HI")])
13486
13487 (define_insn "*rotlhi3_1"
13488   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13489         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13490                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13491    (clobber (reg:CC FLAGS_REG))]
13492   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13493   "@
13494    rol{w}\t{%2, %0|%0, %2}
13495    rol{w}\t{%b2, %0|%0, %b2}"
13496   [(set_attr "type" "rotate")
13497    (set_attr "mode" "HI")])
13498
13499 (define_split
13500  [(set (match_operand:HI 0 "register_operand" "")
13501        (rotate:HI (match_dup 0) (const_int 8)))
13502   (clobber (reg:CC FLAGS_REG))]
13503  "reload_completed"
13504  [(parallel [(set (strict_low_part (match_dup 0))
13505                   (bswap:HI (match_dup 0)))
13506              (clobber (reg:CC FLAGS_REG))])]
13507  "")
13508
13509 (define_expand "rotlqi3"
13510   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13511         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13512                    (match_operand:QI 2 "nonmemory_operand" "")))]
13513   "TARGET_QIMODE_MATH"
13514   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13515
13516 (define_insn "*rotlqi3_1_one_bit_slp"
13517   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13518         (rotate:QI (match_dup 0)
13519                    (match_operand:QI 1 "const1_operand" "")))
13520    (clobber (reg:CC FLAGS_REG))]
13521   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13522    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13523   "rol{b}\t%0"
13524   [(set_attr "type" "rotate1")
13525    (set_attr "length_immediate" "0")
13526    (set_attr "mode" "QI")])
13527
13528 (define_insn "*rotlqi3_1_one_bit"
13529   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13530         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13531                    (match_operand:QI 2 "const1_operand" "")))
13532    (clobber (reg:CC FLAGS_REG))]
13533   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13534    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13535   "rol{b}\t%0"
13536   [(set_attr "type" "rotate")
13537    (set_attr "length_immediate" "0")
13538    (set_attr "mode" "QI")])
13539
13540 (define_insn "*rotlqi3_1_slp"
13541   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13542         (rotate:QI (match_dup 0)
13543                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13544    (clobber (reg:CC FLAGS_REG))]
13545   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13546    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13547   "@
13548    rol{b}\t{%1, %0|%0, %1}
13549    rol{b}\t{%b1, %0|%0, %b1}"
13550   [(set_attr "type" "rotate1")
13551    (set_attr "mode" "QI")])
13552
13553 (define_insn "*rotlqi3_1"
13554   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13555         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13556                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13557    (clobber (reg:CC FLAGS_REG))]
13558   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13559   "@
13560    rol{b}\t{%2, %0|%0, %2}
13561    rol{b}\t{%b2, %0|%0, %b2}"
13562   [(set_attr "type" "rotate")
13563    (set_attr "mode" "QI")])
13564
13565 (define_expand "rotrdi3"
13566   [(set (match_operand:DI 0 "shiftdi_operand" "")
13567         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13568                    (match_operand:QI 2 "nonmemory_operand" "")))]
13569  ""
13570 {
13571   if (TARGET_64BIT)
13572     {
13573       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13574       DONE;
13575     }
13576   if (!const_1_to_31_operand (operands[2], VOIDmode))
13577     FAIL;
13578   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13579   DONE;
13580 })
13581
13582 ;; Implement rotation using two double-precision shift instructions
13583 ;; and a scratch register.
13584 (define_insn_and_split "ix86_rotrdi3"
13585  [(set (match_operand:DI 0 "register_operand" "=r")
13586        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13587                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13588   (clobber (reg:CC FLAGS_REG))
13589   (clobber (match_scratch:SI 3 "=&r"))]
13590  "!TARGET_64BIT"
13591  ""
13592  "&& reload_completed"
13593  [(set (match_dup 3) (match_dup 4))
13594   (parallel
13595    [(set (match_dup 4)
13596          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13597                  (ashift:SI (match_dup 5)
13598                             (minus:QI (const_int 32) (match_dup 2)))))
13599     (clobber (reg:CC FLAGS_REG))])
13600   (parallel
13601    [(set (match_dup 5)
13602          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13603                  (ashift:SI (match_dup 3)
13604                             (minus:QI (const_int 32) (match_dup 2)))))
13605     (clobber (reg:CC FLAGS_REG))])]
13606  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13607
13608 (define_insn "*rotrdi3_1_one_bit_rex64"
13609   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13610         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13611                      (match_operand:QI 2 "const1_operand" "")))
13612    (clobber (reg:CC FLAGS_REG))]
13613   "TARGET_64BIT
13614    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13615    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13616   "ror{q}\t%0"
13617   [(set_attr "type" "rotate")
13618    (set_attr "length_immediate" "0")
13619    (set_attr "mode" "DI")])
13620
13621 (define_insn "*rotrdi3_1_rex64"
13622   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13623         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13624                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13625    (clobber (reg:CC FLAGS_REG))]
13626   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13627   "@
13628    ror{q}\t{%2, %0|%0, %2}
13629    ror{q}\t{%b2, %0|%0, %b2}"
13630   [(set_attr "type" "rotate")
13631    (set_attr "mode" "DI")])
13632
13633 (define_expand "rotrsi3"
13634   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13635         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13636                      (match_operand:QI 2 "nonmemory_operand" "")))]
13637   ""
13638   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13639
13640 (define_insn "*rotrsi3_1_one_bit"
13641   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13642         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13643                      (match_operand:QI 2 "const1_operand" "")))
13644    (clobber (reg:CC FLAGS_REG))]
13645   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13646    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13647   "ror{l}\t%0"
13648   [(set_attr "type" "rotate")
13649    (set_attr "length_immediate" "0")
13650    (set_attr "mode" "SI")])
13651
13652 (define_insn "*rotrsi3_1_one_bit_zext"
13653   [(set (match_operand:DI 0 "register_operand" "=r")
13654         (zero_extend:DI
13655           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13656                        (match_operand:QI 2 "const1_operand" ""))))
13657    (clobber (reg:CC FLAGS_REG))]
13658   "TARGET_64BIT
13659    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13660    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13661   "ror{l}\t%k0"
13662   [(set_attr "type" "rotate")
13663    (set_attr "length_immediate" "0")
13664    (set_attr "mode" "SI")])
13665
13666 (define_insn "*rotrsi3_1"
13667   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13668         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13669                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13670    (clobber (reg:CC FLAGS_REG))]
13671   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13672   "@
13673    ror{l}\t{%2, %0|%0, %2}
13674    ror{l}\t{%b2, %0|%0, %b2}"
13675   [(set_attr "type" "rotate")
13676    (set_attr "mode" "SI")])
13677
13678 (define_insn "*rotrsi3_1_zext"
13679   [(set (match_operand:DI 0 "register_operand" "=r,r")
13680         (zero_extend:DI
13681           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13682                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13683    (clobber (reg:CC FLAGS_REG))]
13684   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13685   "@
13686    ror{l}\t{%2, %k0|%k0, %2}
13687    ror{l}\t{%b2, %k0|%k0, %b2}"
13688   [(set_attr "type" "rotate")
13689    (set_attr "mode" "SI")])
13690
13691 (define_expand "rotrhi3"
13692   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13693         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13694                      (match_operand:QI 2 "nonmemory_operand" "")))]
13695   "TARGET_HIMODE_MATH"
13696   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13697
13698 (define_insn "*rotrhi3_one_bit"
13699   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13700         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13701                      (match_operand:QI 2 "const1_operand" "")))
13702    (clobber (reg:CC FLAGS_REG))]
13703   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13705   "ror{w}\t%0"
13706   [(set_attr "type" "rotate")
13707    (set_attr "length_immediate" "0")
13708    (set_attr "mode" "HI")])
13709
13710 (define_insn "*rotrhi3_1"
13711   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13712         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13713                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13714    (clobber (reg:CC FLAGS_REG))]
13715   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13716   "@
13717    ror{w}\t{%2, %0|%0, %2}
13718    ror{w}\t{%b2, %0|%0, %b2}"
13719   [(set_attr "type" "rotate")
13720    (set_attr "mode" "HI")])
13721
13722 (define_split
13723  [(set (match_operand:HI 0 "register_operand" "")
13724        (rotatert:HI (match_dup 0) (const_int 8)))
13725   (clobber (reg:CC FLAGS_REG))]
13726  "reload_completed"
13727  [(parallel [(set (strict_low_part (match_dup 0))
13728                   (bswap:HI (match_dup 0)))
13729              (clobber (reg:CC FLAGS_REG))])]
13730  "")
13731
13732 (define_expand "rotrqi3"
13733   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13734         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13735                      (match_operand:QI 2 "nonmemory_operand" "")))]
13736   "TARGET_QIMODE_MATH"
13737   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13738
13739 (define_insn "*rotrqi3_1_one_bit"
13740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13741         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13742                      (match_operand:QI 2 "const1_operand" "")))
13743    (clobber (reg:CC FLAGS_REG))]
13744   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13745    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13746   "ror{b}\t%0"
13747   [(set_attr "type" "rotate")
13748    (set_attr "length_immediate" "0")
13749    (set_attr "mode" "QI")])
13750
13751 (define_insn "*rotrqi3_1_one_bit_slp"
13752   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13753         (rotatert:QI (match_dup 0)
13754                      (match_operand:QI 1 "const1_operand" "")))
13755    (clobber (reg:CC FLAGS_REG))]
13756   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13757    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13758   "ror{b}\t%0"
13759   [(set_attr "type" "rotate1")
13760    (set_attr "length_immediate" "0")
13761    (set_attr "mode" "QI")])
13762
13763 (define_insn "*rotrqi3_1"
13764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13765         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13766                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13767    (clobber (reg:CC FLAGS_REG))]
13768   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13769   "@
13770    ror{b}\t{%2, %0|%0, %2}
13771    ror{b}\t{%b2, %0|%0, %b2}"
13772   [(set_attr "type" "rotate")
13773    (set_attr "mode" "QI")])
13774
13775 (define_insn "*rotrqi3_1_slp"
13776   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13777         (rotatert:QI (match_dup 0)
13778                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13779    (clobber (reg:CC FLAGS_REG))]
13780   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13781    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13782   "@
13783    ror{b}\t{%1, %0|%0, %1}
13784    ror{b}\t{%b1, %0|%0, %b1}"
13785   [(set_attr "type" "rotate1")
13786    (set_attr "mode" "QI")])
13787 \f
13788 ;; Bit set / bit test instructions
13789
13790 (define_expand "extv"
13791   [(set (match_operand:SI 0 "register_operand" "")
13792         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13793                          (match_operand:SI 2 "const8_operand" "")
13794                          (match_operand:SI 3 "const8_operand" "")))]
13795   ""
13796 {
13797   /* Handle extractions from %ah et al.  */
13798   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13799     FAIL;
13800
13801   /* From mips.md: extract_bit_field doesn't verify that our source
13802      matches the predicate, so check it again here.  */
13803   if (! ext_register_operand (operands[1], VOIDmode))
13804     FAIL;
13805 })
13806
13807 (define_expand "extzv"
13808   [(set (match_operand:SI 0 "register_operand" "")
13809         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13810                          (match_operand:SI 2 "const8_operand" "")
13811                          (match_operand:SI 3 "const8_operand" "")))]
13812   ""
13813 {
13814   /* Handle extractions from %ah et al.  */
13815   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13816     FAIL;
13817
13818   /* From mips.md: extract_bit_field doesn't verify that our source
13819      matches the predicate, so check it again here.  */
13820   if (! ext_register_operand (operands[1], VOIDmode))
13821     FAIL;
13822 })
13823
13824 (define_expand "insv"
13825   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13826                       (match_operand 1 "const8_operand" "")
13827                       (match_operand 2 "const8_operand" ""))
13828         (match_operand 3 "register_operand" ""))]
13829   ""
13830 {
13831   /* Handle insertions to %ah et al.  */
13832   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13833     FAIL;
13834
13835   /* From mips.md: insert_bit_field doesn't verify that our source
13836      matches the predicate, so check it again here.  */
13837   if (! ext_register_operand (operands[0], VOIDmode))
13838     FAIL;
13839
13840   if (TARGET_64BIT)
13841     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13842   else
13843     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13844
13845   DONE;
13846 })
13847
13848 ;; %%% bts, btr, btc, bt.
13849 ;; In general these instructions are *slow* when applied to memory,
13850 ;; since they enforce atomic operation.  When applied to registers,
13851 ;; it depends on the cpu implementation.  They're never faster than
13852 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13853 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13854 ;; within the instruction itself, so operating on bits in the high
13855 ;; 32-bits of a register becomes easier.
13856 ;;
13857 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13858 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13859 ;; negdf respectively, so they can never be disabled entirely.
13860
13861 (define_insn "*btsq"
13862   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13863                          (const_int 1)
13864                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13865         (const_int 1))
13866    (clobber (reg:CC FLAGS_REG))]
13867   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13868   "bts{q}\t{%1, %0|%0, %1}"
13869   [(set_attr "type" "alu1")
13870    (set_attr "prefix_0f" "1")
13871    (set_attr "mode" "DI")])
13872
13873 (define_insn "*btrq"
13874   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13875                          (const_int 1)
13876                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13877         (const_int 0))
13878    (clobber (reg:CC FLAGS_REG))]
13879   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13880   "btr{q}\t{%1, %0|%0, %1}"
13881   [(set_attr "type" "alu1")
13882    (set_attr "prefix_0f" "1")
13883    (set_attr "mode" "DI")])
13884
13885 (define_insn "*btcq"
13886   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13887                          (const_int 1)
13888                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13889         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13890    (clobber (reg:CC FLAGS_REG))]
13891   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13892   "btc{q}\t{%1, %0|%0, %1}"
13893   [(set_attr "type" "alu1")
13894    (set_attr "prefix_0f" "1")
13895    (set_attr "mode" "DI")])
13896
13897 ;; Allow Nocona to avoid these instructions if a register is available.
13898
13899 (define_peephole2
13900   [(match_scratch:DI 2 "r")
13901    (parallel [(set (zero_extract:DI
13902                      (match_operand:DI 0 "register_operand" "")
13903                      (const_int 1)
13904                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13905                    (const_int 1))
13906               (clobber (reg:CC FLAGS_REG))])]
13907   "TARGET_64BIT && !TARGET_USE_BT"
13908   [(const_int 0)]
13909 {
13910   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13911   rtx op1;
13912
13913   if (HOST_BITS_PER_WIDE_INT >= 64)
13914     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13915   else if (i < HOST_BITS_PER_WIDE_INT)
13916     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13917   else
13918     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13919
13920   op1 = immed_double_const (lo, hi, DImode);
13921   if (i >= 31)
13922     {
13923       emit_move_insn (operands[2], op1);
13924       op1 = operands[2];
13925     }
13926
13927   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13928   DONE;
13929 })
13930
13931 (define_peephole2
13932   [(match_scratch:DI 2 "r")
13933    (parallel [(set (zero_extract:DI
13934                      (match_operand:DI 0 "register_operand" "")
13935                      (const_int 1)
13936                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13937                    (const_int 0))
13938               (clobber (reg:CC FLAGS_REG))])]
13939   "TARGET_64BIT && !TARGET_USE_BT"
13940   [(const_int 0)]
13941 {
13942   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13943   rtx op1;
13944
13945   if (HOST_BITS_PER_WIDE_INT >= 64)
13946     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13947   else if (i < HOST_BITS_PER_WIDE_INT)
13948     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13949   else
13950     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13951
13952   op1 = immed_double_const (~lo, ~hi, DImode);
13953   if (i >= 32)
13954     {
13955       emit_move_insn (operands[2], op1);
13956       op1 = operands[2];
13957     }
13958
13959   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13960   DONE;
13961 })
13962
13963 (define_peephole2
13964   [(match_scratch:DI 2 "r")
13965    (parallel [(set (zero_extract:DI
13966                      (match_operand:DI 0 "register_operand" "")
13967                      (const_int 1)
13968                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13969               (not:DI (zero_extract:DI
13970                         (match_dup 0) (const_int 1) (match_dup 1))))
13971               (clobber (reg:CC FLAGS_REG))])]
13972   "TARGET_64BIT && !TARGET_USE_BT"
13973   [(const_int 0)]
13974 {
13975   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13976   rtx op1;
13977
13978   if (HOST_BITS_PER_WIDE_INT >= 64)
13979     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13980   else if (i < HOST_BITS_PER_WIDE_INT)
13981     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13982   else
13983     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13984
13985   op1 = immed_double_const (lo, hi, DImode);
13986   if (i >= 31)
13987     {
13988       emit_move_insn (operands[2], op1);
13989       op1 = operands[2];
13990     }
13991
13992   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13993   DONE;
13994 })
13995
13996 (define_insn "*btdi_rex64"
13997   [(set (reg:CCC FLAGS_REG)
13998         (compare:CCC
13999           (zero_extract:DI
14000             (match_operand:DI 0 "register_operand" "r")
14001             (const_int 1)
14002             (match_operand:DI 1 "nonmemory_operand" "rN"))
14003           (const_int 0)))]
14004   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14005   "bt{q}\t{%1, %0|%0, %1}"
14006   [(set_attr "type" "alu1")
14007    (set_attr "prefix_0f" "1")
14008    (set_attr "mode" "DI")])
14009
14010 (define_insn "*btsi"
14011   [(set (reg:CCC FLAGS_REG)
14012         (compare:CCC
14013           (zero_extract:SI
14014             (match_operand:SI 0 "register_operand" "r")
14015             (const_int 1)
14016             (match_operand:SI 1 "nonmemory_operand" "rN"))
14017           (const_int 0)))]
14018   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14019   "bt{l}\t{%1, %0|%0, %1}"
14020   [(set_attr "type" "alu1")
14021    (set_attr "prefix_0f" "1")
14022    (set_attr "mode" "SI")])
14023 \f
14024 ;; Store-flag instructions.
14025
14026 ;; For all sCOND expanders, also expand the compare or test insn that
14027 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14028
14029 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14030 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14031 ;; way, which can later delete the movzx if only QImode is needed.
14032
14033 (define_insn "*setcc_1"
14034   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14035         (match_operator:QI 1 "ix86_comparison_operator"
14036           [(reg FLAGS_REG) (const_int 0)]))]
14037   ""
14038   "set%C1\t%0"
14039   [(set_attr "type" "setcc")
14040    (set_attr "mode" "QI")])
14041
14042 (define_insn "*setcc_2"
14043   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14044         (match_operator:QI 1 "ix86_comparison_operator"
14045           [(reg FLAGS_REG) (const_int 0)]))]
14046   ""
14047   "set%C1\t%0"
14048   [(set_attr "type" "setcc")
14049    (set_attr "mode" "QI")])
14050
14051 ;; In general it is not safe to assume too much about CCmode registers,
14052 ;; so simplify-rtx stops when it sees a second one.  Under certain
14053 ;; conditions this is safe on x86, so help combine not create
14054 ;;
14055 ;;      seta    %al
14056 ;;      testb   %al, %al
14057 ;;      sete    %al
14058
14059 (define_split
14060   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14061         (ne:QI (match_operator 1 "ix86_comparison_operator"
14062                  [(reg FLAGS_REG) (const_int 0)])
14063             (const_int 0)))]
14064   ""
14065   [(set (match_dup 0) (match_dup 1))]
14066 {
14067   PUT_MODE (operands[1], QImode);
14068 })
14069
14070 (define_split
14071   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14072         (ne:QI (match_operator 1 "ix86_comparison_operator"
14073                  [(reg FLAGS_REG) (const_int 0)])
14074             (const_int 0)))]
14075   ""
14076   [(set (match_dup 0) (match_dup 1))]
14077 {
14078   PUT_MODE (operands[1], QImode);
14079 })
14080
14081 (define_split
14082   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14083         (eq:QI (match_operator 1 "ix86_comparison_operator"
14084                  [(reg FLAGS_REG) (const_int 0)])
14085             (const_int 0)))]
14086   ""
14087   [(set (match_dup 0) (match_dup 1))]
14088 {
14089   rtx new_op1 = copy_rtx (operands[1]);
14090   operands[1] = new_op1;
14091   PUT_MODE (new_op1, QImode);
14092   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14093                                              GET_MODE (XEXP (new_op1, 0))));
14094
14095   /* Make sure that (a) the CCmode we have for the flags is strong
14096      enough for the reversed compare or (b) we have a valid FP compare.  */
14097   if (! ix86_comparison_operator (new_op1, VOIDmode))
14098     FAIL;
14099 })
14100
14101 (define_split
14102   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14103         (eq:QI (match_operator 1 "ix86_comparison_operator"
14104                  [(reg FLAGS_REG) (const_int 0)])
14105             (const_int 0)))]
14106   ""
14107   [(set (match_dup 0) (match_dup 1))]
14108 {
14109   rtx new_op1 = copy_rtx (operands[1]);
14110   operands[1] = new_op1;
14111   PUT_MODE (new_op1, QImode);
14112   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14113                                              GET_MODE (XEXP (new_op1, 0))));
14114
14115   /* Make sure that (a) the CCmode we have for the flags is strong
14116      enough for the reversed compare or (b) we have a valid FP compare.  */
14117   if (! ix86_comparison_operator (new_op1, VOIDmode))
14118     FAIL;
14119 })
14120
14121 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14122 ;; subsequent logical operations are used to imitate conditional moves.
14123 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14124 ;; it directly.
14125
14126 (define_insn "*avx_setcc<mode>"
14127   [(set (match_operand:MODEF 0 "register_operand" "=x")
14128         (match_operator:MODEF 1 "avx_comparison_float_operator"
14129           [(match_operand:MODEF 2 "register_operand" "x")
14130            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14131   "TARGET_AVX"
14132   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14133   [(set_attr "type" "ssecmp")
14134    (set_attr "prefix" "vex")
14135    (set_attr "length_immediate" "1")
14136    (set_attr "mode" "<MODE>")])
14137
14138 (define_insn "*sse_setcc<mode>"
14139   [(set (match_operand:MODEF 0 "register_operand" "=x")
14140         (match_operator:MODEF 1 "sse_comparison_operator"
14141           [(match_operand:MODEF 2 "register_operand" "0")
14142            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14143   "SSE_FLOAT_MODE_P (<MODE>mode)"
14144   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14145   [(set_attr "type" "ssecmp")
14146    (set_attr "length_immediate" "1")
14147    (set_attr "mode" "<MODE>")])
14148 \f
14149 ;; Basic conditional jump instructions.
14150 ;; We ignore the overflow flag for signed branch instructions.
14151
14152 (define_insn "*jcc_1"
14153   [(set (pc)
14154         (if_then_else (match_operator 1 "ix86_comparison_operator"
14155                                       [(reg FLAGS_REG) (const_int 0)])
14156                       (label_ref (match_operand 0 "" ""))
14157                       (pc)))]
14158   ""
14159   "%+j%C1\t%l0"
14160   [(set_attr "type" "ibr")
14161    (set_attr "modrm" "0")
14162    (set (attr "length")
14163            (if_then_else (and (ge (minus (match_dup 0) (pc))
14164                                   (const_int -126))
14165                               (lt (minus (match_dup 0) (pc))
14166                                   (const_int 128)))
14167              (const_int 2)
14168              (const_int 6)))])
14169
14170 (define_insn "*jcc_2"
14171   [(set (pc)
14172         (if_then_else (match_operator 1 "ix86_comparison_operator"
14173                                       [(reg FLAGS_REG) (const_int 0)])
14174                       (pc)
14175                       (label_ref (match_operand 0 "" ""))))]
14176   ""
14177   "%+j%c1\t%l0"
14178   [(set_attr "type" "ibr")
14179    (set_attr "modrm" "0")
14180    (set (attr "length")
14181            (if_then_else (and (ge (minus (match_dup 0) (pc))
14182                                   (const_int -126))
14183                               (lt (minus (match_dup 0) (pc))
14184                                   (const_int 128)))
14185              (const_int 2)
14186              (const_int 6)))])
14187
14188 ;; In general it is not safe to assume too much about CCmode registers,
14189 ;; so simplify-rtx stops when it sees a second one.  Under certain
14190 ;; conditions this is safe on x86, so help combine not create
14191 ;;
14192 ;;      seta    %al
14193 ;;      testb   %al, %al
14194 ;;      je      Lfoo
14195
14196 (define_split
14197   [(set (pc)
14198         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14199                                       [(reg FLAGS_REG) (const_int 0)])
14200                           (const_int 0))
14201                       (label_ref (match_operand 1 "" ""))
14202                       (pc)))]
14203   ""
14204   [(set (pc)
14205         (if_then_else (match_dup 0)
14206                       (label_ref (match_dup 1))
14207                       (pc)))]
14208 {
14209   PUT_MODE (operands[0], VOIDmode);
14210 })
14211
14212 (define_split
14213   [(set (pc)
14214         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14215                                       [(reg FLAGS_REG) (const_int 0)])
14216                           (const_int 0))
14217                       (label_ref (match_operand 1 "" ""))
14218                       (pc)))]
14219   ""
14220   [(set (pc)
14221         (if_then_else (match_dup 0)
14222                       (label_ref (match_dup 1))
14223                       (pc)))]
14224 {
14225   rtx new_op0 = copy_rtx (operands[0]);
14226   operands[0] = new_op0;
14227   PUT_MODE (new_op0, VOIDmode);
14228   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14229                                              GET_MODE (XEXP (new_op0, 0))));
14230
14231   /* Make sure that (a) the CCmode we have for the flags is strong
14232      enough for the reversed compare or (b) we have a valid FP compare.  */
14233   if (! ix86_comparison_operator (new_op0, VOIDmode))
14234     FAIL;
14235 })
14236
14237 ;; zero_extend in SImode is correct, since this is what combine pass
14238 ;; generates from shift insn with QImode operand.  Actually, the mode of
14239 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14240 ;; appropriate modulo of the bit offset value.
14241
14242 (define_insn_and_split "*jcc_btdi_rex64"
14243   [(set (pc)
14244         (if_then_else (match_operator 0 "bt_comparison_operator"
14245                         [(zero_extract:DI
14246                            (match_operand:DI 1 "register_operand" "r")
14247                            (const_int 1)
14248                            (zero_extend:SI
14249                              (match_operand:QI 2 "register_operand" "r")))
14250                          (const_int 0)])
14251                       (label_ref (match_operand 3 "" ""))
14252                       (pc)))
14253    (clobber (reg:CC FLAGS_REG))]
14254   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14255   "#"
14256   "&& 1"
14257   [(set (reg:CCC FLAGS_REG)
14258         (compare:CCC
14259           (zero_extract:DI
14260             (match_dup 1)
14261             (const_int 1)
14262             (match_dup 2))
14263           (const_int 0)))
14264    (set (pc)
14265         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14266                       (label_ref (match_dup 3))
14267                       (pc)))]
14268 {
14269   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14270
14271   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14272 })
14273
14274 ;; avoid useless masking of bit offset operand
14275 (define_insn_and_split "*jcc_btdi_mask_rex64"
14276   [(set (pc)
14277         (if_then_else (match_operator 0 "bt_comparison_operator"
14278                         [(zero_extract:DI
14279                            (match_operand:DI 1 "register_operand" "r")
14280                            (const_int 1)
14281                            (and:SI
14282                              (match_operand:SI 2 "register_operand" "r")
14283                              (match_operand:SI 3 "const_int_operand" "n")))])
14284                       (label_ref (match_operand 4 "" ""))
14285                       (pc)))
14286    (clobber (reg:CC FLAGS_REG))]
14287   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14288    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14289   "#"
14290   "&& 1"
14291   [(set (reg:CCC FLAGS_REG)
14292         (compare:CCC
14293           (zero_extract:DI
14294             (match_dup 1)
14295             (const_int 1)
14296             (match_dup 2))
14297           (const_int 0)))
14298    (set (pc)
14299         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14300                       (label_ref (match_dup 4))
14301                       (pc)))]
14302 {
14303   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14304
14305   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14306 })
14307
14308 (define_insn_and_split "*jcc_btsi"
14309   [(set (pc)
14310         (if_then_else (match_operator 0 "bt_comparison_operator"
14311                         [(zero_extract:SI
14312                            (match_operand:SI 1 "register_operand" "r")
14313                            (const_int 1)
14314                            (zero_extend:SI
14315                              (match_operand:QI 2 "register_operand" "r")))
14316                          (const_int 0)])
14317                       (label_ref (match_operand 3 "" ""))
14318                       (pc)))
14319    (clobber (reg:CC FLAGS_REG))]
14320   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14321   "#"
14322   "&& 1"
14323   [(set (reg:CCC FLAGS_REG)
14324         (compare:CCC
14325           (zero_extract:SI
14326             (match_dup 1)
14327             (const_int 1)
14328             (match_dup 2))
14329           (const_int 0)))
14330    (set (pc)
14331         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14332                       (label_ref (match_dup 3))
14333                       (pc)))]
14334 {
14335   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14336
14337   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14338 })
14339
14340 ;; avoid useless masking of bit offset operand
14341 (define_insn_and_split "*jcc_btsi_mask"
14342   [(set (pc)
14343         (if_then_else (match_operator 0 "bt_comparison_operator"
14344                         [(zero_extract:SI
14345                            (match_operand:SI 1 "register_operand" "r")
14346                            (const_int 1)
14347                            (and:SI
14348                              (match_operand:SI 2 "register_operand" "r")
14349                              (match_operand:SI 3 "const_int_operand" "n")))])
14350                       (label_ref (match_operand 4 "" ""))
14351                       (pc)))
14352    (clobber (reg:CC FLAGS_REG))]
14353   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14354    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14355   "#"
14356   "&& 1"
14357   [(set (reg:CCC FLAGS_REG)
14358         (compare:CCC
14359           (zero_extract:SI
14360             (match_dup 1)
14361             (const_int 1)
14362             (match_dup 2))
14363           (const_int 0)))
14364    (set (pc)
14365         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14366                       (label_ref (match_dup 4))
14367                       (pc)))]
14368   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14369
14370 (define_insn_and_split "*jcc_btsi_1"
14371   [(set (pc)
14372         (if_then_else (match_operator 0 "bt_comparison_operator"
14373                         [(and:SI
14374                            (lshiftrt:SI
14375                              (match_operand:SI 1 "register_operand" "r")
14376                              (match_operand:QI 2 "register_operand" "r"))
14377                            (const_int 1))
14378                          (const_int 0)])
14379                       (label_ref (match_operand 3 "" ""))
14380                       (pc)))
14381    (clobber (reg:CC FLAGS_REG))]
14382   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14383   "#"
14384   "&& 1"
14385   [(set (reg:CCC FLAGS_REG)
14386         (compare:CCC
14387           (zero_extract:SI
14388             (match_dup 1)
14389             (const_int 1)
14390             (match_dup 2))
14391           (const_int 0)))
14392    (set (pc)
14393         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14394                       (label_ref (match_dup 3))
14395                       (pc)))]
14396 {
14397   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14398
14399   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14400 })
14401
14402 ;; avoid useless masking of bit offset operand
14403 (define_insn_and_split "*jcc_btsi_mask_1"
14404   [(set (pc)
14405         (if_then_else
14406           (match_operator 0 "bt_comparison_operator"
14407             [(and:SI
14408                (lshiftrt:SI
14409                  (match_operand:SI 1 "register_operand" "r")
14410                  (subreg:QI
14411                    (and:SI
14412                      (match_operand:SI 2 "register_operand" "r")
14413                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14414                (const_int 1))
14415              (const_int 0)])
14416           (label_ref (match_operand 4 "" ""))
14417           (pc)))
14418    (clobber (reg:CC FLAGS_REG))]
14419   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14420    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14421   "#"
14422   "&& 1"
14423   [(set (reg:CCC FLAGS_REG)
14424         (compare:CCC
14425           (zero_extract:SI
14426             (match_dup 1)
14427             (const_int 1)
14428             (match_dup 2))
14429           (const_int 0)))
14430    (set (pc)
14431         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14432                       (label_ref (match_dup 4))
14433                       (pc)))]
14434   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14435
14436 ;; Define combination compare-and-branch fp compare instructions to help
14437 ;; combine.
14438
14439 (define_insn "*fp_jcc_3_387"
14440   [(set (pc)
14441         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14442                         [(match_operand 1 "register_operand" "f")
14443                          (match_operand 2 "nonimmediate_operand" "fm")])
14444           (label_ref (match_operand 3 "" ""))
14445           (pc)))
14446    (clobber (reg:CCFP FPSR_REG))
14447    (clobber (reg:CCFP FLAGS_REG))
14448    (clobber (match_scratch:HI 4 "=a"))]
14449   "TARGET_80387
14450    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14451    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14452    && SELECT_CC_MODE (GET_CODE (operands[0]),
14453                       operands[1], operands[2]) == CCFPmode
14454    && !TARGET_CMOVE"
14455   "#")
14456
14457 (define_insn "*fp_jcc_4_387"
14458   [(set (pc)
14459         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14460                         [(match_operand 1 "register_operand" "f")
14461                          (match_operand 2 "nonimmediate_operand" "fm")])
14462           (pc)
14463           (label_ref (match_operand 3 "" ""))))
14464    (clobber (reg:CCFP FPSR_REG))
14465    (clobber (reg:CCFP FLAGS_REG))
14466    (clobber (match_scratch:HI 4 "=a"))]
14467   "TARGET_80387
14468    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14469    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14470    && SELECT_CC_MODE (GET_CODE (operands[0]),
14471                       operands[1], operands[2]) == CCFPmode
14472    && !TARGET_CMOVE"
14473   "#")
14474
14475 (define_insn "*fp_jcc_5_387"
14476   [(set (pc)
14477         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14478                         [(match_operand 1 "register_operand" "f")
14479                          (match_operand 2 "register_operand" "f")])
14480           (label_ref (match_operand 3 "" ""))
14481           (pc)))
14482    (clobber (reg:CCFP FPSR_REG))
14483    (clobber (reg:CCFP FLAGS_REG))
14484    (clobber (match_scratch:HI 4 "=a"))]
14485   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14486    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14487    && !TARGET_CMOVE"
14488   "#")
14489
14490 (define_insn "*fp_jcc_6_387"
14491   [(set (pc)
14492         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14493                         [(match_operand 1 "register_operand" "f")
14494                          (match_operand 2 "register_operand" "f")])
14495           (pc)
14496           (label_ref (match_operand 3 "" ""))))
14497    (clobber (reg:CCFP FPSR_REG))
14498    (clobber (reg:CCFP FLAGS_REG))
14499    (clobber (match_scratch:HI 4 "=a"))]
14500   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14501    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14502    && !TARGET_CMOVE"
14503   "#")
14504
14505 (define_insn "*fp_jcc_7_387"
14506   [(set (pc)
14507         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14508                         [(match_operand 1 "register_operand" "f")
14509                          (match_operand 2 "const0_operand" "")])
14510           (label_ref (match_operand 3 "" ""))
14511           (pc)))
14512    (clobber (reg:CCFP FPSR_REG))
14513    (clobber (reg:CCFP FLAGS_REG))
14514    (clobber (match_scratch:HI 4 "=a"))]
14515   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14516    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14517    && SELECT_CC_MODE (GET_CODE (operands[0]),
14518                       operands[1], operands[2]) == CCFPmode
14519    && !TARGET_CMOVE"
14520   "#")
14521
14522 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14523 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14524 ;; with a precedence over other operators and is always put in the first
14525 ;; place. Swap condition and operands to match ficom instruction.
14526
14527 (define_insn "*fp_jcc_8<mode>_387"
14528   [(set (pc)
14529         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14530                         [(match_operator 1 "float_operator"
14531                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14532                            (match_operand 3 "register_operand" "f,f")])
14533           (label_ref (match_operand 4 "" ""))
14534           (pc)))
14535    (clobber (reg:CCFP FPSR_REG))
14536    (clobber (reg:CCFP FLAGS_REG))
14537    (clobber (match_scratch:HI 5 "=a,a"))]
14538   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14539    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14540    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14541    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14542    && !TARGET_CMOVE"
14543   "#")
14544
14545 (define_split
14546   [(set (pc)
14547         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14548                         [(match_operand 1 "register_operand" "")
14549                          (match_operand 2 "nonimmediate_operand" "")])
14550           (match_operand 3 "" "")
14551           (match_operand 4 "" "")))
14552    (clobber (reg:CCFP FPSR_REG))
14553    (clobber (reg:CCFP FLAGS_REG))]
14554   "reload_completed"
14555   [(const_int 0)]
14556 {
14557   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14558                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14559   DONE;
14560 })
14561
14562 (define_split
14563   [(set (pc)
14564         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14565                         [(match_operand 1 "register_operand" "")
14566                          (match_operand 2 "general_operand" "")])
14567           (match_operand 3 "" "")
14568           (match_operand 4 "" "")))
14569    (clobber (reg:CCFP FPSR_REG))
14570    (clobber (reg:CCFP FLAGS_REG))
14571    (clobber (match_scratch:HI 5 "=a"))]
14572   "reload_completed"
14573   [(const_int 0)]
14574 {
14575   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14576                         operands[3], operands[4], operands[5], NULL_RTX);
14577   DONE;
14578 })
14579
14580 (define_split
14581   [(set (pc)
14582         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14583                         [(match_operator 1 "float_operator"
14584                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14585                            (match_operand 3 "register_operand" "")])
14586           (match_operand 4 "" "")
14587           (match_operand 5 "" "")))
14588    (clobber (reg:CCFP FPSR_REG))
14589    (clobber (reg:CCFP FLAGS_REG))
14590    (clobber (match_scratch:HI 6 "=a"))]
14591   "reload_completed"
14592   [(const_int 0)]
14593 {
14594   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14595   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14596                         operands[3], operands[7],
14597                         operands[4], operands[5], operands[6], NULL_RTX);
14598   DONE;
14599 })
14600
14601 ;; %%% Kill this when reload knows how to do it.
14602 (define_split
14603   [(set (pc)
14604         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14605                         [(match_operator 1 "float_operator"
14606                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14607                            (match_operand 3 "register_operand" "")])
14608           (match_operand 4 "" "")
14609           (match_operand 5 "" "")))
14610    (clobber (reg:CCFP FPSR_REG))
14611    (clobber (reg:CCFP FLAGS_REG))
14612    (clobber (match_scratch:HI 6 "=a"))]
14613   "reload_completed"
14614   [(const_int 0)]
14615 {
14616   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14617   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14618   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14619                         operands[3], operands[7],
14620                         operands[4], operands[5], operands[6], operands[2]);
14621   DONE;
14622 })
14623 \f
14624 ;; Unconditional and other jump instructions
14625
14626 (define_insn "jump"
14627   [(set (pc)
14628         (label_ref (match_operand 0 "" "")))]
14629   ""
14630   "jmp\t%l0"
14631   [(set_attr "type" "ibr")
14632    (set (attr "length")
14633            (if_then_else (and (ge (minus (match_dup 0) (pc))
14634                                   (const_int -126))
14635                               (lt (minus (match_dup 0) (pc))
14636                                   (const_int 128)))
14637              (const_int 2)
14638              (const_int 5)))
14639    (set_attr "modrm" "0")])
14640
14641 (define_expand "indirect_jump"
14642   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14643   ""
14644   "")
14645
14646 (define_insn "*indirect_jump"
14647   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14648   ""
14649   "jmp\t%A0"
14650   [(set_attr "type" "ibr")
14651    (set_attr "length_immediate" "0")])
14652
14653 (define_expand "tablejump"
14654   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14655               (use (label_ref (match_operand 1 "" "")))])]
14656   ""
14657 {
14658   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14659      relative.  Convert the relative address to an absolute address.  */
14660   if (flag_pic)
14661     {
14662       rtx op0, op1;
14663       enum rtx_code code;
14664
14665       /* We can't use @GOTOFF for text labels on VxWorks;
14666          see gotoff_operand.  */
14667       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14668         {
14669           code = PLUS;
14670           op0 = operands[0];
14671           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14672         }
14673       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14674         {
14675           code = PLUS;
14676           op0 = operands[0];
14677           op1 = pic_offset_table_rtx;
14678         }
14679       else
14680         {
14681           code = MINUS;
14682           op0 = pic_offset_table_rtx;
14683           op1 = operands[0];
14684         }
14685
14686       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14687                                          OPTAB_DIRECT);
14688     }
14689 })
14690
14691 (define_insn "*tablejump_1"
14692   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14693    (use (label_ref (match_operand 1 "" "")))]
14694   ""
14695   "jmp\t%A0"
14696   [(set_attr "type" "ibr")
14697    (set_attr "length_immediate" "0")])
14698 \f
14699 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14700
14701 (define_peephole2
14702   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14703    (set (match_operand:QI 1 "register_operand" "")
14704         (match_operator:QI 2 "ix86_comparison_operator"
14705           [(reg FLAGS_REG) (const_int 0)]))
14706    (set (match_operand 3 "q_regs_operand" "")
14707         (zero_extend (match_dup 1)))]
14708   "(peep2_reg_dead_p (3, operands[1])
14709     || operands_match_p (operands[1], operands[3]))
14710    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14711   [(set (match_dup 4) (match_dup 0))
14712    (set (strict_low_part (match_dup 5))
14713         (match_dup 2))]
14714 {
14715   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14716   operands[5] = gen_lowpart (QImode, operands[3]);
14717   ix86_expand_clear (operands[3]);
14718 })
14719
14720 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14721
14722 (define_peephole2
14723   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14724    (set (match_operand:QI 1 "register_operand" "")
14725         (match_operator:QI 2 "ix86_comparison_operator"
14726           [(reg FLAGS_REG) (const_int 0)]))
14727    (parallel [(set (match_operand 3 "q_regs_operand" "")
14728                    (zero_extend (match_dup 1)))
14729               (clobber (reg:CC FLAGS_REG))])]
14730   "(peep2_reg_dead_p (3, operands[1])
14731     || operands_match_p (operands[1], operands[3]))
14732    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14733   [(set (match_dup 4) (match_dup 0))
14734    (set (strict_low_part (match_dup 5))
14735         (match_dup 2))]
14736 {
14737   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14738   operands[5] = gen_lowpart (QImode, operands[3]);
14739   ix86_expand_clear (operands[3]);
14740 })
14741 \f
14742 ;; Call instructions.
14743
14744 ;; The predicates normally associated with named expanders are not properly
14745 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14746 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14747
14748 ;; Call subroutine returning no value.
14749
14750 (define_expand "call_pop"
14751   [(parallel [(call (match_operand:QI 0 "" "")
14752                     (match_operand:SI 1 "" ""))
14753               (set (reg:SI SP_REG)
14754                    (plus:SI (reg:SI SP_REG)
14755                             (match_operand:SI 3 "" "")))])]
14756   "!TARGET_64BIT"
14757 {
14758   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14759   DONE;
14760 })
14761
14762 (define_insn "*call_pop_0"
14763   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14764          (match_operand:SI 1 "" ""))
14765    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14766                             (match_operand:SI 2 "immediate_operand" "")))]
14767   "!TARGET_64BIT"
14768 {
14769   if (SIBLING_CALL_P (insn))
14770     return "jmp\t%P0";
14771   else
14772     return "call\t%P0";
14773 }
14774   [(set_attr "type" "call")])
14775
14776 (define_insn "*call_pop_1"
14777   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14778          (match_operand:SI 1 "" ""))
14779    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14780                             (match_operand:SI 2 "immediate_operand" "i")))]
14781   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14782 {
14783   if (constant_call_address_operand (operands[0], Pmode))
14784     return "call\t%P0";
14785   return "call\t%A0";
14786 }
14787   [(set_attr "type" "call")])
14788
14789 (define_insn "*sibcall_pop_1"
14790   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14791          (match_operand:SI 1 "" ""))
14792    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14793                             (match_operand:SI 2 "immediate_operand" "i,i")))]
14794   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14795   "@
14796    jmp\t%P0
14797    jmp\t%A0"
14798   [(set_attr "type" "call")])
14799
14800 (define_expand "call"
14801   [(call (match_operand:QI 0 "" "")
14802          (match_operand 1 "" ""))
14803    (use (match_operand 2 "" ""))]
14804   ""
14805 {
14806   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14807   DONE;
14808 })
14809
14810 (define_expand "sibcall"
14811   [(call (match_operand:QI 0 "" "")
14812          (match_operand 1 "" ""))
14813    (use (match_operand 2 "" ""))]
14814   ""
14815 {
14816   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14817   DONE;
14818 })
14819
14820 (define_insn "*call_0"
14821   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14822          (match_operand 1 "" ""))]
14823   ""
14824 {
14825   if (SIBLING_CALL_P (insn))
14826     return "jmp\t%P0";
14827   else
14828     return "call\t%P0";
14829 }
14830   [(set_attr "type" "call")])
14831
14832 (define_insn "*call_1"
14833   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14834          (match_operand 1 "" ""))]
14835   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14836 {
14837   if (constant_call_address_operand (operands[0], Pmode))
14838     return "call\t%P0";
14839   return "call\t%A0";
14840 }
14841   [(set_attr "type" "call")])
14842
14843 (define_insn "*sibcall_1"
14844   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14845          (match_operand 1 "" ""))]
14846   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14847   "@
14848    jmp\t%P0
14849    jmp\t%A0"
14850   [(set_attr "type" "call")])
14851
14852 (define_insn "*call_1_rex64"
14853   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14854          (match_operand 1 "" ""))]
14855   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14856    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14857 {
14858   if (constant_call_address_operand (operands[0], Pmode))
14859     return "call\t%P0";
14860   return "call\t%A0";
14861 }
14862   [(set_attr "type" "call")])
14863
14864 (define_insn "*call_1_rex64_ms_sysv"
14865   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14866          (match_operand 1 "" ""))
14867    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14868    (clobber (reg:TI XMM6_REG))
14869    (clobber (reg:TI XMM7_REG))
14870    (clobber (reg:TI XMM8_REG))
14871    (clobber (reg:TI XMM9_REG))
14872    (clobber (reg:TI XMM10_REG))
14873    (clobber (reg:TI XMM11_REG))
14874    (clobber (reg:TI XMM12_REG))
14875    (clobber (reg:TI XMM13_REG))
14876    (clobber (reg:TI XMM14_REG))
14877    (clobber (reg:TI XMM15_REG))
14878    (clobber (reg:DI SI_REG))
14879    (clobber (reg:DI DI_REG))]
14880   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14881 {
14882   if (constant_call_address_operand (operands[0], Pmode))
14883     return "call\t%P0";
14884   return "call\t%A0";
14885 }
14886   [(set_attr "type" "call")])
14887
14888 (define_insn "*call_1_rex64_large"
14889   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14890          (match_operand 1 "" ""))]
14891   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14892   "call\t%A0"
14893   [(set_attr "type" "call")])
14894
14895 (define_insn "*sibcall_1_rex64"
14896   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14897          (match_operand 1 "" ""))]
14898   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14899   "@
14900    jmp\t%P0
14901    jmp\t%A0"
14902   [(set_attr "type" "call")])
14903
14904 ;; Call subroutine, returning value in operand 0
14905 (define_expand "call_value_pop"
14906   [(parallel [(set (match_operand 0 "" "")
14907                    (call (match_operand:QI 1 "" "")
14908                          (match_operand:SI 2 "" "")))
14909               (set (reg:SI SP_REG)
14910                    (plus:SI (reg:SI SP_REG)
14911                             (match_operand:SI 4 "" "")))])]
14912   "!TARGET_64BIT"
14913 {
14914   ix86_expand_call (operands[0], operands[1], operands[2],
14915                     operands[3], operands[4], 0);
14916   DONE;
14917 })
14918
14919 (define_expand "call_value"
14920   [(set (match_operand 0 "" "")
14921         (call (match_operand:QI 1 "" "")
14922               (match_operand:SI 2 "" "")))
14923    (use (match_operand:SI 3 "" ""))]
14924   ;; Operand 2 not used on the i386.
14925   ""
14926 {
14927   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14928   DONE;
14929 })
14930
14931 (define_expand "sibcall_value"
14932   [(set (match_operand 0 "" "")
14933         (call (match_operand:QI 1 "" "")
14934               (match_operand:SI 2 "" "")))
14935    (use (match_operand:SI 3 "" ""))]
14936   ;; Operand 2 not used on the i386.
14937   ""
14938 {
14939   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14940   DONE;
14941 })
14942
14943 ;; Call subroutine returning any type.
14944
14945 (define_expand "untyped_call"
14946   [(parallel [(call (match_operand 0 "" "")
14947                     (const_int 0))
14948               (match_operand 1 "" "")
14949               (match_operand 2 "" "")])]
14950   ""
14951 {
14952   int i;
14953
14954   /* In order to give reg-stack an easier job in validating two
14955      coprocessor registers as containing a possible return value,
14956      simply pretend the untyped call returns a complex long double
14957      value. 
14958
14959      We can't use SSE_REGPARM_MAX here since callee is unprototyped
14960      and should have the default ABI.  */
14961
14962   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14963                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14964                     operands[0], const0_rtx,
14965                     GEN_INT ((TARGET_64BIT
14966                               ? (ix86_abi == SYSV_ABI
14967                                  ? X86_64_SSE_REGPARM_MAX
14968                                  : X86_64_MS_SSE_REGPARM_MAX)
14969                               : X86_32_SSE_REGPARM_MAX)
14970                              - 1),
14971                     NULL, 0);
14972
14973   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14974     {
14975       rtx set = XVECEXP (operands[2], 0, i);
14976       emit_move_insn (SET_DEST (set), SET_SRC (set));
14977     }
14978
14979   /* The optimizer does not know that the call sets the function value
14980      registers we stored in the result block.  We avoid problems by
14981      claiming that all hard registers are used and clobbered at this
14982      point.  */
14983   emit_insn (gen_blockage ());
14984
14985   DONE;
14986 })
14987 \f
14988 ;; Prologue and epilogue instructions
14989
14990 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14991 ;; all of memory.  This blocks insns from being moved across this point.
14992
14993 (define_insn "blockage"
14994   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14995   ""
14996   ""
14997   [(set_attr "length" "0")])
14998
14999 ;; Do not schedule instructions accessing memory across this point.
15000
15001 (define_expand "memory_blockage"
15002   [(set (match_dup 0)
15003         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15004   ""
15005 {
15006   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15007   MEM_VOLATILE_P (operands[0]) = 1;
15008 })
15009
15010 (define_insn "*memory_blockage"
15011   [(set (match_operand:BLK 0 "" "")
15012         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15013   ""
15014   ""
15015   [(set_attr "length" "0")])
15016
15017 ;; As USE insns aren't meaningful after reload, this is used instead
15018 ;; to prevent deleting instructions setting registers for PIC code
15019 (define_insn "prologue_use"
15020   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15021   ""
15022   ""
15023   [(set_attr "length" "0")])
15024
15025 ;; Insn emitted into the body of a function to return from a function.
15026 ;; This is only done if the function's epilogue is known to be simple.
15027 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15028
15029 (define_expand "return"
15030   [(return)]
15031   "ix86_can_use_return_insn_p ()"
15032 {
15033   if (crtl->args.pops_args)
15034     {
15035       rtx popc = GEN_INT (crtl->args.pops_args);
15036       emit_jump_insn (gen_return_pop_internal (popc));
15037       DONE;
15038     }
15039 })
15040
15041 (define_insn "return_internal"
15042   [(return)]
15043   "reload_completed"
15044   "ret"
15045   [(set_attr "length" "1")
15046    (set_attr "atom_unit" "jeu")
15047    (set_attr "length_immediate" "0")
15048    (set_attr "modrm" "0")])
15049
15050 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15051 ;; instruction Athlon and K8 have.
15052
15053 (define_insn "return_internal_long"
15054   [(return)
15055    (unspec [(const_int 0)] UNSPEC_REP)]
15056   "reload_completed"
15057   "rep\;ret"
15058   [(set_attr "length" "2")
15059    (set_attr "atom_unit" "jeu")
15060    (set_attr "length_immediate" "0")
15061    (set_attr "prefix_rep" "1")
15062    (set_attr "modrm" "0")])
15063
15064 (define_insn "return_pop_internal"
15065   [(return)
15066    (use (match_operand:SI 0 "const_int_operand" ""))]
15067   "reload_completed"
15068   "ret\t%0"
15069   [(set_attr "length" "3")
15070    (set_attr "atom_unit" "jeu")
15071    (set_attr "length_immediate" "2")
15072    (set_attr "modrm" "0")])
15073
15074 (define_insn "return_indirect_internal"
15075   [(return)
15076    (use (match_operand:SI 0 "register_operand" "r"))]
15077   "reload_completed"
15078   "jmp\t%A0"
15079   [(set_attr "type" "ibr")
15080    (set_attr "length_immediate" "0")])
15081
15082 (define_insn "nop"
15083   [(const_int 0)]
15084   ""
15085   "nop"
15086   [(set_attr "length" "1")
15087    (set_attr "length_immediate" "0")
15088    (set_attr "modrm" "0")])
15089
15090 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
15091 ;; branch prediction penalty for the third jump in a 16-byte
15092 ;; block on K8.
15093
15094 (define_insn "pad"
15095   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15096   ""
15097 {
15098 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15099   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15100 #else
15101   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15102      The align insn is used to avoid 3 jump instructions in the row to improve
15103      branch prediction and the benefits hardly outweigh the cost of extra 8
15104      nops on the average inserted by full alignment pseudo operation.  */
15105 #endif
15106   return "";
15107 }
15108   [(set_attr "length" "16")])
15109
15110 (define_expand "prologue"
15111   [(const_int 0)]
15112   ""
15113   "ix86_expand_prologue (); DONE;")
15114
15115 (define_insn "set_got"
15116   [(set (match_operand:SI 0 "register_operand" "=r")
15117         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15118    (clobber (reg:CC FLAGS_REG))]
15119   "!TARGET_64BIT"
15120   { return output_set_got (operands[0], NULL_RTX); }
15121   [(set_attr "type" "multi")
15122    (set_attr "length" "12")])
15123
15124 (define_insn "set_got_labelled"
15125   [(set (match_operand:SI 0 "register_operand" "=r")
15126         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15127          UNSPEC_SET_GOT))
15128    (clobber (reg:CC FLAGS_REG))]
15129   "!TARGET_64BIT"
15130   { return output_set_got (operands[0], operands[1]); }
15131   [(set_attr "type" "multi")
15132    (set_attr "length" "12")])
15133
15134 (define_insn "set_got_rex64"
15135   [(set (match_operand:DI 0 "register_operand" "=r")
15136         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15137   "TARGET_64BIT"
15138   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15139   [(set_attr "type" "lea")
15140    (set_attr "length_address" "4")
15141    (set_attr "mode" "DI")])
15142
15143 (define_insn "set_rip_rex64"
15144   [(set (match_operand:DI 0 "register_operand" "=r")
15145         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15146   "TARGET_64BIT"
15147   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15148   [(set_attr "type" "lea")
15149    (set_attr "length_address" "4")
15150    (set_attr "mode" "DI")])
15151
15152 (define_insn "set_got_offset_rex64"
15153   [(set (match_operand:DI 0 "register_operand" "=r")
15154         (unspec:DI
15155           [(label_ref (match_operand 1 "" ""))]
15156           UNSPEC_SET_GOT_OFFSET))]
15157   "TARGET_64BIT"
15158   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15159   [(set_attr "type" "imov")
15160    (set_attr "length_immediate" "0")
15161    (set_attr "length_address" "8")
15162    (set_attr "mode" "DI")])
15163
15164 (define_expand "epilogue"
15165   [(const_int 0)]
15166   ""
15167   "ix86_expand_epilogue (1); DONE;")
15168
15169 (define_expand "sibcall_epilogue"
15170   [(const_int 0)]
15171   ""
15172   "ix86_expand_epilogue (0); DONE;")
15173
15174 (define_expand "eh_return"
15175   [(use (match_operand 0 "register_operand" ""))]
15176   ""
15177 {
15178   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15179
15180   /* Tricky bit: we write the address of the handler to which we will
15181      be returning into someone else's stack frame, one word below the
15182      stack address we wish to restore.  */
15183   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15184   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15185   tmp = gen_rtx_MEM (Pmode, tmp);
15186   emit_move_insn (tmp, ra);
15187
15188   emit_jump_insn (gen_eh_return_internal ());
15189   emit_barrier ();
15190   DONE;
15191 })
15192
15193 (define_insn_and_split "eh_return_internal"
15194   [(eh_return)]
15195   ""
15196   "#"
15197   "epilogue_completed"
15198   [(const_int 0)]
15199   "ix86_expand_epilogue (2); DONE;")
15200
15201 (define_insn "leave"
15202   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15203    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15204    (clobber (mem:BLK (scratch)))]
15205   "!TARGET_64BIT"
15206   "leave"
15207   [(set_attr "type" "leave")])
15208
15209 (define_insn "leave_rex64"
15210   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15211    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15212    (clobber (mem:BLK (scratch)))]
15213   "TARGET_64BIT"
15214   "leave"
15215   [(set_attr "type" "leave")])
15216 \f
15217 (define_expand "ffssi2"
15218   [(parallel
15219      [(set (match_operand:SI 0 "register_operand" "")
15220            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15221       (clobber (match_scratch:SI 2 ""))
15222       (clobber (reg:CC FLAGS_REG))])]
15223   ""
15224 {
15225   if (TARGET_CMOVE)
15226     {
15227       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15228       DONE;
15229     }
15230 })
15231
15232 (define_expand "ffs_cmove"
15233   [(set (match_dup 2) (const_int -1))
15234    (parallel [(set (reg:CCZ FLAGS_REG)
15235                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15236                                 (const_int 0)))
15237               (set (match_operand:SI 0 "register_operand" "")
15238                    (ctz:SI (match_dup 1)))])
15239    (set (match_dup 0) (if_then_else:SI
15240                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15241                         (match_dup 2)
15242                         (match_dup 0)))
15243    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15244               (clobber (reg:CC FLAGS_REG))])]
15245   "TARGET_CMOVE"
15246   "operands[2] = gen_reg_rtx (SImode);")
15247
15248 (define_insn_and_split "*ffs_no_cmove"
15249   [(set (match_operand:SI 0 "register_operand" "=r")
15250         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15251    (clobber (match_scratch:SI 2 "=&q"))
15252    (clobber (reg:CC FLAGS_REG))]
15253   "!TARGET_CMOVE"
15254   "#"
15255   "&& reload_completed"
15256   [(parallel [(set (reg:CCZ FLAGS_REG)
15257                    (compare:CCZ (match_dup 1) (const_int 0)))
15258               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15259    (set (strict_low_part (match_dup 3))
15260         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15261    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15262               (clobber (reg:CC FLAGS_REG))])
15263    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15264               (clobber (reg:CC FLAGS_REG))])
15265    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15266               (clobber (reg:CC FLAGS_REG))])]
15267 {
15268   operands[3] = gen_lowpart (QImode, operands[2]);
15269   ix86_expand_clear (operands[2]);
15270 })
15271
15272 (define_insn "*ffssi_1"
15273   [(set (reg:CCZ FLAGS_REG)
15274         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15275                      (const_int 0)))
15276    (set (match_operand:SI 0 "register_operand" "=r")
15277         (ctz:SI (match_dup 1)))]
15278   ""
15279   "bsf{l}\t{%1, %0|%0, %1}"
15280   [(set_attr "type" "alu1")
15281    (set_attr "prefix_0f" "1")
15282    (set_attr "mode" "SI")])
15283
15284 (define_expand "ffsdi2"
15285   [(set (match_dup 2) (const_int -1))
15286    (parallel [(set (reg:CCZ FLAGS_REG)
15287                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15288                                 (const_int 0)))
15289               (set (match_operand:DI 0 "register_operand" "")
15290                    (ctz:DI (match_dup 1)))])
15291    (set (match_dup 0) (if_then_else:DI
15292                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15293                         (match_dup 2)
15294                         (match_dup 0)))
15295    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15296               (clobber (reg:CC FLAGS_REG))])]
15297   "TARGET_64BIT"
15298   "operands[2] = gen_reg_rtx (DImode);")
15299
15300 (define_insn "*ffsdi_1"
15301   [(set (reg:CCZ FLAGS_REG)
15302         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15303                      (const_int 0)))
15304    (set (match_operand:DI 0 "register_operand" "=r")
15305         (ctz:DI (match_dup 1)))]
15306   "TARGET_64BIT"
15307   "bsf{q}\t{%1, %0|%0, %1}"
15308   [(set_attr "type" "alu1")
15309    (set_attr "prefix_0f" "1")
15310    (set_attr "mode" "DI")])
15311
15312 (define_insn "ctzsi2"
15313   [(set (match_operand:SI 0 "register_operand" "=r")
15314         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15315    (clobber (reg:CC FLAGS_REG))]
15316   ""
15317   "bsf{l}\t{%1, %0|%0, %1}"
15318   [(set_attr "type" "alu1")
15319    (set_attr "prefix_0f" "1")
15320    (set_attr "mode" "SI")])
15321
15322 (define_insn "ctzdi2"
15323   [(set (match_operand:DI 0 "register_operand" "=r")
15324         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15325    (clobber (reg:CC FLAGS_REG))]
15326   "TARGET_64BIT"
15327   "bsf{q}\t{%1, %0|%0, %1}"
15328   [(set_attr "type" "alu1")
15329    (set_attr "prefix_0f" "1")
15330    (set_attr "mode" "DI")])
15331
15332 (define_expand "clzsi2"
15333   [(parallel
15334      [(set (match_operand:SI 0 "register_operand" "")
15335            (minus:SI (const_int 31)
15336                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15337       (clobber (reg:CC FLAGS_REG))])
15338    (parallel
15339      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15340       (clobber (reg:CC FLAGS_REG))])]
15341   ""
15342 {
15343   if (TARGET_ABM)
15344     {
15345       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15346       DONE;
15347     }
15348 })
15349
15350 (define_insn "clzsi2_abm"
15351   [(set (match_operand:SI 0 "register_operand" "=r")
15352         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15353    (clobber (reg:CC FLAGS_REG))]
15354   "TARGET_ABM"
15355   "lzcnt{l}\t{%1, %0|%0, %1}"
15356   [(set_attr "prefix_rep" "1")
15357    (set_attr "type" "bitmanip")
15358    (set_attr "mode" "SI")])
15359
15360 (define_insn "bsr"
15361   [(set (match_operand:SI 0 "register_operand" "=r")
15362         (minus:SI (const_int 31)
15363                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15364    (clobber (reg:CC FLAGS_REG))]
15365   ""
15366   "bsr{l}\t{%1, %0|%0, %1}"
15367   [(set_attr "type" "alu1")
15368    (set_attr "prefix_0f" "1")
15369    (set_attr "mode" "SI")])
15370
15371 (define_insn "popcount<mode>2"
15372   [(set (match_operand:SWI248 0 "register_operand" "=r")
15373         (popcount:SWI248
15374           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15375    (clobber (reg:CC FLAGS_REG))]
15376   "TARGET_POPCNT"
15377 {
15378 #if TARGET_MACHO
15379   return "popcnt\t{%1, %0|%0, %1}";
15380 #else
15381   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15382 #endif
15383 }
15384   [(set_attr "prefix_rep" "1")
15385    (set_attr "type" "bitmanip")
15386    (set_attr "mode" "<MODE>")])
15387
15388 (define_insn "*popcount<mode>2_cmp"
15389   [(set (reg FLAGS_REG)
15390         (compare
15391           (popcount:SWI248
15392             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15393           (const_int 0)))
15394    (set (match_operand:SWI248 0 "register_operand" "=r")
15395         (popcount:SWI248 (match_dup 1)))]
15396   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15397 {
15398 #if TARGET_MACHO
15399   return "popcnt\t{%1, %0|%0, %1}";
15400 #else
15401   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15402 #endif
15403 }
15404   [(set_attr "prefix_rep" "1")
15405    (set_attr "type" "bitmanip")
15406    (set_attr "mode" "<MODE>")])
15407
15408 (define_insn "*popcountsi2_cmp_zext"
15409   [(set (reg FLAGS_REG)
15410         (compare
15411           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15412           (const_int 0)))
15413    (set (match_operand:DI 0 "register_operand" "=r")
15414         (zero_extend:DI(popcount:SI (match_dup 1))))]
15415   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15416 {
15417 #if TARGET_MACHO
15418   return "popcnt\t{%1, %0|%0, %1}";
15419 #else
15420   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15421 #endif
15422 }
15423   [(set_attr "prefix_rep" "1")
15424    (set_attr "type" "bitmanip")
15425    (set_attr "mode" "SI")])
15426
15427 (define_expand "bswapsi2"
15428   [(set (match_operand:SI 0 "register_operand" "")
15429         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15430   ""
15431 {
15432   if (!(TARGET_BSWAP || TARGET_MOVBE))
15433     {
15434       rtx x = operands[0];
15435
15436       emit_move_insn (x, operands[1]);
15437       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15438       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15439       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15440       DONE;
15441     }
15442 })
15443
15444 (define_insn "*bswapsi_movbe"
15445   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
15446         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
15447   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15448   "@
15449     bswap\t%0
15450     movbe\t{%1, %0|%0, %1}
15451     movbe\t{%1, %0|%0, %1}"
15452   [(set_attr "type" "*,imov,imov")
15453    (set_attr "modrm" "*,1,1")
15454    (set_attr "prefix_0f" "1")
15455    (set_attr "prefix_extra" "*,1,1")
15456    (set_attr "length" "2,*,*")
15457    (set_attr "mode" "SI")])
15458
15459 (define_insn "*bswapsi_1"
15460   [(set (match_operand:SI 0 "register_operand" "=r")
15461         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15462   "TARGET_BSWAP"
15463   "bswap\t%0"
15464   [(set_attr "prefix_0f" "1")
15465    (set_attr "length" "2")])
15466
15467 (define_insn "*bswaphi_lowpart_1"
15468   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15469         (bswap:HI (match_dup 0)))
15470    (clobber (reg:CC FLAGS_REG))]
15471   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15472   "@
15473     xchg{b}\t{%h0, %b0|%b0, %h0}
15474     rol{w}\t{$8, %0|%0, 8}"
15475   [(set_attr "length" "2,4")
15476    (set_attr "mode" "QI,HI")])
15477
15478 (define_insn "bswaphi_lowpart"
15479   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15480         (bswap:HI (match_dup 0)))
15481    (clobber (reg:CC FLAGS_REG))]
15482   ""
15483   "rol{w}\t{$8, %0|%0, 8}"
15484   [(set_attr "length" "4")
15485    (set_attr "mode" "HI")])
15486
15487 (define_expand "bswapdi2"
15488   [(set (match_operand:DI 0 "register_operand" "")
15489         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
15490   "TARGET_64BIT"
15491   "")
15492
15493 (define_insn "*bswapdi_movbe"
15494   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
15495         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
15496   "TARGET_64BIT && TARGET_MOVBE
15497    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15498   "@
15499     bswap\t%0
15500     movbe\t{%1, %0|%0, %1}
15501     movbe\t{%1, %0|%0, %1}"
15502   [(set_attr "type" "*,imov,imov")
15503    (set_attr "modrm" "*,1,1")
15504    (set_attr "prefix_0f" "1")
15505    (set_attr "prefix_extra" "*,1,1")
15506    (set_attr "length" "3,*,*")
15507    (set_attr "mode" "DI")])
15508
15509 (define_insn "*bswapdi_1"
15510   [(set (match_operand:DI 0 "register_operand" "=r")
15511         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15512   "TARGET_64BIT"
15513   "bswap\t%0"
15514   [(set_attr "prefix_0f" "1")
15515    (set_attr "length" "3")])
15516
15517 (define_expand "clzdi2"
15518   [(parallel
15519      [(set (match_operand:DI 0 "register_operand" "")
15520            (minus:DI (const_int 63)
15521                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15522       (clobber (reg:CC FLAGS_REG))])
15523    (parallel
15524      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15525       (clobber (reg:CC FLAGS_REG))])]
15526   "TARGET_64BIT"
15527 {
15528   if (TARGET_ABM)
15529     {
15530       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15531       DONE;
15532     }
15533 })
15534
15535 (define_insn "clzdi2_abm"
15536   [(set (match_operand:DI 0 "register_operand" "=r")
15537         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15538    (clobber (reg:CC FLAGS_REG))]
15539   "TARGET_64BIT && TARGET_ABM"
15540   "lzcnt{q}\t{%1, %0|%0, %1}"
15541   [(set_attr "prefix_rep" "1")
15542    (set_attr "type" "bitmanip")
15543    (set_attr "mode" "DI")])
15544
15545 (define_insn "bsr_rex64"
15546   [(set (match_operand:DI 0 "register_operand" "=r")
15547         (minus:DI (const_int 63)
15548                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15549    (clobber (reg:CC FLAGS_REG))]
15550   "TARGET_64BIT"
15551   "bsr{q}\t{%1, %0|%0, %1}"
15552   [(set_attr "type" "alu1")
15553    (set_attr "prefix_0f" "1")
15554    (set_attr "mode" "DI")])
15555
15556 (define_expand "clzhi2"
15557   [(parallel
15558      [(set (match_operand:HI 0 "register_operand" "")
15559            (minus:HI (const_int 15)
15560                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15561       (clobber (reg:CC FLAGS_REG))])
15562    (parallel
15563      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15564       (clobber (reg:CC FLAGS_REG))])]
15565   ""
15566 {
15567   if (TARGET_ABM)
15568     {
15569       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15570       DONE;
15571     }
15572 })
15573
15574 (define_insn "clzhi2_abm"
15575   [(set (match_operand:HI 0 "register_operand" "=r")
15576         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15577    (clobber (reg:CC FLAGS_REG))]
15578   "TARGET_ABM"
15579   "lzcnt{w}\t{%1, %0|%0, %1}"
15580   [(set_attr "prefix_rep" "1")
15581    (set_attr "type" "bitmanip")
15582    (set_attr "mode" "HI")])
15583
15584 (define_insn "*bsrhi"
15585   [(set (match_operand:HI 0 "register_operand" "=r")
15586         (minus:HI (const_int 15)
15587                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15588    (clobber (reg:CC FLAGS_REG))]
15589   ""
15590   "bsr{w}\t{%1, %0|%0, %1}"
15591   [(set_attr "type" "alu1")
15592    (set_attr "prefix_0f" "1")
15593    (set_attr "mode" "HI")])
15594
15595 (define_expand "paritydi2"
15596   [(set (match_operand:DI 0 "register_operand" "")
15597         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15598   "! TARGET_POPCNT"
15599 {
15600   rtx scratch = gen_reg_rtx (QImode);
15601   rtx cond;
15602
15603   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15604                                 NULL_RTX, operands[1]));
15605
15606   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15607                          gen_rtx_REG (CCmode, FLAGS_REG),
15608                          const0_rtx);
15609   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15610
15611   if (TARGET_64BIT)
15612     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15613   else
15614     {
15615       rtx tmp = gen_reg_rtx (SImode);
15616
15617       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15618       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15619     }
15620   DONE;
15621 })
15622
15623 (define_insn_and_split "paritydi2_cmp"
15624   [(set (reg:CC FLAGS_REG)
15625         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15626    (clobber (match_scratch:DI 0 "=r"))
15627    (clobber (match_scratch:SI 1 "=&r"))
15628    (clobber (match_scratch:HI 2 "=Q"))]
15629   "! TARGET_POPCNT"
15630   "#"
15631   "&& reload_completed"
15632   [(parallel
15633      [(set (match_dup 1)
15634            (xor:SI (match_dup 1) (match_dup 4)))
15635       (clobber (reg:CC FLAGS_REG))])
15636    (parallel
15637      [(set (reg:CC FLAGS_REG)
15638            (parity:CC (match_dup 1)))
15639       (clobber (match_dup 1))
15640       (clobber (match_dup 2))])]
15641 {
15642   operands[4] = gen_lowpart (SImode, operands[3]);
15643
15644   if (TARGET_64BIT)
15645     {
15646       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15647       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15648     }
15649   else
15650     operands[1] = gen_highpart (SImode, operands[3]);
15651 })
15652
15653 (define_expand "paritysi2"
15654   [(set (match_operand:SI 0 "register_operand" "")
15655         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15656   "! TARGET_POPCNT"
15657 {
15658   rtx scratch = gen_reg_rtx (QImode);
15659   rtx cond;
15660
15661   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15662
15663   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15664                          gen_rtx_REG (CCmode, FLAGS_REG),
15665                          const0_rtx);
15666   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15667
15668   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15669   DONE;
15670 })
15671
15672 (define_insn_and_split "paritysi2_cmp"
15673   [(set (reg:CC FLAGS_REG)
15674         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15675    (clobber (match_scratch:SI 0 "=r"))
15676    (clobber (match_scratch:HI 1 "=&Q"))]
15677   "! TARGET_POPCNT"
15678   "#"
15679   "&& reload_completed"
15680   [(parallel
15681      [(set (match_dup 1)
15682            (xor:HI (match_dup 1) (match_dup 3)))
15683       (clobber (reg:CC FLAGS_REG))])
15684    (parallel
15685      [(set (reg:CC FLAGS_REG)
15686            (parity:CC (match_dup 1)))
15687       (clobber (match_dup 1))])]
15688 {
15689   operands[3] = gen_lowpart (HImode, operands[2]);
15690
15691   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15692   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15693 })
15694
15695 (define_insn "*parityhi2_cmp"
15696   [(set (reg:CC FLAGS_REG)
15697         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15698    (clobber (match_scratch:HI 0 "=Q"))]
15699   "! TARGET_POPCNT"
15700   "xor{b}\t{%h0, %b0|%b0, %h0}"
15701   [(set_attr "length" "2")
15702    (set_attr "mode" "HI")])
15703
15704 (define_insn "*parityqi2_cmp"
15705   [(set (reg:CC FLAGS_REG)
15706         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15707   "! TARGET_POPCNT"
15708   "test{b}\t%0, %0"
15709   [(set_attr "length" "2")
15710    (set_attr "mode" "QI")])
15711 \f
15712 ;; Thread-local storage patterns for ELF.
15713 ;;
15714 ;; Note that these code sequences must appear exactly as shown
15715 ;; in order to allow linker relaxation.
15716
15717 (define_insn "*tls_global_dynamic_32_gnu"
15718   [(set (match_operand:SI 0 "register_operand" "=a")
15719         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15720                     (match_operand:SI 2 "tls_symbolic_operand" "")
15721                     (match_operand:SI 3 "call_insn_operand" "")]
15722                     UNSPEC_TLS_GD))
15723    (clobber (match_scratch:SI 4 "=d"))
15724    (clobber (match_scratch:SI 5 "=c"))
15725    (clobber (reg:CC FLAGS_REG))]
15726   "!TARGET_64BIT && TARGET_GNU_TLS"
15727   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15728   [(set_attr "type" "multi")
15729    (set_attr "length" "12")])
15730
15731 (define_insn "*tls_global_dynamic_32_sun"
15732   [(set (match_operand:SI 0 "register_operand" "=a")
15733         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15734                     (match_operand:SI 2 "tls_symbolic_operand" "")
15735                     (match_operand:SI 3 "call_insn_operand" "")]
15736                     UNSPEC_TLS_GD))
15737    (clobber (match_scratch:SI 4 "=d"))
15738    (clobber (match_scratch:SI 5 "=c"))
15739    (clobber (reg:CC FLAGS_REG))]
15740   "!TARGET_64BIT && TARGET_SUN_TLS"
15741   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15742         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15743   [(set_attr "type" "multi")
15744    (set_attr "length" "14")])
15745
15746 (define_expand "tls_global_dynamic_32"
15747   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15748                    (unspec:SI
15749                     [(match_dup 2)
15750                      (match_operand:SI 1 "tls_symbolic_operand" "")
15751                      (match_dup 3)]
15752                     UNSPEC_TLS_GD))
15753               (clobber (match_scratch:SI 4 ""))
15754               (clobber (match_scratch:SI 5 ""))
15755               (clobber (reg:CC FLAGS_REG))])]
15756   ""
15757 {
15758   if (flag_pic)
15759     operands[2] = pic_offset_table_rtx;
15760   else
15761     {
15762       operands[2] = gen_reg_rtx (Pmode);
15763       emit_insn (gen_set_got (operands[2]));
15764     }
15765   if (TARGET_GNU2_TLS)
15766     {
15767        emit_insn (gen_tls_dynamic_gnu2_32
15768                   (operands[0], operands[1], operands[2]));
15769        DONE;
15770     }
15771   operands[3] = ix86_tls_get_addr ();
15772 })
15773
15774 (define_insn "*tls_global_dynamic_64"
15775   [(set (match_operand:DI 0 "register_operand" "=a")
15776         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15777                  (match_operand:DI 3 "" "")))
15778    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15779               UNSPEC_TLS_GD)]
15780   "TARGET_64BIT"
15781   { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
15782   [(set_attr "type" "multi")
15783    (set_attr "length" "16")])
15784
15785 (define_expand "tls_global_dynamic_64"
15786   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15787                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15788               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15789                          UNSPEC_TLS_GD)])]
15790   ""
15791 {
15792   if (TARGET_GNU2_TLS)
15793     {
15794        emit_insn (gen_tls_dynamic_gnu2_64
15795                   (operands[0], operands[1]));
15796        DONE;
15797     }
15798   operands[2] = ix86_tls_get_addr ();
15799 })
15800
15801 (define_insn "*tls_local_dynamic_base_32_gnu"
15802   [(set (match_operand:SI 0 "register_operand" "=a")
15803         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15804                     (match_operand:SI 2 "call_insn_operand" "")]
15805                    UNSPEC_TLS_LD_BASE))
15806    (clobber (match_scratch:SI 3 "=d"))
15807    (clobber (match_scratch:SI 4 "=c"))
15808    (clobber (reg:CC FLAGS_REG))]
15809   "!TARGET_64BIT && TARGET_GNU_TLS"
15810   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15811   [(set_attr "type" "multi")
15812    (set_attr "length" "11")])
15813
15814 (define_insn "*tls_local_dynamic_base_32_sun"
15815   [(set (match_operand:SI 0 "register_operand" "=a")
15816         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15817                     (match_operand:SI 2 "call_insn_operand" "")]
15818                    UNSPEC_TLS_LD_BASE))
15819    (clobber (match_scratch:SI 3 "=d"))
15820    (clobber (match_scratch:SI 4 "=c"))
15821    (clobber (reg:CC FLAGS_REG))]
15822   "!TARGET_64BIT && TARGET_SUN_TLS"
15823   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15824         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15825   [(set_attr "type" "multi")
15826    (set_attr "length" "13")])
15827
15828 (define_expand "tls_local_dynamic_base_32"
15829   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15830                    (unspec:SI [(match_dup 1) (match_dup 2)]
15831                               UNSPEC_TLS_LD_BASE))
15832               (clobber (match_scratch:SI 3 ""))
15833               (clobber (match_scratch:SI 4 ""))
15834               (clobber (reg:CC FLAGS_REG))])]
15835   ""
15836 {
15837   if (flag_pic)
15838     operands[1] = pic_offset_table_rtx;
15839   else
15840     {
15841       operands[1] = gen_reg_rtx (Pmode);
15842       emit_insn (gen_set_got (operands[1]));
15843     }
15844   if (TARGET_GNU2_TLS)
15845     {
15846        emit_insn (gen_tls_dynamic_gnu2_32
15847                   (operands[0], ix86_tls_module_base (), operands[1]));
15848        DONE;
15849     }
15850   operands[2] = ix86_tls_get_addr ();
15851 })
15852
15853 (define_insn "*tls_local_dynamic_base_64"
15854   [(set (match_operand:DI 0 "register_operand" "=a")
15855         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15856                  (match_operand:DI 2 "" "")))
15857    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15858   "TARGET_64BIT"
15859   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15860   [(set_attr "type" "multi")
15861    (set_attr "length" "12")])
15862
15863 (define_expand "tls_local_dynamic_base_64"
15864   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15865                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15866               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15867   ""
15868 {
15869   if (TARGET_GNU2_TLS)
15870     {
15871        emit_insn (gen_tls_dynamic_gnu2_64
15872                   (operands[0], ix86_tls_module_base ()));
15873        DONE;
15874     }
15875   operands[1] = ix86_tls_get_addr ();
15876 })
15877
15878 ;; Local dynamic of a single variable is a lose.  Show combine how
15879 ;; to convert that back to global dynamic.
15880
15881 (define_insn_and_split "*tls_local_dynamic_32_once"
15882   [(set (match_operand:SI 0 "register_operand" "=a")
15883         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15884                              (match_operand:SI 2 "call_insn_operand" "")]
15885                             UNSPEC_TLS_LD_BASE)
15886                  (const:SI (unspec:SI
15887                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15888                             UNSPEC_DTPOFF))))
15889    (clobber (match_scratch:SI 4 "=d"))
15890    (clobber (match_scratch:SI 5 "=c"))
15891    (clobber (reg:CC FLAGS_REG))]
15892   ""
15893   "#"
15894   ""
15895   [(parallel [(set (match_dup 0)
15896                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15897                               UNSPEC_TLS_GD))
15898               (clobber (match_dup 4))
15899               (clobber (match_dup 5))
15900               (clobber (reg:CC FLAGS_REG))])]
15901   "")
15902
15903 ;; Load and add the thread base pointer from %gs:0.
15904
15905 (define_insn "*load_tp_si"
15906   [(set (match_operand:SI 0 "register_operand" "=r")
15907         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15908   "!TARGET_64BIT"
15909   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15910   [(set_attr "type" "imov")
15911    (set_attr "modrm" "0")
15912    (set_attr "length" "7")
15913    (set_attr "memory" "load")
15914    (set_attr "imm_disp" "false")])
15915
15916 (define_insn "*add_tp_si"
15917   [(set (match_operand:SI 0 "register_operand" "=r")
15918         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15919                  (match_operand:SI 1 "register_operand" "0")))
15920    (clobber (reg:CC FLAGS_REG))]
15921   "!TARGET_64BIT"
15922   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15923   [(set_attr "type" "alu")
15924    (set_attr "modrm" "0")
15925    (set_attr "length" "7")
15926    (set_attr "memory" "load")
15927    (set_attr "imm_disp" "false")])
15928
15929 (define_insn "*load_tp_di"
15930   [(set (match_operand:DI 0 "register_operand" "=r")
15931         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15932   "TARGET_64BIT"
15933   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15934   [(set_attr "type" "imov")
15935    (set_attr "modrm" "0")
15936    (set_attr "length" "7")
15937    (set_attr "memory" "load")
15938    (set_attr "imm_disp" "false")])
15939
15940 (define_insn "*add_tp_di"
15941   [(set (match_operand:DI 0 "register_operand" "=r")
15942         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15943                  (match_operand:DI 1 "register_operand" "0")))
15944    (clobber (reg:CC FLAGS_REG))]
15945   "TARGET_64BIT"
15946   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15947   [(set_attr "type" "alu")
15948    (set_attr "modrm" "0")
15949    (set_attr "length" "7")
15950    (set_attr "memory" "load")
15951    (set_attr "imm_disp" "false")])
15952
15953 ;; GNU2 TLS patterns can be split.
15954
15955 (define_expand "tls_dynamic_gnu2_32"
15956   [(set (match_dup 3)
15957         (plus:SI (match_operand:SI 2 "register_operand" "")
15958                  (const:SI
15959                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15960                              UNSPEC_TLSDESC))))
15961    (parallel
15962     [(set (match_operand:SI 0 "register_operand" "")
15963           (unspec:SI [(match_dup 1) (match_dup 3)
15964                       (match_dup 2) (reg:SI SP_REG)]
15965                       UNSPEC_TLSDESC))
15966      (clobber (reg:CC FLAGS_REG))])]
15967   "!TARGET_64BIT && TARGET_GNU2_TLS"
15968 {
15969   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15970   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15971 })
15972
15973 (define_insn "*tls_dynamic_lea_32"
15974   [(set (match_operand:SI 0 "register_operand" "=r")
15975         (plus:SI (match_operand:SI 1 "register_operand" "b")
15976                  (const:SI
15977                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15978                               UNSPEC_TLSDESC))))]
15979   "!TARGET_64BIT && TARGET_GNU2_TLS"
15980   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15981   [(set_attr "type" "lea")
15982    (set_attr "mode" "SI")
15983    (set_attr "length" "6")
15984    (set_attr "length_address" "4")])
15985
15986 (define_insn "*tls_dynamic_call_32"
15987   [(set (match_operand:SI 0 "register_operand" "=a")
15988         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15989                     (match_operand:SI 2 "register_operand" "0")
15990                     ;; we have to make sure %ebx still points to the GOT
15991                     (match_operand:SI 3 "register_operand" "b")
15992                     (reg:SI SP_REG)]
15993                    UNSPEC_TLSDESC))
15994    (clobber (reg:CC FLAGS_REG))]
15995   "!TARGET_64BIT && TARGET_GNU2_TLS"
15996   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15997   [(set_attr "type" "call")
15998    (set_attr "length" "2")
15999    (set_attr "length_address" "0")])
16000
16001 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16002   [(set (match_operand:SI 0 "register_operand" "=&a")
16003         (plus:SI
16004          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16005                      (match_operand:SI 4 "" "")
16006                      (match_operand:SI 2 "register_operand" "b")
16007                      (reg:SI SP_REG)]
16008                     UNSPEC_TLSDESC)
16009          (const:SI (unspec:SI
16010                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16011                     UNSPEC_DTPOFF))))
16012    (clobber (reg:CC FLAGS_REG))]
16013   "!TARGET_64BIT && TARGET_GNU2_TLS"
16014   "#"
16015   ""
16016   [(set (match_dup 0) (match_dup 5))]
16017 {
16018   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16019   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16020 })
16021
16022 (define_expand "tls_dynamic_gnu2_64"
16023   [(set (match_dup 2)
16024         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16025                    UNSPEC_TLSDESC))
16026    (parallel
16027     [(set (match_operand:DI 0 "register_operand" "")
16028           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16029                      UNSPEC_TLSDESC))
16030      (clobber (reg:CC FLAGS_REG))])]
16031   "TARGET_64BIT && TARGET_GNU2_TLS"
16032 {
16033   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16034   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16035 })
16036
16037 (define_insn "*tls_dynamic_lea_64"
16038   [(set (match_operand:DI 0 "register_operand" "=r")
16039         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16040                    UNSPEC_TLSDESC))]
16041   "TARGET_64BIT && TARGET_GNU2_TLS"
16042   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16043   [(set_attr "type" "lea")
16044    (set_attr "mode" "DI")
16045    (set_attr "length" "7")
16046    (set_attr "length_address" "4")])
16047
16048 (define_insn "*tls_dynamic_call_64"
16049   [(set (match_operand:DI 0 "register_operand" "=a")
16050         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16051                     (match_operand:DI 2 "register_operand" "0")
16052                     (reg:DI SP_REG)]
16053                    UNSPEC_TLSDESC))
16054    (clobber (reg:CC FLAGS_REG))]
16055   "TARGET_64BIT && TARGET_GNU2_TLS"
16056   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16057   [(set_attr "type" "call")
16058    (set_attr "length" "2")
16059    (set_attr "length_address" "0")])
16060
16061 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16062   [(set (match_operand:DI 0 "register_operand" "=&a")
16063         (plus:DI
16064          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16065                      (match_operand:DI 3 "" "")
16066                      (reg:DI SP_REG)]
16067                     UNSPEC_TLSDESC)
16068          (const:DI (unspec:DI
16069                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16070                     UNSPEC_DTPOFF))))
16071    (clobber (reg:CC FLAGS_REG))]
16072   "TARGET_64BIT && TARGET_GNU2_TLS"
16073   "#"
16074   ""
16075   [(set (match_dup 0) (match_dup 4))]
16076 {
16077   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16078   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16079 })
16080
16081 ;;
16082 \f
16083 ;; These patterns match the binary 387 instructions for addM3, subM3,
16084 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16085 ;; SFmode.  The first is the normal insn, the second the same insn but
16086 ;; with one operand a conversion, and the third the same insn but with
16087 ;; the other operand a conversion.  The conversion may be SFmode or
16088 ;; SImode if the target mode DFmode, but only SImode if the target mode
16089 ;; is SFmode.
16090
16091 ;; Gcc is slightly more smart about handling normal two address instructions
16092 ;; so use special patterns for add and mull.
16093
16094 (define_insn "*fop_<mode>_comm_mixed_avx"
16095   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16096         (match_operator:MODEF 3 "binary_fp_operator"
16097           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16098            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16099   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16100    && COMMUTATIVE_ARITH_P (operands[3])
16101    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16102   "* return output_387_binary_op (insn, operands);"
16103   [(set (attr "type")
16104         (if_then_else (eq_attr "alternative" "1")
16105            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16106               (const_string "ssemul")
16107               (const_string "sseadd"))
16108            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16109               (const_string "fmul")
16110               (const_string "fop"))))
16111    (set_attr "prefix" "orig,maybe_vex")
16112    (set_attr "mode" "<MODE>")])
16113
16114 (define_insn "*fop_<mode>_comm_mixed"
16115   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16116         (match_operator:MODEF 3 "binary_fp_operator"
16117           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16118            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16119   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16120    && COMMUTATIVE_ARITH_P (operands[3])
16121    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16122   "* return output_387_binary_op (insn, operands);"
16123   [(set (attr "type")
16124         (if_then_else (eq_attr "alternative" "1")
16125            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16126               (const_string "ssemul")
16127               (const_string "sseadd"))
16128            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16129               (const_string "fmul")
16130               (const_string "fop"))))
16131    (set_attr "mode" "<MODE>")])
16132
16133 (define_insn "*fop_<mode>_comm_avx"
16134   [(set (match_operand:MODEF 0 "register_operand" "=x")
16135         (match_operator:MODEF 3 "binary_fp_operator"
16136           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16137            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16138   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16139    && COMMUTATIVE_ARITH_P (operands[3])
16140    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16141   "* return output_387_binary_op (insn, operands);"
16142   [(set (attr "type")
16143         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16144            (const_string "ssemul")
16145            (const_string "sseadd")))
16146    (set_attr "prefix" "vex")
16147    (set_attr "mode" "<MODE>")])
16148
16149 (define_insn "*fop_<mode>_comm_sse"
16150   [(set (match_operand:MODEF 0 "register_operand" "=x")
16151         (match_operator:MODEF 3 "binary_fp_operator"
16152           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16153            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16154   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16155    && COMMUTATIVE_ARITH_P (operands[3])
16156    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16157   "* return output_387_binary_op (insn, operands);"
16158   [(set (attr "type")
16159         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16160            (const_string "ssemul")
16161            (const_string "sseadd")))
16162    (set_attr "mode" "<MODE>")])
16163
16164 (define_insn "*fop_<mode>_comm_i387"
16165   [(set (match_operand:MODEF 0 "register_operand" "=f")
16166         (match_operator:MODEF 3 "binary_fp_operator"
16167           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16168            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16169   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16170    && COMMUTATIVE_ARITH_P (operands[3])
16171    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16172   "* return output_387_binary_op (insn, operands);"
16173   [(set (attr "type")
16174         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16175            (const_string "fmul")
16176            (const_string "fop")))
16177    (set_attr "mode" "<MODE>")])
16178
16179 (define_insn "*fop_<mode>_1_mixed_avx"
16180   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16181         (match_operator:MODEF 3 "binary_fp_operator"
16182           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16183            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16184   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16185    && !COMMUTATIVE_ARITH_P (operands[3])
16186    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16187   "* return output_387_binary_op (insn, operands);"
16188   [(set (attr "type")
16189         (cond [(and (eq_attr "alternative" "2")
16190                     (match_operand:MODEF 3 "mult_operator" ""))
16191                  (const_string "ssemul")
16192                (and (eq_attr "alternative" "2")
16193                     (match_operand:MODEF 3 "div_operator" ""))
16194                  (const_string "ssediv")
16195                (eq_attr "alternative" "2")
16196                  (const_string "sseadd")
16197                (match_operand:MODEF 3 "mult_operator" "")
16198                  (const_string "fmul")
16199                (match_operand:MODEF 3 "div_operator" "")
16200                  (const_string "fdiv")
16201               ]
16202               (const_string "fop")))
16203    (set_attr "prefix" "orig,orig,maybe_vex")
16204    (set_attr "mode" "<MODE>")])
16205
16206 (define_insn "*fop_<mode>_1_mixed"
16207   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16208         (match_operator:MODEF 3 "binary_fp_operator"
16209           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16210            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16211   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16212    && !COMMUTATIVE_ARITH_P (operands[3])
16213    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16214   "* return output_387_binary_op (insn, operands);"
16215   [(set (attr "type")
16216         (cond [(and (eq_attr "alternative" "2")
16217                     (match_operand:MODEF 3 "mult_operator" ""))
16218                  (const_string "ssemul")
16219                (and (eq_attr "alternative" "2")
16220                     (match_operand:MODEF 3 "div_operator" ""))
16221                  (const_string "ssediv")
16222                (eq_attr "alternative" "2")
16223                  (const_string "sseadd")
16224                (match_operand:MODEF 3 "mult_operator" "")
16225                  (const_string "fmul")
16226                (match_operand:MODEF 3 "div_operator" "")
16227                  (const_string "fdiv")
16228               ]
16229               (const_string "fop")))
16230    (set_attr "mode" "<MODE>")])
16231
16232 (define_insn "*rcpsf2_sse"
16233   [(set (match_operand:SF 0 "register_operand" "=x")
16234         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16235                    UNSPEC_RCP))]
16236   "TARGET_SSE_MATH"
16237   "%vrcpss\t{%1, %d0|%d0, %1}"
16238   [(set_attr "type" "sse")
16239    (set_attr "atom_sse_attr" "rcp")
16240    (set_attr "prefix" "maybe_vex")
16241    (set_attr "mode" "SF")])
16242
16243 (define_insn "*fop_<mode>_1_avx"
16244   [(set (match_operand:MODEF 0 "register_operand" "=x")
16245         (match_operator:MODEF 3 "binary_fp_operator"
16246           [(match_operand:MODEF 1 "register_operand" "x")
16247            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16248   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16249    && !COMMUTATIVE_ARITH_P (operands[3])"
16250   "* return output_387_binary_op (insn, operands);"
16251   [(set (attr "type")
16252         (cond [(match_operand:MODEF 3 "mult_operator" "")
16253                  (const_string "ssemul")
16254                (match_operand:MODEF 3 "div_operator" "")
16255                  (const_string "ssediv")
16256               ]
16257               (const_string "sseadd")))
16258    (set_attr "prefix" "vex")
16259    (set_attr "mode" "<MODE>")])
16260
16261 (define_insn "*fop_<mode>_1_sse"
16262   [(set (match_operand:MODEF 0 "register_operand" "=x")
16263         (match_operator:MODEF 3 "binary_fp_operator"
16264           [(match_operand:MODEF 1 "register_operand" "0")
16265            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16266   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16267    && !COMMUTATIVE_ARITH_P (operands[3])"
16268   "* return output_387_binary_op (insn, operands);"
16269   [(set (attr "type")
16270         (cond [(match_operand:MODEF 3 "mult_operator" "")
16271                  (const_string "ssemul")
16272                (match_operand:MODEF 3 "div_operator" "")
16273                  (const_string "ssediv")
16274               ]
16275               (const_string "sseadd")))
16276    (set_attr "mode" "<MODE>")])
16277
16278 ;; This pattern is not fully shadowed by the pattern above.
16279 (define_insn "*fop_<mode>_1_i387"
16280   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16281         (match_operator:MODEF 3 "binary_fp_operator"
16282           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16283            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16284   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16285    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16286    && !COMMUTATIVE_ARITH_P (operands[3])
16287    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16288   "* return output_387_binary_op (insn, operands);"
16289   [(set (attr "type")
16290         (cond [(match_operand:MODEF 3 "mult_operator" "")
16291                  (const_string "fmul")
16292                (match_operand:MODEF 3 "div_operator" "")
16293                  (const_string "fdiv")
16294               ]
16295               (const_string "fop")))
16296    (set_attr "mode" "<MODE>")])
16297
16298 ;; ??? Add SSE splitters for these!
16299 (define_insn "*fop_<MODEF:mode>_2_i387"
16300   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16301         (match_operator:MODEF 3 "binary_fp_operator"
16302           [(float:MODEF
16303              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16304            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16305   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16306    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16307    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16308   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16309   [(set (attr "type")
16310         (cond [(match_operand:MODEF 3 "mult_operator" "")
16311                  (const_string "fmul")
16312                (match_operand:MODEF 3 "div_operator" "")
16313                  (const_string "fdiv")
16314               ]
16315               (const_string "fop")))
16316    (set_attr "fp_int_src" "true")
16317    (set_attr "mode" "<X87MODEI12:MODE>")])
16318
16319 (define_insn "*fop_<MODEF:mode>_3_i387"
16320   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16321         (match_operator:MODEF 3 "binary_fp_operator"
16322           [(match_operand:MODEF 1 "register_operand" "0,0")
16323            (float:MODEF
16324              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16325   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16326    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16327    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16328   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16329   [(set (attr "type")
16330         (cond [(match_operand:MODEF 3 "mult_operator" "")
16331                  (const_string "fmul")
16332                (match_operand:MODEF 3 "div_operator" "")
16333                  (const_string "fdiv")
16334               ]
16335               (const_string "fop")))
16336    (set_attr "fp_int_src" "true")
16337    (set_attr "mode" "<MODE>")])
16338
16339 (define_insn "*fop_df_4_i387"
16340   [(set (match_operand:DF 0 "register_operand" "=f,f")
16341         (match_operator:DF 3 "binary_fp_operator"
16342            [(float_extend:DF
16343              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16344             (match_operand:DF 2 "register_operand" "0,f")]))]
16345   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16346    && !(TARGET_SSE2 && TARGET_SSE_MATH)
16347    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16348   "* return output_387_binary_op (insn, operands);"
16349   [(set (attr "type")
16350         (cond [(match_operand:DF 3 "mult_operator" "")
16351                  (const_string "fmul")
16352                (match_operand:DF 3 "div_operator" "")
16353                  (const_string "fdiv")
16354               ]
16355               (const_string "fop")))
16356    (set_attr "mode" "SF")])
16357
16358 (define_insn "*fop_df_5_i387"
16359   [(set (match_operand:DF 0 "register_operand" "=f,f")
16360         (match_operator:DF 3 "binary_fp_operator"
16361           [(match_operand:DF 1 "register_operand" "0,f")
16362            (float_extend:DF
16363             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16364   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16365    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16366   "* return output_387_binary_op (insn, operands);"
16367   [(set (attr "type")
16368         (cond [(match_operand:DF 3 "mult_operator" "")
16369                  (const_string "fmul")
16370                (match_operand:DF 3 "div_operator" "")
16371                  (const_string "fdiv")
16372               ]
16373               (const_string "fop")))
16374    (set_attr "mode" "SF")])
16375
16376 (define_insn "*fop_df_6_i387"
16377   [(set (match_operand:DF 0 "register_operand" "=f,f")
16378         (match_operator:DF 3 "binary_fp_operator"
16379           [(float_extend:DF
16380             (match_operand:SF 1 "register_operand" "0,f"))
16381            (float_extend:DF
16382             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16383   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16384    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16385   "* return output_387_binary_op (insn, operands);"
16386   [(set (attr "type")
16387         (cond [(match_operand:DF 3 "mult_operator" "")
16388                  (const_string "fmul")
16389                (match_operand:DF 3 "div_operator" "")
16390                  (const_string "fdiv")
16391               ]
16392               (const_string "fop")))
16393    (set_attr "mode" "SF")])
16394
16395 (define_insn "*fop_xf_comm_i387"
16396   [(set (match_operand:XF 0 "register_operand" "=f")
16397         (match_operator:XF 3 "binary_fp_operator"
16398                         [(match_operand:XF 1 "register_operand" "%0")
16399                          (match_operand:XF 2 "register_operand" "f")]))]
16400   "TARGET_80387
16401    && COMMUTATIVE_ARITH_P (operands[3])"
16402   "* return output_387_binary_op (insn, operands);"
16403   [(set (attr "type")
16404         (if_then_else (match_operand:XF 3 "mult_operator" "")
16405            (const_string "fmul")
16406            (const_string "fop")))
16407    (set_attr "mode" "XF")])
16408
16409 (define_insn "*fop_xf_1_i387"
16410   [(set (match_operand:XF 0 "register_operand" "=f,f")
16411         (match_operator:XF 3 "binary_fp_operator"
16412                         [(match_operand:XF 1 "register_operand" "0,f")
16413                          (match_operand:XF 2 "register_operand" "f,0")]))]
16414   "TARGET_80387
16415    && !COMMUTATIVE_ARITH_P (operands[3])"
16416   "* return output_387_binary_op (insn, operands);"
16417   [(set (attr "type")
16418         (cond [(match_operand:XF 3 "mult_operator" "")
16419                  (const_string "fmul")
16420                (match_operand:XF 3 "div_operator" "")
16421                  (const_string "fdiv")
16422               ]
16423               (const_string "fop")))
16424    (set_attr "mode" "XF")])
16425
16426 (define_insn "*fop_xf_2_i387"
16427   [(set (match_operand:XF 0 "register_operand" "=f,f")
16428         (match_operator:XF 3 "binary_fp_operator"
16429           [(float:XF
16430              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16431            (match_operand:XF 2 "register_operand" "0,0")]))]
16432   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16433   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16434   [(set (attr "type")
16435         (cond [(match_operand:XF 3 "mult_operator" "")
16436                  (const_string "fmul")
16437                (match_operand:XF 3 "div_operator" "")
16438                  (const_string "fdiv")
16439               ]
16440               (const_string "fop")))
16441    (set_attr "fp_int_src" "true")
16442    (set_attr "mode" "<MODE>")])
16443
16444 (define_insn "*fop_xf_3_i387"
16445   [(set (match_operand:XF 0 "register_operand" "=f,f")
16446         (match_operator:XF 3 "binary_fp_operator"
16447           [(match_operand:XF 1 "register_operand" "0,0")
16448            (float:XF
16449              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16450   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16451   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16452   [(set (attr "type")
16453         (cond [(match_operand:XF 3 "mult_operator" "")
16454                  (const_string "fmul")
16455                (match_operand:XF 3 "div_operator" "")
16456                  (const_string "fdiv")
16457               ]
16458               (const_string "fop")))
16459    (set_attr "fp_int_src" "true")
16460    (set_attr "mode" "<MODE>")])
16461
16462 (define_insn "*fop_xf_4_i387"
16463   [(set (match_operand:XF 0 "register_operand" "=f,f")
16464         (match_operator:XF 3 "binary_fp_operator"
16465            [(float_extend:XF
16466               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16467             (match_operand:XF 2 "register_operand" "0,f")]))]
16468   "TARGET_80387"
16469   "* return output_387_binary_op (insn, operands);"
16470   [(set (attr "type")
16471         (cond [(match_operand:XF 3 "mult_operator" "")
16472                  (const_string "fmul")
16473                (match_operand:XF 3 "div_operator" "")
16474                  (const_string "fdiv")
16475               ]
16476               (const_string "fop")))
16477    (set_attr "mode" "<MODE>")])
16478
16479 (define_insn "*fop_xf_5_i387"
16480   [(set (match_operand:XF 0 "register_operand" "=f,f")
16481         (match_operator:XF 3 "binary_fp_operator"
16482           [(match_operand:XF 1 "register_operand" "0,f")
16483            (float_extend:XF
16484              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16485   "TARGET_80387"
16486   "* return output_387_binary_op (insn, operands);"
16487   [(set (attr "type")
16488         (cond [(match_operand:XF 3 "mult_operator" "")
16489                  (const_string "fmul")
16490                (match_operand:XF 3 "div_operator" "")
16491                  (const_string "fdiv")
16492               ]
16493               (const_string "fop")))
16494    (set_attr "mode" "<MODE>")])
16495
16496 (define_insn "*fop_xf_6_i387"
16497   [(set (match_operand:XF 0 "register_operand" "=f,f")
16498         (match_operator:XF 3 "binary_fp_operator"
16499           [(float_extend:XF
16500              (match_operand:MODEF 1 "register_operand" "0,f"))
16501            (float_extend:XF
16502              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16503   "TARGET_80387"
16504   "* return output_387_binary_op (insn, operands);"
16505   [(set (attr "type")
16506         (cond [(match_operand:XF 3 "mult_operator" "")
16507                  (const_string "fmul")
16508                (match_operand:XF 3 "div_operator" "")
16509                  (const_string "fdiv")
16510               ]
16511               (const_string "fop")))
16512    (set_attr "mode" "<MODE>")])
16513
16514 (define_split
16515   [(set (match_operand 0 "register_operand" "")
16516         (match_operator 3 "binary_fp_operator"
16517            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16518             (match_operand 2 "register_operand" "")]))]
16519   "reload_completed
16520    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16521    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16522   [(const_int 0)]
16523 {
16524   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16525   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16526   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16527                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16528                                           GET_MODE (operands[3]),
16529                                           operands[4],
16530                                           operands[2])));
16531   ix86_free_from_memory (GET_MODE (operands[1]));
16532   DONE;
16533 })
16534
16535 (define_split
16536   [(set (match_operand 0 "register_operand" "")
16537         (match_operator 3 "binary_fp_operator"
16538            [(match_operand 1 "register_operand" "")
16539             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16540   "reload_completed
16541    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16542    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16543   [(const_int 0)]
16544 {
16545   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16546   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16547   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16548                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16549                                           GET_MODE (operands[3]),
16550                                           operands[1],
16551                                           operands[4])));
16552   ix86_free_from_memory (GET_MODE (operands[2]));
16553   DONE;
16554 })
16555 \f
16556 ;; FPU special functions.
16557
16558 ;; This pattern implements a no-op XFmode truncation for
16559 ;; all fancy i386 XFmode math functions.
16560
16561 (define_insn "truncxf<mode>2_i387_noop_unspec"
16562   [(set (match_operand:MODEF 0 "register_operand" "=f")
16563         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16564         UNSPEC_TRUNC_NOOP))]
16565   "TARGET_USE_FANCY_MATH_387"
16566   "* return output_387_reg_move (insn, operands);"
16567   [(set_attr "type" "fmov")
16568    (set_attr "mode" "<MODE>")])
16569
16570 (define_insn "sqrtxf2"
16571   [(set (match_operand:XF 0 "register_operand" "=f")
16572         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16573   "TARGET_USE_FANCY_MATH_387"
16574   "fsqrt"
16575   [(set_attr "type" "fpspc")
16576    (set_attr "mode" "XF")
16577    (set_attr "athlon_decode" "direct")
16578    (set_attr "amdfam10_decode" "direct")])
16579
16580 (define_insn "sqrt_extend<mode>xf2_i387"
16581   [(set (match_operand:XF 0 "register_operand" "=f")
16582         (sqrt:XF
16583           (float_extend:XF
16584             (match_operand:MODEF 1 "register_operand" "0"))))]
16585   "TARGET_USE_FANCY_MATH_387"
16586   "fsqrt"
16587   [(set_attr "type" "fpspc")
16588    (set_attr "mode" "XF")
16589    (set_attr "athlon_decode" "direct")
16590    (set_attr "amdfam10_decode" "direct")])
16591
16592 (define_insn "*rsqrtsf2_sse"
16593   [(set (match_operand:SF 0 "register_operand" "=x")
16594         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16595                    UNSPEC_RSQRT))]
16596   "TARGET_SSE_MATH"
16597   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16598   [(set_attr "type" "sse")
16599    (set_attr "atom_sse_attr" "rcp")
16600    (set_attr "prefix" "maybe_vex")
16601    (set_attr "mode" "SF")])
16602
16603 (define_expand "rsqrtsf2"
16604   [(set (match_operand:SF 0 "register_operand" "")
16605         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16606                    UNSPEC_RSQRT))]
16607   "TARGET_SSE_MATH"
16608 {
16609   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16610   DONE;
16611 })
16612
16613 (define_insn "*sqrt<mode>2_sse"
16614   [(set (match_operand:MODEF 0 "register_operand" "=x")
16615         (sqrt:MODEF
16616           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16617   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16618   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16619   [(set_attr "type" "sse")
16620    (set_attr "atom_sse_attr" "sqrt")
16621    (set_attr "prefix" "maybe_vex")
16622    (set_attr "mode" "<MODE>")
16623    (set_attr "athlon_decode" "*")
16624    (set_attr "amdfam10_decode" "*")])
16625
16626 (define_expand "sqrt<mode>2"
16627   [(set (match_operand:MODEF 0 "register_operand" "")
16628         (sqrt:MODEF
16629           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16630   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16631    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16632 {
16633   if (<MODE>mode == SFmode
16634       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16635       && flag_finite_math_only && !flag_trapping_math
16636       && flag_unsafe_math_optimizations)
16637     {
16638       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16639       DONE;
16640     }
16641
16642   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16643     {
16644       rtx op0 = gen_reg_rtx (XFmode);
16645       rtx op1 = force_reg (<MODE>mode, operands[1]);
16646
16647       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16648       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16649       DONE;
16650    }
16651 })
16652
16653 (define_insn "fpremxf4_i387"
16654   [(set (match_operand:XF 0 "register_operand" "=f")
16655         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16656                     (match_operand:XF 3 "register_operand" "1")]
16657                    UNSPEC_FPREM_F))
16658    (set (match_operand:XF 1 "register_operand" "=u")
16659         (unspec:XF [(match_dup 2) (match_dup 3)]
16660                    UNSPEC_FPREM_U))
16661    (set (reg:CCFP FPSR_REG)
16662         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16663                      UNSPEC_C2_FLAG))]
16664   "TARGET_USE_FANCY_MATH_387"
16665   "fprem"
16666   [(set_attr "type" "fpspc")
16667    (set_attr "mode" "XF")])
16668
16669 (define_expand "fmodxf3"
16670   [(use (match_operand:XF 0 "register_operand" ""))
16671    (use (match_operand:XF 1 "general_operand" ""))
16672    (use (match_operand:XF 2 "general_operand" ""))]
16673   "TARGET_USE_FANCY_MATH_387"
16674 {
16675   rtx label = gen_label_rtx ();
16676
16677   rtx op1 = gen_reg_rtx (XFmode);
16678   rtx op2 = gen_reg_rtx (XFmode);
16679
16680   emit_move_insn (op2, operands[2]);
16681   emit_move_insn (op1, operands[1]);
16682
16683   emit_label (label);
16684   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16685   ix86_emit_fp_unordered_jump (label);
16686   LABEL_NUSES (label) = 1;
16687
16688   emit_move_insn (operands[0], op1);
16689   DONE;
16690 })
16691
16692 (define_expand "fmod<mode>3"
16693   [(use (match_operand:MODEF 0 "register_operand" ""))
16694    (use (match_operand:MODEF 1 "general_operand" ""))
16695    (use (match_operand:MODEF 2 "general_operand" ""))]
16696   "TARGET_USE_FANCY_MATH_387"
16697 {
16698   rtx label = gen_label_rtx ();
16699
16700   rtx op1 = gen_reg_rtx (XFmode);
16701   rtx op2 = gen_reg_rtx (XFmode);
16702
16703   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16704   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16705
16706   emit_label (label);
16707   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16708   ix86_emit_fp_unordered_jump (label);
16709   LABEL_NUSES (label) = 1;
16710
16711   /* Truncate the result properly for strict SSE math.  */
16712   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16713       && !TARGET_MIX_SSE_I387)
16714     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16715   else
16716     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16717
16718   DONE;
16719 })
16720
16721 (define_insn "fprem1xf4_i387"
16722   [(set (match_operand:XF 0 "register_operand" "=f")
16723         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16724                     (match_operand:XF 3 "register_operand" "1")]
16725                    UNSPEC_FPREM1_F))
16726    (set (match_operand:XF 1 "register_operand" "=u")
16727         (unspec:XF [(match_dup 2) (match_dup 3)]
16728                    UNSPEC_FPREM1_U))
16729    (set (reg:CCFP FPSR_REG)
16730         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16731                      UNSPEC_C2_FLAG))]
16732   "TARGET_USE_FANCY_MATH_387"
16733   "fprem1"
16734   [(set_attr "type" "fpspc")
16735    (set_attr "mode" "XF")])
16736
16737 (define_expand "remainderxf3"
16738   [(use (match_operand:XF 0 "register_operand" ""))
16739    (use (match_operand:XF 1 "general_operand" ""))
16740    (use (match_operand:XF 2 "general_operand" ""))]
16741   "TARGET_USE_FANCY_MATH_387"
16742 {
16743   rtx label = gen_label_rtx ();
16744
16745   rtx op1 = gen_reg_rtx (XFmode);
16746   rtx op2 = gen_reg_rtx (XFmode);
16747
16748   emit_move_insn (op2, operands[2]);
16749   emit_move_insn (op1, operands[1]);
16750
16751   emit_label (label);
16752   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16753   ix86_emit_fp_unordered_jump (label);
16754   LABEL_NUSES (label) = 1;
16755
16756   emit_move_insn (operands[0], op1);
16757   DONE;
16758 })
16759
16760 (define_expand "remainder<mode>3"
16761   [(use (match_operand:MODEF 0 "register_operand" ""))
16762    (use (match_operand:MODEF 1 "general_operand" ""))
16763    (use (match_operand:MODEF 2 "general_operand" ""))]
16764   "TARGET_USE_FANCY_MATH_387"
16765 {
16766   rtx label = gen_label_rtx ();
16767
16768   rtx op1 = gen_reg_rtx (XFmode);
16769   rtx op2 = gen_reg_rtx (XFmode);
16770
16771   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16772   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16773
16774   emit_label (label);
16775
16776   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16777   ix86_emit_fp_unordered_jump (label);
16778   LABEL_NUSES (label) = 1;
16779
16780   /* Truncate the result properly for strict SSE math.  */
16781   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16782       && !TARGET_MIX_SSE_I387)
16783     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16784   else
16785     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16786
16787   DONE;
16788 })
16789
16790 (define_insn "*sinxf2_i387"
16791   [(set (match_operand:XF 0 "register_operand" "=f")
16792         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16793   "TARGET_USE_FANCY_MATH_387
16794    && flag_unsafe_math_optimizations"
16795   "fsin"
16796   [(set_attr "type" "fpspc")
16797    (set_attr "mode" "XF")])
16798
16799 (define_insn "*sin_extend<mode>xf2_i387"
16800   [(set (match_operand:XF 0 "register_operand" "=f")
16801         (unspec:XF [(float_extend:XF
16802                       (match_operand:MODEF 1 "register_operand" "0"))]
16803                    UNSPEC_SIN))]
16804   "TARGET_USE_FANCY_MATH_387
16805    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16806        || TARGET_MIX_SSE_I387)
16807    && flag_unsafe_math_optimizations"
16808   "fsin"
16809   [(set_attr "type" "fpspc")
16810    (set_attr "mode" "XF")])
16811
16812 (define_insn "*cosxf2_i387"
16813   [(set (match_operand:XF 0 "register_operand" "=f")
16814         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16815   "TARGET_USE_FANCY_MATH_387
16816    && flag_unsafe_math_optimizations"
16817   "fcos"
16818   [(set_attr "type" "fpspc")
16819    (set_attr "mode" "XF")])
16820
16821 (define_insn "*cos_extend<mode>xf2_i387"
16822   [(set (match_operand:XF 0 "register_operand" "=f")
16823         (unspec:XF [(float_extend:XF
16824                       (match_operand:MODEF 1 "register_operand" "0"))]
16825                    UNSPEC_COS))]
16826   "TARGET_USE_FANCY_MATH_387
16827    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16828        || TARGET_MIX_SSE_I387)
16829    && flag_unsafe_math_optimizations"
16830   "fcos"
16831   [(set_attr "type" "fpspc")
16832    (set_attr "mode" "XF")])
16833
16834 ;; When sincos pattern is defined, sin and cos builtin functions will be
16835 ;; expanded to sincos pattern with one of its outputs left unused.
16836 ;; CSE pass will figure out if two sincos patterns can be combined,
16837 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16838 ;; depending on the unused output.
16839
16840 (define_insn "sincosxf3"
16841   [(set (match_operand:XF 0 "register_operand" "=f")
16842         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16843                    UNSPEC_SINCOS_COS))
16844    (set (match_operand:XF 1 "register_operand" "=u")
16845         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16846   "TARGET_USE_FANCY_MATH_387
16847    && flag_unsafe_math_optimizations"
16848   "fsincos"
16849   [(set_attr "type" "fpspc")
16850    (set_attr "mode" "XF")])
16851
16852 (define_split
16853   [(set (match_operand:XF 0 "register_operand" "")
16854         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16855                    UNSPEC_SINCOS_COS))
16856    (set (match_operand:XF 1 "register_operand" "")
16857         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16858   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16859    && !(reload_completed || reload_in_progress)"
16860   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16861   "")
16862
16863 (define_split
16864   [(set (match_operand:XF 0 "register_operand" "")
16865         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16866                    UNSPEC_SINCOS_COS))
16867    (set (match_operand:XF 1 "register_operand" "")
16868         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16869   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16870    && !(reload_completed || reload_in_progress)"
16871   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16872   "")
16873
16874 (define_insn "sincos_extend<mode>xf3_i387"
16875   [(set (match_operand:XF 0 "register_operand" "=f")
16876         (unspec:XF [(float_extend:XF
16877                       (match_operand:MODEF 2 "register_operand" "0"))]
16878                    UNSPEC_SINCOS_COS))
16879    (set (match_operand:XF 1 "register_operand" "=u")
16880         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16881   "TARGET_USE_FANCY_MATH_387
16882    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16883        || TARGET_MIX_SSE_I387)
16884    && flag_unsafe_math_optimizations"
16885   "fsincos"
16886   [(set_attr "type" "fpspc")
16887    (set_attr "mode" "XF")])
16888
16889 (define_split
16890   [(set (match_operand:XF 0 "register_operand" "")
16891         (unspec:XF [(float_extend:XF
16892                       (match_operand:MODEF 2 "register_operand" ""))]
16893                    UNSPEC_SINCOS_COS))
16894    (set (match_operand:XF 1 "register_operand" "")
16895         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16896   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16897    && !(reload_completed || reload_in_progress)"
16898   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16899   "")
16900
16901 (define_split
16902   [(set (match_operand:XF 0 "register_operand" "")
16903         (unspec:XF [(float_extend:XF
16904                       (match_operand:MODEF 2 "register_operand" ""))]
16905                    UNSPEC_SINCOS_COS))
16906    (set (match_operand:XF 1 "register_operand" "")
16907         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16908   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16909    && !(reload_completed || reload_in_progress)"
16910   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16911   "")
16912
16913 (define_expand "sincos<mode>3"
16914   [(use (match_operand:MODEF 0 "register_operand" ""))
16915    (use (match_operand:MODEF 1 "register_operand" ""))
16916    (use (match_operand:MODEF 2 "register_operand" ""))]
16917   "TARGET_USE_FANCY_MATH_387
16918    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16919        || TARGET_MIX_SSE_I387)
16920    && flag_unsafe_math_optimizations"
16921 {
16922   rtx op0 = gen_reg_rtx (XFmode);
16923   rtx op1 = gen_reg_rtx (XFmode);
16924
16925   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16926   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16927   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16928   DONE;
16929 })
16930
16931 (define_insn "fptanxf4_i387"
16932   [(set (match_operand:XF 0 "register_operand" "=f")
16933         (match_operand:XF 3 "const_double_operand" "F"))
16934    (set (match_operand:XF 1 "register_operand" "=u")
16935         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16936                    UNSPEC_TAN))]
16937   "TARGET_USE_FANCY_MATH_387
16938    && flag_unsafe_math_optimizations
16939    && standard_80387_constant_p (operands[3]) == 2"
16940   "fptan"
16941   [(set_attr "type" "fpspc")
16942    (set_attr "mode" "XF")])
16943
16944 (define_insn "fptan_extend<mode>xf4_i387"
16945   [(set (match_operand:MODEF 0 "register_operand" "=f")
16946         (match_operand:MODEF 3 "const_double_operand" "F"))
16947    (set (match_operand:XF 1 "register_operand" "=u")
16948         (unspec:XF [(float_extend:XF
16949                       (match_operand:MODEF 2 "register_operand" "0"))]
16950                    UNSPEC_TAN))]
16951   "TARGET_USE_FANCY_MATH_387
16952    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16953        || TARGET_MIX_SSE_I387)
16954    && flag_unsafe_math_optimizations
16955    && standard_80387_constant_p (operands[3]) == 2"
16956   "fptan"
16957   [(set_attr "type" "fpspc")
16958    (set_attr "mode" "XF")])
16959
16960 (define_expand "tanxf2"
16961   [(use (match_operand:XF 0 "register_operand" ""))
16962    (use (match_operand:XF 1 "register_operand" ""))]
16963   "TARGET_USE_FANCY_MATH_387
16964    && flag_unsafe_math_optimizations"
16965 {
16966   rtx one = gen_reg_rtx (XFmode);
16967   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16968
16969   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16970   DONE;
16971 })
16972
16973 (define_expand "tan<mode>2"
16974   [(use (match_operand:MODEF 0 "register_operand" ""))
16975    (use (match_operand:MODEF 1 "register_operand" ""))]
16976   "TARGET_USE_FANCY_MATH_387
16977    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16978        || TARGET_MIX_SSE_I387)
16979    && flag_unsafe_math_optimizations"
16980 {
16981   rtx op0 = gen_reg_rtx (XFmode);
16982
16983   rtx one = gen_reg_rtx (<MODE>mode);
16984   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16985
16986   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16987                                              operands[1], op2));
16988   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16989   DONE;
16990 })
16991
16992 (define_insn "*fpatanxf3_i387"
16993   [(set (match_operand:XF 0 "register_operand" "=f")
16994         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16995                     (match_operand:XF 2 "register_operand" "u")]
16996                    UNSPEC_FPATAN))
16997    (clobber (match_scratch:XF 3 "=2"))]
16998   "TARGET_USE_FANCY_MATH_387
16999    && flag_unsafe_math_optimizations"
17000   "fpatan"
17001   [(set_attr "type" "fpspc")
17002    (set_attr "mode" "XF")])
17003
17004 (define_insn "fpatan_extend<mode>xf3_i387"
17005   [(set (match_operand:XF 0 "register_operand" "=f")
17006         (unspec:XF [(float_extend:XF
17007                       (match_operand:MODEF 1 "register_operand" "0"))
17008                     (float_extend:XF
17009                       (match_operand:MODEF 2 "register_operand" "u"))]
17010                    UNSPEC_FPATAN))
17011    (clobber (match_scratch:XF 3 "=2"))]
17012   "TARGET_USE_FANCY_MATH_387
17013    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17014        || TARGET_MIX_SSE_I387)
17015    && flag_unsafe_math_optimizations"
17016   "fpatan"
17017   [(set_attr "type" "fpspc")
17018    (set_attr "mode" "XF")])
17019
17020 (define_expand "atan2xf3"
17021   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17022                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17023                                (match_operand:XF 1 "register_operand" "")]
17024                               UNSPEC_FPATAN))
17025               (clobber (match_scratch:XF 3 ""))])]
17026   "TARGET_USE_FANCY_MATH_387
17027    && flag_unsafe_math_optimizations"
17028   "")
17029
17030 (define_expand "atan2<mode>3"
17031   [(use (match_operand:MODEF 0 "register_operand" ""))
17032    (use (match_operand:MODEF 1 "register_operand" ""))
17033    (use (match_operand:MODEF 2 "register_operand" ""))]
17034   "TARGET_USE_FANCY_MATH_387
17035    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17036        || TARGET_MIX_SSE_I387)
17037    && flag_unsafe_math_optimizations"
17038 {
17039   rtx op0 = gen_reg_rtx (XFmode);
17040
17041   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17042   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17043   DONE;
17044 })
17045
17046 (define_expand "atanxf2"
17047   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17048                    (unspec:XF [(match_dup 2)
17049                                (match_operand:XF 1 "register_operand" "")]
17050                               UNSPEC_FPATAN))
17051               (clobber (match_scratch:XF 3 ""))])]
17052   "TARGET_USE_FANCY_MATH_387
17053    && flag_unsafe_math_optimizations"
17054 {
17055   operands[2] = gen_reg_rtx (XFmode);
17056   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17057 })
17058
17059 (define_expand "atan<mode>2"
17060   [(use (match_operand:MODEF 0 "register_operand" ""))
17061    (use (match_operand:MODEF 1 "register_operand" ""))]
17062   "TARGET_USE_FANCY_MATH_387
17063    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17064        || TARGET_MIX_SSE_I387)
17065    && flag_unsafe_math_optimizations"
17066 {
17067   rtx op0 = gen_reg_rtx (XFmode);
17068
17069   rtx op2 = gen_reg_rtx (<MODE>mode);
17070   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17071
17072   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17073   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17074   DONE;
17075 })
17076
17077 (define_expand "asinxf2"
17078   [(set (match_dup 2)
17079         (mult:XF (match_operand:XF 1 "register_operand" "")
17080                  (match_dup 1)))
17081    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17082    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17083    (parallel [(set (match_operand:XF 0 "register_operand" "")
17084                    (unspec:XF [(match_dup 5) (match_dup 1)]
17085                               UNSPEC_FPATAN))
17086               (clobber (match_scratch:XF 6 ""))])]
17087   "TARGET_USE_FANCY_MATH_387
17088    && flag_unsafe_math_optimizations"
17089 {
17090   int i;
17091
17092   if (optimize_insn_for_size_p ())
17093     FAIL;
17094
17095   for (i = 2; i < 6; i++)
17096     operands[i] = gen_reg_rtx (XFmode);
17097
17098   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17099 })
17100
17101 (define_expand "asin<mode>2"
17102   [(use (match_operand:MODEF 0 "register_operand" ""))
17103    (use (match_operand:MODEF 1 "general_operand" ""))]
17104  "TARGET_USE_FANCY_MATH_387
17105    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17106        || TARGET_MIX_SSE_I387)
17107    && flag_unsafe_math_optimizations"
17108 {
17109   rtx op0 = gen_reg_rtx (XFmode);
17110   rtx op1 = gen_reg_rtx (XFmode);
17111
17112   if (optimize_insn_for_size_p ())
17113     FAIL;
17114
17115   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17116   emit_insn (gen_asinxf2 (op0, op1));
17117   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17118   DONE;
17119 })
17120
17121 (define_expand "acosxf2"
17122   [(set (match_dup 2)
17123         (mult:XF (match_operand:XF 1 "register_operand" "")
17124                  (match_dup 1)))
17125    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17126    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17127    (parallel [(set (match_operand:XF 0 "register_operand" "")
17128                    (unspec:XF [(match_dup 1) (match_dup 5)]
17129                               UNSPEC_FPATAN))
17130               (clobber (match_scratch:XF 6 ""))])]
17131   "TARGET_USE_FANCY_MATH_387
17132    && flag_unsafe_math_optimizations"
17133 {
17134   int i;
17135
17136   if (optimize_insn_for_size_p ())
17137     FAIL;
17138
17139   for (i = 2; i < 6; i++)
17140     operands[i] = gen_reg_rtx (XFmode);
17141
17142   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17143 })
17144
17145 (define_expand "acos<mode>2"
17146   [(use (match_operand:MODEF 0 "register_operand" ""))
17147    (use (match_operand:MODEF 1 "general_operand" ""))]
17148  "TARGET_USE_FANCY_MATH_387
17149    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17150        || TARGET_MIX_SSE_I387)
17151    && flag_unsafe_math_optimizations"
17152 {
17153   rtx op0 = gen_reg_rtx (XFmode);
17154   rtx op1 = gen_reg_rtx (XFmode);
17155
17156   if (optimize_insn_for_size_p ())
17157     FAIL;
17158
17159   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17160   emit_insn (gen_acosxf2 (op0, op1));
17161   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17162   DONE;
17163 })
17164
17165 (define_insn "fyl2xxf3_i387"
17166   [(set (match_operand:XF 0 "register_operand" "=f")
17167         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17168                     (match_operand:XF 2 "register_operand" "u")]
17169                    UNSPEC_FYL2X))
17170    (clobber (match_scratch:XF 3 "=2"))]
17171   "TARGET_USE_FANCY_MATH_387
17172    && flag_unsafe_math_optimizations"
17173   "fyl2x"
17174   [(set_attr "type" "fpspc")
17175    (set_attr "mode" "XF")])
17176
17177 (define_insn "fyl2x_extend<mode>xf3_i387"
17178   [(set (match_operand:XF 0 "register_operand" "=f")
17179         (unspec:XF [(float_extend:XF
17180                       (match_operand:MODEF 1 "register_operand" "0"))
17181                     (match_operand:XF 2 "register_operand" "u")]
17182                    UNSPEC_FYL2X))
17183    (clobber (match_scratch:XF 3 "=2"))]
17184   "TARGET_USE_FANCY_MATH_387
17185    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17186        || TARGET_MIX_SSE_I387)
17187    && flag_unsafe_math_optimizations"
17188   "fyl2x"
17189   [(set_attr "type" "fpspc")
17190    (set_attr "mode" "XF")])
17191
17192 (define_expand "logxf2"
17193   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17194                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17195                                (match_dup 2)] UNSPEC_FYL2X))
17196               (clobber (match_scratch:XF 3 ""))])]
17197   "TARGET_USE_FANCY_MATH_387
17198    && flag_unsafe_math_optimizations"
17199 {
17200   operands[2] = gen_reg_rtx (XFmode);
17201   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17202 })
17203
17204 (define_expand "log<mode>2"
17205   [(use (match_operand:MODEF 0 "register_operand" ""))
17206    (use (match_operand:MODEF 1 "register_operand" ""))]
17207   "TARGET_USE_FANCY_MATH_387
17208    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17209        || TARGET_MIX_SSE_I387)
17210    && flag_unsafe_math_optimizations"
17211 {
17212   rtx op0 = gen_reg_rtx (XFmode);
17213
17214   rtx op2 = gen_reg_rtx (XFmode);
17215   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17216
17217   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17218   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17219   DONE;
17220 })
17221
17222 (define_expand "log10xf2"
17223   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17224                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17225                                (match_dup 2)] UNSPEC_FYL2X))
17226               (clobber (match_scratch:XF 3 ""))])]
17227   "TARGET_USE_FANCY_MATH_387
17228    && flag_unsafe_math_optimizations"
17229 {
17230   operands[2] = gen_reg_rtx (XFmode);
17231   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17232 })
17233
17234 (define_expand "log10<mode>2"
17235   [(use (match_operand:MODEF 0 "register_operand" ""))
17236    (use (match_operand:MODEF 1 "register_operand" ""))]
17237   "TARGET_USE_FANCY_MATH_387
17238    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17239        || TARGET_MIX_SSE_I387)
17240    && flag_unsafe_math_optimizations"
17241 {
17242   rtx op0 = gen_reg_rtx (XFmode);
17243
17244   rtx op2 = gen_reg_rtx (XFmode);
17245   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17246
17247   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17248   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17249   DONE;
17250 })
17251
17252 (define_expand "log2xf2"
17253   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17254                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17255                                (match_dup 2)] UNSPEC_FYL2X))
17256               (clobber (match_scratch:XF 3 ""))])]
17257   "TARGET_USE_FANCY_MATH_387
17258    && flag_unsafe_math_optimizations"
17259 {
17260   operands[2] = gen_reg_rtx (XFmode);
17261   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17262 })
17263
17264 (define_expand "log2<mode>2"
17265   [(use (match_operand:MODEF 0 "register_operand" ""))
17266    (use (match_operand:MODEF 1 "register_operand" ""))]
17267   "TARGET_USE_FANCY_MATH_387
17268    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17269        || TARGET_MIX_SSE_I387)
17270    && flag_unsafe_math_optimizations"
17271 {
17272   rtx op0 = gen_reg_rtx (XFmode);
17273
17274   rtx op2 = gen_reg_rtx (XFmode);
17275   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17276
17277   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17278   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17279   DONE;
17280 })
17281
17282 (define_insn "fyl2xp1xf3_i387"
17283   [(set (match_operand:XF 0 "register_operand" "=f")
17284         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17285                     (match_operand:XF 2 "register_operand" "u")]
17286                    UNSPEC_FYL2XP1))
17287    (clobber (match_scratch:XF 3 "=2"))]
17288   "TARGET_USE_FANCY_MATH_387
17289    && flag_unsafe_math_optimizations"
17290   "fyl2xp1"
17291   [(set_attr "type" "fpspc")
17292    (set_attr "mode" "XF")])
17293
17294 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17295   [(set (match_operand:XF 0 "register_operand" "=f")
17296         (unspec:XF [(float_extend:XF
17297                       (match_operand:MODEF 1 "register_operand" "0"))
17298                     (match_operand:XF 2 "register_operand" "u")]
17299                    UNSPEC_FYL2XP1))
17300    (clobber (match_scratch:XF 3 "=2"))]
17301   "TARGET_USE_FANCY_MATH_387
17302    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17303        || TARGET_MIX_SSE_I387)
17304    && flag_unsafe_math_optimizations"
17305   "fyl2xp1"
17306   [(set_attr "type" "fpspc")
17307    (set_attr "mode" "XF")])
17308
17309 (define_expand "log1pxf2"
17310   [(use (match_operand:XF 0 "register_operand" ""))
17311    (use (match_operand:XF 1 "register_operand" ""))]
17312   "TARGET_USE_FANCY_MATH_387
17313    && flag_unsafe_math_optimizations"
17314 {
17315   if (optimize_insn_for_size_p ())
17316     FAIL;
17317
17318   ix86_emit_i387_log1p (operands[0], operands[1]);
17319   DONE;
17320 })
17321
17322 (define_expand "log1p<mode>2"
17323   [(use (match_operand:MODEF 0 "register_operand" ""))
17324    (use (match_operand:MODEF 1 "register_operand" ""))]
17325   "TARGET_USE_FANCY_MATH_387
17326    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17327        || TARGET_MIX_SSE_I387)
17328    && flag_unsafe_math_optimizations"
17329 {
17330   rtx op0;
17331
17332   if (optimize_insn_for_size_p ())
17333     FAIL;
17334
17335   op0 = gen_reg_rtx (XFmode);
17336
17337   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17338
17339   ix86_emit_i387_log1p (op0, operands[1]);
17340   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17341   DONE;
17342 })
17343
17344 (define_insn "fxtractxf3_i387"
17345   [(set (match_operand:XF 0 "register_operand" "=f")
17346         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17347                    UNSPEC_XTRACT_FRACT))
17348    (set (match_operand:XF 1 "register_operand" "=u")
17349         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17350   "TARGET_USE_FANCY_MATH_387
17351    && flag_unsafe_math_optimizations"
17352   "fxtract"
17353   [(set_attr "type" "fpspc")
17354    (set_attr "mode" "XF")])
17355
17356 (define_insn "fxtract_extend<mode>xf3_i387"
17357   [(set (match_operand:XF 0 "register_operand" "=f")
17358         (unspec:XF [(float_extend:XF
17359                       (match_operand:MODEF 2 "register_operand" "0"))]
17360                    UNSPEC_XTRACT_FRACT))
17361    (set (match_operand:XF 1 "register_operand" "=u")
17362         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17363   "TARGET_USE_FANCY_MATH_387
17364    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17365        || TARGET_MIX_SSE_I387)
17366    && flag_unsafe_math_optimizations"
17367   "fxtract"
17368   [(set_attr "type" "fpspc")
17369    (set_attr "mode" "XF")])
17370
17371 (define_expand "logbxf2"
17372   [(parallel [(set (match_dup 2)
17373                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17374                               UNSPEC_XTRACT_FRACT))
17375               (set (match_operand:XF 0 "register_operand" "")
17376                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17377   "TARGET_USE_FANCY_MATH_387
17378    && flag_unsafe_math_optimizations"
17379 {
17380   operands[2] = gen_reg_rtx (XFmode);
17381 })
17382
17383 (define_expand "logb<mode>2"
17384   [(use (match_operand:MODEF 0 "register_operand" ""))
17385    (use (match_operand:MODEF 1 "register_operand" ""))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17388        || TARGET_MIX_SSE_I387)
17389    && flag_unsafe_math_optimizations"
17390 {
17391   rtx op0 = gen_reg_rtx (XFmode);
17392   rtx op1 = gen_reg_rtx (XFmode);
17393
17394   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17395   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17396   DONE;
17397 })
17398
17399 (define_expand "ilogbxf2"
17400   [(use (match_operand:SI 0 "register_operand" ""))
17401    (use (match_operand:XF 1 "register_operand" ""))]
17402   "TARGET_USE_FANCY_MATH_387
17403    && flag_unsafe_math_optimizations"
17404 {
17405   rtx op0, op1;
17406
17407   if (optimize_insn_for_size_p ())
17408     FAIL;
17409
17410   op0 = gen_reg_rtx (XFmode);
17411   op1 = gen_reg_rtx (XFmode);
17412
17413   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17414   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17415   DONE;
17416 })
17417
17418 (define_expand "ilogb<mode>2"
17419   [(use (match_operand:SI 0 "register_operand" ""))
17420    (use (match_operand:MODEF 1 "register_operand" ""))]
17421   "TARGET_USE_FANCY_MATH_387
17422    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17423        || TARGET_MIX_SSE_I387)
17424    && flag_unsafe_math_optimizations"
17425 {
17426   rtx op0, op1;
17427
17428   if (optimize_insn_for_size_p ())
17429     FAIL;
17430
17431   op0 = gen_reg_rtx (XFmode);
17432   op1 = gen_reg_rtx (XFmode);
17433
17434   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17435   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17436   DONE;
17437 })
17438
17439 (define_insn "*f2xm1xf2_i387"
17440   [(set (match_operand:XF 0 "register_operand" "=f")
17441         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17442                    UNSPEC_F2XM1))]
17443   "TARGET_USE_FANCY_MATH_387
17444    && flag_unsafe_math_optimizations"
17445   "f2xm1"
17446   [(set_attr "type" "fpspc")
17447    (set_attr "mode" "XF")])
17448
17449 (define_insn "*fscalexf4_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_FSCALE_FRACT))
17454    (set (match_operand:XF 1 "register_operand" "=u")
17455         (unspec:XF [(match_dup 2) (match_dup 3)]
17456                    UNSPEC_FSCALE_EXP))]
17457   "TARGET_USE_FANCY_MATH_387
17458    && flag_unsafe_math_optimizations"
17459   "fscale"
17460   [(set_attr "type" "fpspc")
17461    (set_attr "mode" "XF")])
17462
17463 (define_expand "expNcorexf3"
17464   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17465                                (match_operand:XF 2 "register_operand" "")))
17466    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17467    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17468    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17469    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17470    (parallel [(set (match_operand:XF 0 "register_operand" "")
17471                    (unspec:XF [(match_dup 8) (match_dup 4)]
17472                               UNSPEC_FSCALE_FRACT))
17473               (set (match_dup 9)
17474                    (unspec:XF [(match_dup 8) (match_dup 4)]
17475                               UNSPEC_FSCALE_EXP))])]
17476   "TARGET_USE_FANCY_MATH_387
17477    && flag_unsafe_math_optimizations"
17478 {
17479   int i;
17480
17481   if (optimize_insn_for_size_p ())
17482     FAIL;
17483
17484   for (i = 3; i < 10; i++)
17485     operands[i] = gen_reg_rtx (XFmode);
17486
17487   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17488 })
17489
17490 (define_expand "expxf2"
17491   [(use (match_operand:XF 0 "register_operand" ""))
17492    (use (match_operand:XF 1 "register_operand" ""))]
17493   "TARGET_USE_FANCY_MATH_387
17494    && flag_unsafe_math_optimizations"
17495 {
17496   rtx op2;
17497
17498   if (optimize_insn_for_size_p ())
17499     FAIL;
17500
17501   op2 = gen_reg_rtx (XFmode);
17502   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17503
17504   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17505   DONE;
17506 })
17507
17508 (define_expand "exp<mode>2"
17509   [(use (match_operand:MODEF 0 "register_operand" ""))
17510    (use (match_operand:MODEF 1 "general_operand" ""))]
17511  "TARGET_USE_FANCY_MATH_387
17512    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17513        || TARGET_MIX_SSE_I387)
17514    && flag_unsafe_math_optimizations"
17515 {
17516   rtx op0, op1;
17517
17518   if (optimize_insn_for_size_p ())
17519     FAIL;
17520
17521   op0 = gen_reg_rtx (XFmode);
17522   op1 = gen_reg_rtx (XFmode);
17523
17524   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17525   emit_insn (gen_expxf2 (op0, op1));
17526   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17527   DONE;
17528 })
17529
17530 (define_expand "exp10xf2"
17531   [(use (match_operand:XF 0 "register_operand" ""))
17532    (use (match_operand:XF 1 "register_operand" ""))]
17533   "TARGET_USE_FANCY_MATH_387
17534    && flag_unsafe_math_optimizations"
17535 {
17536   rtx op2;
17537
17538   if (optimize_insn_for_size_p ())
17539     FAIL;
17540
17541   op2 = gen_reg_rtx (XFmode);
17542   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17543
17544   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17545   DONE;
17546 })
17547
17548 (define_expand "exp10<mode>2"
17549   [(use (match_operand:MODEF 0 "register_operand" ""))
17550    (use (match_operand:MODEF 1 "general_operand" ""))]
17551  "TARGET_USE_FANCY_MATH_387
17552    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17553        || TARGET_MIX_SSE_I387)
17554    && flag_unsafe_math_optimizations"
17555 {
17556   rtx op0, op1;
17557
17558   if (optimize_insn_for_size_p ())
17559     FAIL;
17560
17561   op0 = gen_reg_rtx (XFmode);
17562   op1 = gen_reg_rtx (XFmode);
17563
17564   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17565   emit_insn (gen_exp10xf2 (op0, op1));
17566   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17567   DONE;
17568 })
17569
17570 (define_expand "exp2xf2"
17571   [(use (match_operand:XF 0 "register_operand" ""))
17572    (use (match_operand:XF 1 "register_operand" ""))]
17573   "TARGET_USE_FANCY_MATH_387
17574    && flag_unsafe_math_optimizations"
17575 {
17576   rtx op2;
17577
17578   if (optimize_insn_for_size_p ())
17579     FAIL;
17580
17581   op2 = gen_reg_rtx (XFmode);
17582   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17583
17584   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17585   DONE;
17586 })
17587
17588 (define_expand "exp2<mode>2"
17589   [(use (match_operand:MODEF 0 "register_operand" ""))
17590    (use (match_operand:MODEF 1 "general_operand" ""))]
17591  "TARGET_USE_FANCY_MATH_387
17592    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17593        || TARGET_MIX_SSE_I387)
17594    && flag_unsafe_math_optimizations"
17595 {
17596   rtx op0, op1;
17597
17598   if (optimize_insn_for_size_p ())
17599     FAIL;
17600
17601   op0 = gen_reg_rtx (XFmode);
17602   op1 = gen_reg_rtx (XFmode);
17603
17604   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17605   emit_insn (gen_exp2xf2 (op0, op1));
17606   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17607   DONE;
17608 })
17609
17610 (define_expand "expm1xf2"
17611   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17612                                (match_dup 2)))
17613    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17614    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17615    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17616    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17617    (parallel [(set (match_dup 7)
17618                    (unspec:XF [(match_dup 6) (match_dup 4)]
17619                               UNSPEC_FSCALE_FRACT))
17620               (set (match_dup 8)
17621                    (unspec:XF [(match_dup 6) (match_dup 4)]
17622                               UNSPEC_FSCALE_EXP))])
17623    (parallel [(set (match_dup 10)
17624                    (unspec:XF [(match_dup 9) (match_dup 8)]
17625                               UNSPEC_FSCALE_FRACT))
17626               (set (match_dup 11)
17627                    (unspec:XF [(match_dup 9) (match_dup 8)]
17628                               UNSPEC_FSCALE_EXP))])
17629    (set (match_dup 12) (minus:XF (match_dup 10)
17630                                  (float_extend:XF (match_dup 13))))
17631    (set (match_operand:XF 0 "register_operand" "")
17632         (plus:XF (match_dup 12) (match_dup 7)))]
17633   "TARGET_USE_FANCY_MATH_387
17634    && flag_unsafe_math_optimizations"
17635 {
17636   int i;
17637
17638   if (optimize_insn_for_size_p ())
17639     FAIL;
17640
17641   for (i = 2; i < 13; i++)
17642     operands[i] = gen_reg_rtx (XFmode);
17643
17644   operands[13]
17645     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17646
17647   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17648 })
17649
17650 (define_expand "expm1<mode>2"
17651   [(use (match_operand:MODEF 0 "register_operand" ""))
17652    (use (match_operand:MODEF 1 "general_operand" ""))]
17653  "TARGET_USE_FANCY_MATH_387
17654    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17655        || TARGET_MIX_SSE_I387)
17656    && flag_unsafe_math_optimizations"
17657 {
17658   rtx op0, op1;
17659
17660   if (optimize_insn_for_size_p ())
17661     FAIL;
17662
17663   op0 = gen_reg_rtx (XFmode);
17664   op1 = gen_reg_rtx (XFmode);
17665
17666   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17667   emit_insn (gen_expm1xf2 (op0, op1));
17668   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17669   DONE;
17670 })
17671
17672 (define_expand "ldexpxf3"
17673   [(set (match_dup 3)
17674         (float:XF (match_operand:SI 2 "register_operand" "")))
17675    (parallel [(set (match_operand:XF 0 " register_operand" "")
17676                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17677                                (match_dup 3)]
17678                               UNSPEC_FSCALE_FRACT))
17679               (set (match_dup 4)
17680                    (unspec:XF [(match_dup 1) (match_dup 3)]
17681                               UNSPEC_FSCALE_EXP))])]
17682   "TARGET_USE_FANCY_MATH_387
17683    && flag_unsafe_math_optimizations"
17684 {
17685   if (optimize_insn_for_size_p ())
17686     FAIL;
17687
17688   operands[3] = gen_reg_rtx (XFmode);
17689   operands[4] = gen_reg_rtx (XFmode);
17690 })
17691
17692 (define_expand "ldexp<mode>3"
17693   [(use (match_operand:MODEF 0 "register_operand" ""))
17694    (use (match_operand:MODEF 1 "general_operand" ""))
17695    (use (match_operand:SI 2 "register_operand" ""))]
17696  "TARGET_USE_FANCY_MATH_387
17697    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17698        || TARGET_MIX_SSE_I387)
17699    && flag_unsafe_math_optimizations"
17700 {
17701   rtx op0, op1;
17702
17703   if (optimize_insn_for_size_p ())
17704     FAIL;
17705
17706   op0 = gen_reg_rtx (XFmode);
17707   op1 = gen_reg_rtx (XFmode);
17708
17709   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17710   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17711   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17712   DONE;
17713 })
17714
17715 (define_expand "scalbxf3"
17716   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17717                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17718                                (match_operand:XF 2 "register_operand" "")]
17719                               UNSPEC_FSCALE_FRACT))
17720               (set (match_dup 3)
17721                    (unspec:XF [(match_dup 1) (match_dup 2)]
17722                               UNSPEC_FSCALE_EXP))])]
17723   "TARGET_USE_FANCY_MATH_387
17724    && flag_unsafe_math_optimizations"
17725 {
17726   if (optimize_insn_for_size_p ())
17727     FAIL;
17728
17729   operands[3] = gen_reg_rtx (XFmode);
17730 })
17731
17732 (define_expand "scalb<mode>3"
17733   [(use (match_operand:MODEF 0 "register_operand" ""))
17734    (use (match_operand:MODEF 1 "general_operand" ""))
17735    (use (match_operand:MODEF 2 "general_operand" ""))]
17736  "TARGET_USE_FANCY_MATH_387
17737    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17738        || TARGET_MIX_SSE_I387)
17739    && flag_unsafe_math_optimizations"
17740 {
17741   rtx op0, op1, op2;
17742
17743   if (optimize_insn_for_size_p ())
17744     FAIL;
17745
17746   op0 = gen_reg_rtx (XFmode);
17747   op1 = gen_reg_rtx (XFmode);
17748   op2 = gen_reg_rtx (XFmode);
17749
17750   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17751   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17752   emit_insn (gen_scalbxf3 (op0, op1, op2));
17753   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17754   DONE;
17755 })
17756
17757 (define_expand "significandxf2"
17758   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17759                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17760                               UNSPEC_XTRACT_FRACT))
17761               (set (match_dup 2)
17762                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17763   "TARGET_USE_FANCY_MATH_387
17764    && flag_unsafe_math_optimizations"
17765 {
17766   operands[2] = gen_reg_rtx (XFmode);
17767 })
17768
17769 (define_expand "significand<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   rtx op1 = gen_reg_rtx (XFmode);
17779
17780   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17781   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17782   DONE;
17783 })
17784 \f
17785
17786 (define_insn "sse4_1_round<mode>2"
17787   [(set (match_operand:MODEF 0 "register_operand" "=x")
17788         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17789                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17790                       UNSPEC_ROUND))]
17791   "TARGET_ROUND"
17792   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17793   [(set_attr "type" "ssecvt")
17794    (set_attr "prefix_extra" "1")
17795    (set_attr "prefix" "maybe_vex")
17796    (set_attr "mode" "<MODE>")])
17797
17798 (define_insn "rintxf2"
17799   [(set (match_operand:XF 0 "register_operand" "=f")
17800         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17801                    UNSPEC_FRNDINT))]
17802   "TARGET_USE_FANCY_MATH_387
17803    && flag_unsafe_math_optimizations"
17804   "frndint"
17805   [(set_attr "type" "fpspc")
17806    (set_attr "mode" "XF")])
17807
17808 (define_expand "rint<mode>2"
17809   [(use (match_operand:MODEF 0 "register_operand" ""))
17810    (use (match_operand:MODEF 1 "register_operand" ""))]
17811   "(TARGET_USE_FANCY_MATH_387
17812     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17813         || TARGET_MIX_SSE_I387)
17814     && flag_unsafe_math_optimizations)
17815    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17816        && !flag_trapping_math)"
17817 {
17818   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17819       && !flag_trapping_math)
17820     {
17821       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17822         FAIL;
17823       if (TARGET_ROUND)
17824         emit_insn (gen_sse4_1_round<mode>2
17825                    (operands[0], operands[1], GEN_INT (0x04)));
17826       else
17827         ix86_expand_rint (operand0, operand1);
17828     }
17829   else
17830     {
17831       rtx op0 = gen_reg_rtx (XFmode);
17832       rtx op1 = gen_reg_rtx (XFmode);
17833
17834       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17835       emit_insn (gen_rintxf2 (op0, op1));
17836
17837       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17838     }
17839   DONE;
17840 })
17841
17842 (define_expand "round<mode>2"
17843   [(match_operand:MODEF 0 "register_operand" "")
17844    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17845   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17846    && !flag_trapping_math && !flag_rounding_math"
17847 {
17848   if (optimize_insn_for_size_p ())
17849     FAIL;
17850   if (TARGET_64BIT || (<MODE>mode != DFmode))
17851     ix86_expand_round (operand0, operand1);
17852   else
17853     ix86_expand_rounddf_32 (operand0, operand1);
17854   DONE;
17855 })
17856
17857 (define_insn_and_split "*fistdi2_1"
17858   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17859         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17860                    UNSPEC_FIST))]
17861   "TARGET_USE_FANCY_MATH_387
17862    && can_create_pseudo_p ()"
17863   "#"
17864   "&& 1"
17865   [(const_int 0)]
17866 {
17867   if (memory_operand (operands[0], VOIDmode))
17868     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17869   else
17870     {
17871       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17872       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17873                                          operands[2]));
17874     }
17875   DONE;
17876 }
17877   [(set_attr "type" "fpspc")
17878    (set_attr "mode" "DI")])
17879
17880 (define_insn "fistdi2"
17881   [(set (match_operand:DI 0 "memory_operand" "=m")
17882         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17883                    UNSPEC_FIST))
17884    (clobber (match_scratch:XF 2 "=&1f"))]
17885   "TARGET_USE_FANCY_MATH_387"
17886   "* return output_fix_trunc (insn, operands, 0);"
17887   [(set_attr "type" "fpspc")
17888    (set_attr "mode" "DI")])
17889
17890 (define_insn "fistdi2_with_temp"
17891   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17892         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17893                    UNSPEC_FIST))
17894    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17895    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17896   "TARGET_USE_FANCY_MATH_387"
17897   "#"
17898   [(set_attr "type" "fpspc")
17899    (set_attr "mode" "DI")])
17900
17901 (define_split
17902   [(set (match_operand:DI 0 "register_operand" "")
17903         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17904                    UNSPEC_FIST))
17905    (clobber (match_operand:DI 2 "memory_operand" ""))
17906    (clobber (match_scratch 3 ""))]
17907   "reload_completed"
17908   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17909               (clobber (match_dup 3))])
17910    (set (match_dup 0) (match_dup 2))]
17911   "")
17912
17913 (define_split
17914   [(set (match_operand:DI 0 "memory_operand" "")
17915         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17916                    UNSPEC_FIST))
17917    (clobber (match_operand:DI 2 "memory_operand" ""))
17918    (clobber (match_scratch 3 ""))]
17919   "reload_completed"
17920   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17921               (clobber (match_dup 3))])]
17922   "")
17923
17924 (define_insn_and_split "*fist<mode>2_1"
17925   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17926         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17927                            UNSPEC_FIST))]
17928   "TARGET_USE_FANCY_MATH_387
17929    && can_create_pseudo_p ()"
17930   "#"
17931   "&& 1"
17932   [(const_int 0)]
17933 {
17934   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17935   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17936                                         operands[2]));
17937   DONE;
17938 }
17939   [(set_attr "type" "fpspc")
17940    (set_attr "mode" "<MODE>")])
17941
17942 (define_insn "fist<mode>2"
17943   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17944         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17945                            UNSPEC_FIST))]
17946   "TARGET_USE_FANCY_MATH_387"
17947   "* return output_fix_trunc (insn, operands, 0);"
17948   [(set_attr "type" "fpspc")
17949    (set_attr "mode" "<MODE>")])
17950
17951 (define_insn "fist<mode>2_with_temp"
17952   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17953         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17954                            UNSPEC_FIST))
17955    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17956   "TARGET_USE_FANCY_MATH_387"
17957   "#"
17958   [(set_attr "type" "fpspc")
17959    (set_attr "mode" "<MODE>")])
17960
17961 (define_split
17962   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17963         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17964                            UNSPEC_FIST))
17965    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17966   "reload_completed"
17967   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17968    (set (match_dup 0) (match_dup 2))]
17969   "")
17970
17971 (define_split
17972   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17973         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17974                            UNSPEC_FIST))
17975    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17976   "reload_completed"
17977   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17978   "")
17979
17980 (define_expand "lrintxf<mode>2"
17981   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17982      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17983                       UNSPEC_FIST))]
17984   "TARGET_USE_FANCY_MATH_387"
17985   "")
17986
17987 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17988   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17989      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17990                         UNSPEC_FIX_NOTRUNC))]
17991   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17992    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17993   "")
17994
17995 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17996   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17997    (match_operand:MODEF 1 "register_operand" "")]
17998   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17999    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18000    && !flag_trapping_math && !flag_rounding_math"
18001 {
18002   if (optimize_insn_for_size_p ())
18003     FAIL;
18004   ix86_expand_lround (operand0, operand1);
18005   DONE;
18006 })
18007
18008 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18009 (define_insn_and_split "frndintxf2_floor"
18010   [(set (match_operand:XF 0 "register_operand" "")
18011         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18012          UNSPEC_FRNDINT_FLOOR))
18013    (clobber (reg:CC FLAGS_REG))]
18014   "TARGET_USE_FANCY_MATH_387
18015    && flag_unsafe_math_optimizations
18016    && can_create_pseudo_p ()"
18017   "#"
18018   "&& 1"
18019   [(const_int 0)]
18020 {
18021   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18022
18023   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18024   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18025
18026   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18027                                         operands[2], operands[3]));
18028   DONE;
18029 }
18030   [(set_attr "type" "frndint")
18031    (set_attr "i387_cw" "floor")
18032    (set_attr "mode" "XF")])
18033
18034 (define_insn "frndintxf2_floor_i387"
18035   [(set (match_operand:XF 0 "register_operand" "=f")
18036         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18037          UNSPEC_FRNDINT_FLOOR))
18038    (use (match_operand:HI 2 "memory_operand" "m"))
18039    (use (match_operand:HI 3 "memory_operand" "m"))]
18040   "TARGET_USE_FANCY_MATH_387
18041    && flag_unsafe_math_optimizations"
18042   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18043   [(set_attr "type" "frndint")
18044    (set_attr "i387_cw" "floor")
18045    (set_attr "mode" "XF")])
18046
18047 (define_expand "floorxf2"
18048   [(use (match_operand:XF 0 "register_operand" ""))
18049    (use (match_operand:XF 1 "register_operand" ""))]
18050   "TARGET_USE_FANCY_MATH_387
18051    && flag_unsafe_math_optimizations"
18052 {
18053   if (optimize_insn_for_size_p ())
18054     FAIL;
18055   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18056   DONE;
18057 })
18058
18059 (define_expand "floor<mode>2"
18060   [(use (match_operand:MODEF 0 "register_operand" ""))
18061    (use (match_operand:MODEF 1 "register_operand" ""))]
18062   "(TARGET_USE_FANCY_MATH_387
18063     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18064         || TARGET_MIX_SSE_I387)
18065     && flag_unsafe_math_optimizations)
18066    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18067        && !flag_trapping_math)"
18068 {
18069   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18070       && !flag_trapping_math
18071       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18072     {
18073       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18074         FAIL;
18075       if (TARGET_ROUND)
18076         emit_insn (gen_sse4_1_round<mode>2
18077                    (operands[0], operands[1], GEN_INT (0x01)));
18078       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18079         ix86_expand_floorceil (operand0, operand1, true);
18080       else
18081         ix86_expand_floorceildf_32 (operand0, operand1, true);
18082     }
18083   else
18084     {
18085       rtx op0, op1;
18086
18087       if (optimize_insn_for_size_p ())
18088         FAIL;
18089
18090       op0 = gen_reg_rtx (XFmode);
18091       op1 = gen_reg_rtx (XFmode);
18092       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18093       emit_insn (gen_frndintxf2_floor (op0, op1));
18094
18095       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18096     }
18097   DONE;
18098 })
18099
18100 (define_insn_and_split "*fist<mode>2_floor_1"
18101   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18102         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18103          UNSPEC_FIST_FLOOR))
18104    (clobber (reg:CC FLAGS_REG))]
18105   "TARGET_USE_FANCY_MATH_387
18106    && flag_unsafe_math_optimizations
18107    && can_create_pseudo_p ()"
18108   "#"
18109   "&& 1"
18110   [(const_int 0)]
18111 {
18112   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18113
18114   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18115   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18116   if (memory_operand (operands[0], VOIDmode))
18117     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18118                                       operands[2], operands[3]));
18119   else
18120     {
18121       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18122       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18123                                                   operands[2], operands[3],
18124                                                   operands[4]));
18125     }
18126   DONE;
18127 }
18128   [(set_attr "type" "fistp")
18129    (set_attr "i387_cw" "floor")
18130    (set_attr "mode" "<MODE>")])
18131
18132 (define_insn "fistdi2_floor"
18133   [(set (match_operand:DI 0 "memory_operand" "=m")
18134         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18135          UNSPEC_FIST_FLOOR))
18136    (use (match_operand:HI 2 "memory_operand" "m"))
18137    (use (match_operand:HI 3 "memory_operand" "m"))
18138    (clobber (match_scratch:XF 4 "=&1f"))]
18139   "TARGET_USE_FANCY_MATH_387
18140    && flag_unsafe_math_optimizations"
18141   "* return output_fix_trunc (insn, operands, 0);"
18142   [(set_attr "type" "fistp")
18143    (set_attr "i387_cw" "floor")
18144    (set_attr "mode" "DI")])
18145
18146 (define_insn "fistdi2_floor_with_temp"
18147   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18148         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18149          UNSPEC_FIST_FLOOR))
18150    (use (match_operand:HI 2 "memory_operand" "m,m"))
18151    (use (match_operand:HI 3 "memory_operand" "m,m"))
18152    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18153    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18154   "TARGET_USE_FANCY_MATH_387
18155    && flag_unsafe_math_optimizations"
18156   "#"
18157   [(set_attr "type" "fistp")
18158    (set_attr "i387_cw" "floor")
18159    (set_attr "mode" "DI")])
18160
18161 (define_split
18162   [(set (match_operand:DI 0 "register_operand" "")
18163         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18164          UNSPEC_FIST_FLOOR))
18165    (use (match_operand:HI 2 "memory_operand" ""))
18166    (use (match_operand:HI 3 "memory_operand" ""))
18167    (clobber (match_operand:DI 4 "memory_operand" ""))
18168    (clobber (match_scratch 5 ""))]
18169   "reload_completed"
18170   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18171               (use (match_dup 2))
18172               (use (match_dup 3))
18173               (clobber (match_dup 5))])
18174    (set (match_dup 0) (match_dup 4))]
18175   "")
18176
18177 (define_split
18178   [(set (match_operand:DI 0 "memory_operand" "")
18179         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18180          UNSPEC_FIST_FLOOR))
18181    (use (match_operand:HI 2 "memory_operand" ""))
18182    (use (match_operand:HI 3 "memory_operand" ""))
18183    (clobber (match_operand:DI 4 "memory_operand" ""))
18184    (clobber (match_scratch 5 ""))]
18185   "reload_completed"
18186   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18187               (use (match_dup 2))
18188               (use (match_dup 3))
18189               (clobber (match_dup 5))])]
18190   "")
18191
18192 (define_insn "fist<mode>2_floor"
18193   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18194         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18195          UNSPEC_FIST_FLOOR))
18196    (use (match_operand:HI 2 "memory_operand" "m"))
18197    (use (match_operand:HI 3 "memory_operand" "m"))]
18198   "TARGET_USE_FANCY_MATH_387
18199    && flag_unsafe_math_optimizations"
18200   "* return output_fix_trunc (insn, operands, 0);"
18201   [(set_attr "type" "fistp")
18202    (set_attr "i387_cw" "floor")
18203    (set_attr "mode" "<MODE>")])
18204
18205 (define_insn "fist<mode>2_floor_with_temp"
18206   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18207         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18208          UNSPEC_FIST_FLOOR))
18209    (use (match_operand:HI 2 "memory_operand" "m,m"))
18210    (use (match_operand:HI 3 "memory_operand" "m,m"))
18211    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18212   "TARGET_USE_FANCY_MATH_387
18213    && flag_unsafe_math_optimizations"
18214   "#"
18215   [(set_attr "type" "fistp")
18216    (set_attr "i387_cw" "floor")
18217    (set_attr "mode" "<MODE>")])
18218
18219 (define_split
18220   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18221         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18222          UNSPEC_FIST_FLOOR))
18223    (use (match_operand:HI 2 "memory_operand" ""))
18224    (use (match_operand:HI 3 "memory_operand" ""))
18225    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18226   "reload_completed"
18227   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18228                                   UNSPEC_FIST_FLOOR))
18229               (use (match_dup 2))
18230               (use (match_dup 3))])
18231    (set (match_dup 0) (match_dup 4))]
18232   "")
18233
18234 (define_split
18235   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18236         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18237          UNSPEC_FIST_FLOOR))
18238    (use (match_operand:HI 2 "memory_operand" ""))
18239    (use (match_operand:HI 3 "memory_operand" ""))
18240    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18241   "reload_completed"
18242   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18243                                   UNSPEC_FIST_FLOOR))
18244               (use (match_dup 2))
18245               (use (match_dup 3))])]
18246   "")
18247
18248 (define_expand "lfloorxf<mode>2"
18249   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18250                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18251                     UNSPEC_FIST_FLOOR))
18252               (clobber (reg:CC FLAGS_REG))])]
18253   "TARGET_USE_FANCY_MATH_387
18254    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18255    && flag_unsafe_math_optimizations"
18256   "")
18257
18258 (define_expand "lfloor<mode>di2"
18259   [(match_operand:DI 0 "nonimmediate_operand" "")
18260    (match_operand:MODEF 1 "register_operand" "")]
18261   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18262    && !flag_trapping_math"
18263 {
18264   if (optimize_insn_for_size_p ())
18265     FAIL;
18266   ix86_expand_lfloorceil (operand0, operand1, true);
18267   DONE;
18268 })
18269
18270 (define_expand "lfloor<mode>si2"
18271   [(match_operand:SI 0 "nonimmediate_operand" "")
18272    (match_operand:MODEF 1 "register_operand" "")]
18273   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18274    && !flag_trapping_math"
18275 {
18276   if (optimize_insn_for_size_p () && TARGET_64BIT)
18277     FAIL;
18278   ix86_expand_lfloorceil (operand0, operand1, true);
18279   DONE;
18280 })
18281
18282 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18283 (define_insn_and_split "frndintxf2_ceil"
18284   [(set (match_operand:XF 0 "register_operand" "")
18285         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18286          UNSPEC_FRNDINT_CEIL))
18287    (clobber (reg:CC FLAGS_REG))]
18288   "TARGET_USE_FANCY_MATH_387
18289    && flag_unsafe_math_optimizations
18290    && can_create_pseudo_p ()"
18291   "#"
18292   "&& 1"
18293   [(const_int 0)]
18294 {
18295   ix86_optimize_mode_switching[I387_CEIL] = 1;
18296
18297   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18298   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18299
18300   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18301                                        operands[2], operands[3]));
18302   DONE;
18303 }
18304   [(set_attr "type" "frndint")
18305    (set_attr "i387_cw" "ceil")
18306    (set_attr "mode" "XF")])
18307
18308 (define_insn "frndintxf2_ceil_i387"
18309   [(set (match_operand:XF 0 "register_operand" "=f")
18310         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18311          UNSPEC_FRNDINT_CEIL))
18312    (use (match_operand:HI 2 "memory_operand" "m"))
18313    (use (match_operand:HI 3 "memory_operand" "m"))]
18314   "TARGET_USE_FANCY_MATH_387
18315    && flag_unsafe_math_optimizations"
18316   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18317   [(set_attr "type" "frndint")
18318    (set_attr "i387_cw" "ceil")
18319    (set_attr "mode" "XF")])
18320
18321 (define_expand "ceilxf2"
18322   [(use (match_operand:XF 0 "register_operand" ""))
18323    (use (match_operand:XF 1 "register_operand" ""))]
18324   "TARGET_USE_FANCY_MATH_387
18325    && flag_unsafe_math_optimizations"
18326 {
18327   if (optimize_insn_for_size_p ())
18328     FAIL;
18329   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18330   DONE;
18331 })
18332
18333 (define_expand "ceil<mode>2"
18334   [(use (match_operand:MODEF 0 "register_operand" ""))
18335    (use (match_operand:MODEF 1 "register_operand" ""))]
18336   "(TARGET_USE_FANCY_MATH_387
18337     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18338         || TARGET_MIX_SSE_I387)
18339     && flag_unsafe_math_optimizations)
18340    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18341        && !flag_trapping_math)"
18342 {
18343   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18344       && !flag_trapping_math
18345       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18346     {
18347       if (TARGET_ROUND)
18348         emit_insn (gen_sse4_1_round<mode>2
18349                    (operands[0], operands[1], GEN_INT (0x02)));
18350       else if (optimize_insn_for_size_p ())
18351         FAIL;
18352       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18353         ix86_expand_floorceil (operand0, operand1, false);
18354       else
18355         ix86_expand_floorceildf_32 (operand0, operand1, false);
18356     }
18357   else
18358     {
18359       rtx op0, op1;
18360
18361       if (optimize_insn_for_size_p ())
18362         FAIL;
18363
18364       op0 = gen_reg_rtx (XFmode);
18365       op1 = gen_reg_rtx (XFmode);
18366       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18367       emit_insn (gen_frndintxf2_ceil (op0, op1));
18368
18369       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18370     }
18371   DONE;
18372 })
18373
18374 (define_insn_and_split "*fist<mode>2_ceil_1"
18375   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18376         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18377          UNSPEC_FIST_CEIL))
18378    (clobber (reg:CC FLAGS_REG))]
18379   "TARGET_USE_FANCY_MATH_387
18380    && flag_unsafe_math_optimizations
18381    && can_create_pseudo_p ()"
18382   "#"
18383   "&& 1"
18384   [(const_int 0)]
18385 {
18386   ix86_optimize_mode_switching[I387_CEIL] = 1;
18387
18388   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18389   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18390   if (memory_operand (operands[0], VOIDmode))
18391     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18392                                      operands[2], operands[3]));
18393   else
18394     {
18395       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18396       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18397                                                  operands[2], operands[3],
18398                                                  operands[4]));
18399     }
18400   DONE;
18401 }
18402   [(set_attr "type" "fistp")
18403    (set_attr "i387_cw" "ceil")
18404    (set_attr "mode" "<MODE>")])
18405
18406 (define_insn "fistdi2_ceil"
18407   [(set (match_operand:DI 0 "memory_operand" "=m")
18408         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18409          UNSPEC_FIST_CEIL))
18410    (use (match_operand:HI 2 "memory_operand" "m"))
18411    (use (match_operand:HI 3 "memory_operand" "m"))
18412    (clobber (match_scratch:XF 4 "=&1f"))]
18413   "TARGET_USE_FANCY_MATH_387
18414    && flag_unsafe_math_optimizations"
18415   "* return output_fix_trunc (insn, operands, 0);"
18416   [(set_attr "type" "fistp")
18417    (set_attr "i387_cw" "ceil")
18418    (set_attr "mode" "DI")])
18419
18420 (define_insn "fistdi2_ceil_with_temp"
18421   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18422         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18423          UNSPEC_FIST_CEIL))
18424    (use (match_operand:HI 2 "memory_operand" "m,m"))
18425    (use (match_operand:HI 3 "memory_operand" "m,m"))
18426    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18427    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18428   "TARGET_USE_FANCY_MATH_387
18429    && flag_unsafe_math_optimizations"
18430   "#"
18431   [(set_attr "type" "fistp")
18432    (set_attr "i387_cw" "ceil")
18433    (set_attr "mode" "DI")])
18434
18435 (define_split
18436   [(set (match_operand:DI 0 "register_operand" "")
18437         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18438          UNSPEC_FIST_CEIL))
18439    (use (match_operand:HI 2 "memory_operand" ""))
18440    (use (match_operand:HI 3 "memory_operand" ""))
18441    (clobber (match_operand:DI 4 "memory_operand" ""))
18442    (clobber (match_scratch 5 ""))]
18443   "reload_completed"
18444   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18445               (use (match_dup 2))
18446               (use (match_dup 3))
18447               (clobber (match_dup 5))])
18448    (set (match_dup 0) (match_dup 4))]
18449   "")
18450
18451 (define_split
18452   [(set (match_operand:DI 0 "memory_operand" "")
18453         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18454          UNSPEC_FIST_CEIL))
18455    (use (match_operand:HI 2 "memory_operand" ""))
18456    (use (match_operand:HI 3 "memory_operand" ""))
18457    (clobber (match_operand:DI 4 "memory_operand" ""))
18458    (clobber (match_scratch 5 ""))]
18459   "reload_completed"
18460   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18461               (use (match_dup 2))
18462               (use (match_dup 3))
18463               (clobber (match_dup 5))])]
18464   "")
18465
18466 (define_insn "fist<mode>2_ceil"
18467   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18468         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18469          UNSPEC_FIST_CEIL))
18470    (use (match_operand:HI 2 "memory_operand" "m"))
18471    (use (match_operand:HI 3 "memory_operand" "m"))]
18472   "TARGET_USE_FANCY_MATH_387
18473    && flag_unsafe_math_optimizations"
18474   "* return output_fix_trunc (insn, operands, 0);"
18475   [(set_attr "type" "fistp")
18476    (set_attr "i387_cw" "ceil")
18477    (set_attr "mode" "<MODE>")])
18478
18479 (define_insn "fist<mode>2_ceil_with_temp"
18480   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18481         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18482          UNSPEC_FIST_CEIL))
18483    (use (match_operand:HI 2 "memory_operand" "m,m"))
18484    (use (match_operand:HI 3 "memory_operand" "m,m"))
18485    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18486   "TARGET_USE_FANCY_MATH_387
18487    && flag_unsafe_math_optimizations"
18488   "#"
18489   [(set_attr "type" "fistp")
18490    (set_attr "i387_cw" "ceil")
18491    (set_attr "mode" "<MODE>")])
18492
18493 (define_split
18494   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18495         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18496          UNSPEC_FIST_CEIL))
18497    (use (match_operand:HI 2 "memory_operand" ""))
18498    (use (match_operand:HI 3 "memory_operand" ""))
18499    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18500   "reload_completed"
18501   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18502                                   UNSPEC_FIST_CEIL))
18503               (use (match_dup 2))
18504               (use (match_dup 3))])
18505    (set (match_dup 0) (match_dup 4))]
18506   "")
18507
18508 (define_split
18509   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18510         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18511          UNSPEC_FIST_CEIL))
18512    (use (match_operand:HI 2 "memory_operand" ""))
18513    (use (match_operand:HI 3 "memory_operand" ""))
18514    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18515   "reload_completed"
18516   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18517                                   UNSPEC_FIST_CEIL))
18518               (use (match_dup 2))
18519               (use (match_dup 3))])]
18520   "")
18521
18522 (define_expand "lceilxf<mode>2"
18523   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18524                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18525                     UNSPEC_FIST_CEIL))
18526               (clobber (reg:CC FLAGS_REG))])]
18527   "TARGET_USE_FANCY_MATH_387
18528    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18529    && flag_unsafe_math_optimizations"
18530   "")
18531
18532 (define_expand "lceil<mode>di2"
18533   [(match_operand:DI 0 "nonimmediate_operand" "")
18534    (match_operand:MODEF 1 "register_operand" "")]
18535   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18536    && !flag_trapping_math"
18537 {
18538   ix86_expand_lfloorceil (operand0, operand1, false);
18539   DONE;
18540 })
18541
18542 (define_expand "lceil<mode>si2"
18543   [(match_operand:SI 0 "nonimmediate_operand" "")
18544    (match_operand:MODEF 1 "register_operand" "")]
18545   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18546    && !flag_trapping_math"
18547 {
18548   ix86_expand_lfloorceil (operand0, operand1, false);
18549   DONE;
18550 })
18551
18552 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18553 (define_insn_and_split "frndintxf2_trunc"
18554   [(set (match_operand:XF 0 "register_operand" "")
18555         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18556          UNSPEC_FRNDINT_TRUNC))
18557    (clobber (reg:CC FLAGS_REG))]
18558   "TARGET_USE_FANCY_MATH_387
18559    && flag_unsafe_math_optimizations
18560    && can_create_pseudo_p ()"
18561   "#"
18562   "&& 1"
18563   [(const_int 0)]
18564 {
18565   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18566
18567   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18568   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18569
18570   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18571                                         operands[2], operands[3]));
18572   DONE;
18573 }
18574   [(set_attr "type" "frndint")
18575    (set_attr "i387_cw" "trunc")
18576    (set_attr "mode" "XF")])
18577
18578 (define_insn "frndintxf2_trunc_i387"
18579   [(set (match_operand:XF 0 "register_operand" "=f")
18580         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18581          UNSPEC_FRNDINT_TRUNC))
18582    (use (match_operand:HI 2 "memory_operand" "m"))
18583    (use (match_operand:HI 3 "memory_operand" "m"))]
18584   "TARGET_USE_FANCY_MATH_387
18585    && flag_unsafe_math_optimizations"
18586   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18587   [(set_attr "type" "frndint")
18588    (set_attr "i387_cw" "trunc")
18589    (set_attr "mode" "XF")])
18590
18591 (define_expand "btruncxf2"
18592   [(use (match_operand:XF 0 "register_operand" ""))
18593    (use (match_operand:XF 1 "register_operand" ""))]
18594   "TARGET_USE_FANCY_MATH_387
18595    && flag_unsafe_math_optimizations"
18596 {
18597   if (optimize_insn_for_size_p ())
18598     FAIL;
18599   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18600   DONE;
18601 })
18602
18603 (define_expand "btrunc<mode>2"
18604   [(use (match_operand:MODEF 0 "register_operand" ""))
18605    (use (match_operand:MODEF 1 "register_operand" ""))]
18606   "(TARGET_USE_FANCY_MATH_387
18607     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18608         || TARGET_MIX_SSE_I387)
18609     && flag_unsafe_math_optimizations)
18610    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18611        && !flag_trapping_math)"
18612 {
18613   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18614       && !flag_trapping_math
18615       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18616     {
18617       if (TARGET_ROUND)
18618         emit_insn (gen_sse4_1_round<mode>2
18619                    (operands[0], operands[1], GEN_INT (0x03)));
18620       else if (optimize_insn_for_size_p ())
18621         FAIL;
18622       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18623         ix86_expand_trunc (operand0, operand1);
18624       else
18625         ix86_expand_truncdf_32 (operand0, operand1);
18626     }
18627   else
18628     {
18629       rtx op0, op1;
18630
18631       if (optimize_insn_for_size_p ())
18632         FAIL;
18633
18634       op0 = gen_reg_rtx (XFmode);
18635       op1 = gen_reg_rtx (XFmode);
18636       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18637       emit_insn (gen_frndintxf2_trunc (op0, op1));
18638
18639       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18640     }
18641   DONE;
18642 })
18643
18644 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18645 (define_insn_and_split "frndintxf2_mask_pm"
18646   [(set (match_operand:XF 0 "register_operand" "")
18647         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18648          UNSPEC_FRNDINT_MASK_PM))
18649    (clobber (reg:CC FLAGS_REG))]
18650   "TARGET_USE_FANCY_MATH_387
18651    && flag_unsafe_math_optimizations
18652    && can_create_pseudo_p ()"
18653   "#"
18654   "&& 1"
18655   [(const_int 0)]
18656 {
18657   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18658
18659   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18660   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18661
18662   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18663                                           operands[2], operands[3]));
18664   DONE;
18665 }
18666   [(set_attr "type" "frndint")
18667    (set_attr "i387_cw" "mask_pm")
18668    (set_attr "mode" "XF")])
18669
18670 (define_insn "frndintxf2_mask_pm_i387"
18671   [(set (match_operand:XF 0 "register_operand" "=f")
18672         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18673          UNSPEC_FRNDINT_MASK_PM))
18674    (use (match_operand:HI 2 "memory_operand" "m"))
18675    (use (match_operand:HI 3 "memory_operand" "m"))]
18676   "TARGET_USE_FANCY_MATH_387
18677    && flag_unsafe_math_optimizations"
18678   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18679   [(set_attr "type" "frndint")
18680    (set_attr "i387_cw" "mask_pm")
18681    (set_attr "mode" "XF")])
18682
18683 (define_expand "nearbyintxf2"
18684   [(use (match_operand:XF 0 "register_operand" ""))
18685    (use (match_operand:XF 1 "register_operand" ""))]
18686   "TARGET_USE_FANCY_MATH_387
18687    && flag_unsafe_math_optimizations"
18688 {
18689   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18690
18691   DONE;
18692 })
18693
18694 (define_expand "nearbyint<mode>2"
18695   [(use (match_operand:MODEF 0 "register_operand" ""))
18696    (use (match_operand:MODEF 1 "register_operand" ""))]
18697   "TARGET_USE_FANCY_MATH_387
18698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18699        || TARGET_MIX_SSE_I387)
18700    && flag_unsafe_math_optimizations"
18701 {
18702   rtx op0 = gen_reg_rtx (XFmode);
18703   rtx op1 = gen_reg_rtx (XFmode);
18704
18705   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18706   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18707
18708   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18709   DONE;
18710 })
18711
18712 (define_insn "fxam<mode>2_i387"
18713   [(set (match_operand:HI 0 "register_operand" "=a")
18714         (unspec:HI
18715           [(match_operand:X87MODEF 1 "register_operand" "f")]
18716           UNSPEC_FXAM))]
18717   "TARGET_USE_FANCY_MATH_387"
18718   "fxam\n\tfnstsw\t%0"
18719   [(set_attr "type" "multi")
18720    (set_attr "length" "4")
18721    (set_attr "unit" "i387")
18722    (set_attr "mode" "<MODE>")])
18723
18724 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18725   [(set (match_operand:HI 0 "register_operand" "")
18726         (unspec:HI
18727           [(match_operand:MODEF 1 "memory_operand" "")]
18728           UNSPEC_FXAM_MEM))]
18729   "TARGET_USE_FANCY_MATH_387
18730    && can_create_pseudo_p ()"
18731   "#"
18732   "&& 1"
18733   [(set (match_dup 2)(match_dup 1))
18734    (set (match_dup 0)
18735         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18736 {
18737   operands[2] = gen_reg_rtx (<MODE>mode);
18738
18739   MEM_VOLATILE_P (operands[1]) = 1;
18740 }
18741   [(set_attr "type" "multi")
18742    (set_attr "unit" "i387")
18743    (set_attr "mode" "<MODE>")])
18744
18745 (define_expand "isinfxf2"
18746   [(use (match_operand:SI 0 "register_operand" ""))
18747    (use (match_operand:XF 1 "register_operand" ""))]
18748   "TARGET_USE_FANCY_MATH_387
18749    && TARGET_C99_FUNCTIONS"
18750 {
18751   rtx mask = GEN_INT (0x45);
18752   rtx val = GEN_INT (0x05);
18753
18754   rtx cond;
18755
18756   rtx scratch = gen_reg_rtx (HImode);
18757   rtx res = gen_reg_rtx (QImode);
18758
18759   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18760
18761   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18762   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18763   cond = gen_rtx_fmt_ee (EQ, QImode,
18764                          gen_rtx_REG (CCmode, FLAGS_REG),
18765                          const0_rtx);
18766   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18767   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18768   DONE;
18769 })
18770
18771 (define_expand "isinf<mode>2"
18772   [(use (match_operand:SI 0 "register_operand" ""))
18773    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18774   "TARGET_USE_FANCY_MATH_387
18775    && TARGET_C99_FUNCTIONS
18776    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18777 {
18778   rtx mask = GEN_INT (0x45);
18779   rtx val = GEN_INT (0x05);
18780
18781   rtx cond;
18782
18783   rtx scratch = gen_reg_rtx (HImode);
18784   rtx res = gen_reg_rtx (QImode);
18785
18786   /* Remove excess precision by forcing value through memory. */
18787   if (memory_operand (operands[1], VOIDmode))
18788     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18789   else
18790     {
18791       enum ix86_stack_slot slot = (virtuals_instantiated
18792                                    ? SLOT_TEMP
18793                                    : SLOT_VIRTUAL);
18794       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18795
18796       emit_move_insn (temp, operands[1]);
18797       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18798     }
18799
18800   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18801   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18802   cond = gen_rtx_fmt_ee (EQ, QImode,
18803                          gen_rtx_REG (CCmode, FLAGS_REG),
18804                          const0_rtx);
18805   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18806   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18807   DONE;
18808 })
18809
18810 (define_expand "signbit<mode>2"
18811   [(use (match_operand:SI 0 "register_operand" ""))
18812    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18813   "TARGET_USE_FANCY_MATH_387
18814    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18815 {
18816   rtx mask = GEN_INT (0x0200);
18817
18818   rtx scratch = gen_reg_rtx (HImode);
18819
18820   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18821   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18822   DONE;
18823 })
18824 \f
18825 ;; Block operation instructions
18826
18827 (define_insn "cld"
18828   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18829   ""
18830   "cld"
18831   [(set_attr "length" "1")
18832    (set_attr "length_immediate" "0")
18833    (set_attr "modrm" "0")])
18834
18835 (define_expand "movmemsi"
18836   [(use (match_operand:BLK 0 "memory_operand" ""))
18837    (use (match_operand:BLK 1 "memory_operand" ""))
18838    (use (match_operand:SI 2 "nonmemory_operand" ""))
18839    (use (match_operand:SI 3 "const_int_operand" ""))
18840    (use (match_operand:SI 4 "const_int_operand" ""))
18841    (use (match_operand:SI 5 "const_int_operand" ""))]
18842   ""
18843 {
18844  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18845                          operands[4], operands[5]))
18846    DONE;
18847  else
18848    FAIL;
18849 })
18850
18851 (define_expand "movmemdi"
18852   [(use (match_operand:BLK 0 "memory_operand" ""))
18853    (use (match_operand:BLK 1 "memory_operand" ""))
18854    (use (match_operand:DI 2 "nonmemory_operand" ""))
18855    (use (match_operand:DI 3 "const_int_operand" ""))
18856    (use (match_operand:SI 4 "const_int_operand" ""))
18857    (use (match_operand:SI 5 "const_int_operand" ""))]
18858   "TARGET_64BIT"
18859 {
18860  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18861                          operands[4], operands[5]))
18862    DONE;
18863  else
18864    FAIL;
18865 })
18866
18867 ;; Most CPUs don't like single string operations
18868 ;; Handle this case here to simplify previous expander.
18869
18870 (define_expand "strmov"
18871   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18872    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18873    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18874               (clobber (reg:CC FLAGS_REG))])
18875    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18876               (clobber (reg:CC FLAGS_REG))])]
18877   ""
18878 {
18879   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18880
18881   /* If .md ever supports :P for Pmode, these can be directly
18882      in the pattern above.  */
18883   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18884   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18885
18886   /* Can't use this if the user has appropriated esi or edi.  */
18887   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18888       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18889     {
18890       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18891                                       operands[2], operands[3],
18892                                       operands[5], operands[6]));
18893       DONE;
18894     }
18895
18896   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18897 })
18898
18899 (define_expand "strmov_singleop"
18900   [(parallel [(set (match_operand 1 "memory_operand" "")
18901                    (match_operand 3 "memory_operand" ""))
18902               (set (match_operand 0 "register_operand" "")
18903                    (match_operand 4 "" ""))
18904               (set (match_operand 2 "register_operand" "")
18905                    (match_operand 5 "" ""))])]
18906   ""
18907   "ix86_current_function_needs_cld = 1;")
18908
18909 (define_insn "*strmovdi_rex_1"
18910   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18911         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18912    (set (match_operand:DI 0 "register_operand" "=D")
18913         (plus:DI (match_dup 2)
18914                  (const_int 8)))
18915    (set (match_operand:DI 1 "register_operand" "=S")
18916         (plus:DI (match_dup 3)
18917                  (const_int 8)))]
18918   "TARGET_64BIT"
18919   "movsq"
18920   [(set_attr "type" "str")
18921    (set_attr "mode" "DI")
18922    (set_attr "memory" "both")])
18923
18924 (define_insn "*strmovsi_1"
18925   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18926         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18927    (set (match_operand:SI 0 "register_operand" "=D")
18928         (plus:SI (match_dup 2)
18929                  (const_int 4)))
18930    (set (match_operand:SI 1 "register_operand" "=S")
18931         (plus:SI (match_dup 3)
18932                  (const_int 4)))]
18933   "!TARGET_64BIT"
18934   "movs{l|d}"
18935   [(set_attr "type" "str")
18936    (set_attr "mode" "SI")
18937    (set_attr "memory" "both")])
18938
18939 (define_insn "*strmovsi_rex_1"
18940   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18941         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18942    (set (match_operand:DI 0 "register_operand" "=D")
18943         (plus:DI (match_dup 2)
18944                  (const_int 4)))
18945    (set (match_operand:DI 1 "register_operand" "=S")
18946         (plus:DI (match_dup 3)
18947                  (const_int 4)))]
18948   "TARGET_64BIT"
18949   "movs{l|d}"
18950   [(set_attr "type" "str")
18951    (set_attr "mode" "SI")
18952    (set_attr "memory" "both")])
18953
18954 (define_insn "*strmovhi_1"
18955   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18956         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18957    (set (match_operand:SI 0 "register_operand" "=D")
18958         (plus:SI (match_dup 2)
18959                  (const_int 2)))
18960    (set (match_operand:SI 1 "register_operand" "=S")
18961         (plus:SI (match_dup 3)
18962                  (const_int 2)))]
18963   "!TARGET_64BIT"
18964   "movsw"
18965   [(set_attr "type" "str")
18966    (set_attr "memory" "both")
18967    (set_attr "mode" "HI")])
18968
18969 (define_insn "*strmovhi_rex_1"
18970   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18971         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18972    (set (match_operand:DI 0 "register_operand" "=D")
18973         (plus:DI (match_dup 2)
18974                  (const_int 2)))
18975    (set (match_operand:DI 1 "register_operand" "=S")
18976         (plus:DI (match_dup 3)
18977                  (const_int 2)))]
18978   "TARGET_64BIT"
18979   "movsw"
18980   [(set_attr "type" "str")
18981    (set_attr "memory" "both")
18982    (set_attr "mode" "HI")])
18983
18984 (define_insn "*strmovqi_1"
18985   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18986         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18987    (set (match_operand:SI 0 "register_operand" "=D")
18988         (plus:SI (match_dup 2)
18989                  (const_int 1)))
18990    (set (match_operand:SI 1 "register_operand" "=S")
18991         (plus:SI (match_dup 3)
18992                  (const_int 1)))]
18993   "!TARGET_64BIT"
18994   "movsb"
18995   [(set_attr "type" "str")
18996    (set_attr "memory" "both")
18997    (set_attr "mode" "QI")])
18998
18999 (define_insn "*strmovqi_rex_1"
19000   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19001         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19002    (set (match_operand:DI 0 "register_operand" "=D")
19003         (plus:DI (match_dup 2)
19004                  (const_int 1)))
19005    (set (match_operand:DI 1 "register_operand" "=S")
19006         (plus:DI (match_dup 3)
19007                  (const_int 1)))]
19008   "TARGET_64BIT"
19009   "movsb"
19010   [(set_attr "type" "str")
19011    (set_attr "memory" "both")
19012    (set_attr "prefix_rex" "0")
19013    (set_attr "mode" "QI")])
19014
19015 (define_expand "rep_mov"
19016   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19017               (set (match_operand 0 "register_operand" "")
19018                    (match_operand 5 "" ""))
19019               (set (match_operand 2 "register_operand" "")
19020                    (match_operand 6 "" ""))
19021               (set (match_operand 1 "memory_operand" "")
19022                    (match_operand 3 "memory_operand" ""))
19023               (use (match_dup 4))])]
19024   ""
19025   "ix86_current_function_needs_cld = 1;")
19026
19027 (define_insn "*rep_movdi_rex64"
19028   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19029    (set (match_operand:DI 0 "register_operand" "=D")
19030         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19031                             (const_int 3))
19032                  (match_operand:DI 3 "register_operand" "0")))
19033    (set (match_operand:DI 1 "register_operand" "=S")
19034         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19035                  (match_operand:DI 4 "register_operand" "1")))
19036    (set (mem:BLK (match_dup 3))
19037         (mem:BLK (match_dup 4)))
19038    (use (match_dup 5))]
19039   "TARGET_64BIT"
19040   "rep movsq"
19041   [(set_attr "type" "str")
19042    (set_attr "prefix_rep" "1")
19043    (set_attr "memory" "both")
19044    (set_attr "mode" "DI")])
19045
19046 (define_insn "*rep_movsi"
19047   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19048    (set (match_operand:SI 0 "register_operand" "=D")
19049         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19050                             (const_int 2))
19051                  (match_operand:SI 3 "register_operand" "0")))
19052    (set (match_operand:SI 1 "register_operand" "=S")
19053         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19054                  (match_operand:SI 4 "register_operand" "1")))
19055    (set (mem:BLK (match_dup 3))
19056         (mem:BLK (match_dup 4)))
19057    (use (match_dup 5))]
19058   "!TARGET_64BIT"
19059   "rep movs{l|d}"
19060   [(set_attr "type" "str")
19061    (set_attr "prefix_rep" "1")
19062    (set_attr "memory" "both")
19063    (set_attr "mode" "SI")])
19064
19065 (define_insn "*rep_movsi_rex64"
19066   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19067    (set (match_operand:DI 0 "register_operand" "=D")
19068         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19069                             (const_int 2))
19070                  (match_operand:DI 3 "register_operand" "0")))
19071    (set (match_operand:DI 1 "register_operand" "=S")
19072         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19073                  (match_operand:DI 4 "register_operand" "1")))
19074    (set (mem:BLK (match_dup 3))
19075         (mem:BLK (match_dup 4)))
19076    (use (match_dup 5))]
19077   "TARGET_64BIT"
19078   "rep movs{l|d}"
19079   [(set_attr "type" "str")
19080    (set_attr "prefix_rep" "1")
19081    (set_attr "memory" "both")
19082    (set_attr "mode" "SI")])
19083
19084 (define_insn "*rep_movqi"
19085   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19086    (set (match_operand:SI 0 "register_operand" "=D")
19087         (plus:SI (match_operand:SI 3 "register_operand" "0")
19088                  (match_operand:SI 5 "register_operand" "2")))
19089    (set (match_operand:SI 1 "register_operand" "=S")
19090         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19091    (set (mem:BLK (match_dup 3))
19092         (mem:BLK (match_dup 4)))
19093    (use (match_dup 5))]
19094   "!TARGET_64BIT"
19095   "rep movsb"
19096   [(set_attr "type" "str")
19097    (set_attr "prefix_rep" "1")
19098    (set_attr "memory" "both")
19099    (set_attr "mode" "SI")])
19100
19101 (define_insn "*rep_movqi_rex64"
19102   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19103    (set (match_operand:DI 0 "register_operand" "=D")
19104         (plus:DI (match_operand:DI 3 "register_operand" "0")
19105                  (match_operand:DI 5 "register_operand" "2")))
19106    (set (match_operand:DI 1 "register_operand" "=S")
19107         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19108    (set (mem:BLK (match_dup 3))
19109         (mem:BLK (match_dup 4)))
19110    (use (match_dup 5))]
19111   "TARGET_64BIT"
19112   "rep movsb"
19113   [(set_attr "type" "str")
19114    (set_attr "prefix_rep" "1")
19115    (set_attr "memory" "both")
19116    (set_attr "mode" "SI")])
19117
19118 (define_expand "setmemsi"
19119    [(use (match_operand:BLK 0 "memory_operand" ""))
19120     (use (match_operand:SI 1 "nonmemory_operand" ""))
19121     (use (match_operand 2 "const_int_operand" ""))
19122     (use (match_operand 3 "const_int_operand" ""))
19123     (use (match_operand:SI 4 "const_int_operand" ""))
19124     (use (match_operand:SI 5 "const_int_operand" ""))]
19125   ""
19126 {
19127  if (ix86_expand_setmem (operands[0], operands[1],
19128                          operands[2], operands[3],
19129                          operands[4], operands[5]))
19130    DONE;
19131  else
19132    FAIL;
19133 })
19134
19135 (define_expand "setmemdi"
19136    [(use (match_operand:BLK 0 "memory_operand" ""))
19137     (use (match_operand:DI 1 "nonmemory_operand" ""))
19138     (use (match_operand 2 "const_int_operand" ""))
19139     (use (match_operand 3 "const_int_operand" ""))
19140     (use (match_operand 4 "const_int_operand" ""))
19141     (use (match_operand 5 "const_int_operand" ""))]
19142   "TARGET_64BIT"
19143 {
19144  if (ix86_expand_setmem (operands[0], operands[1],
19145                          operands[2], operands[3],
19146                          operands[4], operands[5]))
19147    DONE;
19148  else
19149    FAIL;
19150 })
19151
19152 ;; Most CPUs don't like single string operations
19153 ;; Handle this case here to simplify previous expander.
19154
19155 (define_expand "strset"
19156   [(set (match_operand 1 "memory_operand" "")
19157         (match_operand 2 "register_operand" ""))
19158    (parallel [(set (match_operand 0 "register_operand" "")
19159                    (match_dup 3))
19160               (clobber (reg:CC FLAGS_REG))])]
19161   ""
19162 {
19163   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19164     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19165
19166   /* If .md ever supports :P for Pmode, this can be directly
19167      in the pattern above.  */
19168   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19169                               GEN_INT (GET_MODE_SIZE (GET_MODE
19170                                                       (operands[2]))));
19171   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19172     {
19173       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19174                                       operands[3]));
19175       DONE;
19176     }
19177 })
19178
19179 (define_expand "strset_singleop"
19180   [(parallel [(set (match_operand 1 "memory_operand" "")
19181                    (match_operand 2 "register_operand" ""))
19182               (set (match_operand 0 "register_operand" "")
19183                    (match_operand 3 "" ""))])]
19184   ""
19185   "ix86_current_function_needs_cld = 1;")
19186
19187 (define_insn "*strsetdi_rex_1"
19188   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19189         (match_operand:DI 2 "register_operand" "a"))
19190    (set (match_operand:DI 0 "register_operand" "=D")
19191         (plus:DI (match_dup 1)
19192                  (const_int 8)))]
19193   "TARGET_64BIT"
19194   "stosq"
19195   [(set_attr "type" "str")
19196    (set_attr "memory" "store")
19197    (set_attr "mode" "DI")])
19198
19199 (define_insn "*strsetsi_1"
19200   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19201         (match_operand:SI 2 "register_operand" "a"))
19202    (set (match_operand:SI 0 "register_operand" "=D")
19203         (plus:SI (match_dup 1)
19204                  (const_int 4)))]
19205   "!TARGET_64BIT"
19206   "stos{l|d}"
19207   [(set_attr "type" "str")
19208    (set_attr "memory" "store")
19209    (set_attr "mode" "SI")])
19210
19211 (define_insn "*strsetsi_rex_1"
19212   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19213         (match_operand:SI 2 "register_operand" "a"))
19214    (set (match_operand:DI 0 "register_operand" "=D")
19215         (plus:DI (match_dup 1)
19216                  (const_int 4)))]
19217   "TARGET_64BIT"
19218   "stos{l|d}"
19219   [(set_attr "type" "str")
19220    (set_attr "memory" "store")
19221    (set_attr "mode" "SI")])
19222
19223 (define_insn "*strsethi_1"
19224   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19225         (match_operand:HI 2 "register_operand" "a"))
19226    (set (match_operand:SI 0 "register_operand" "=D")
19227         (plus:SI (match_dup 1)
19228                  (const_int 2)))]
19229   "!TARGET_64BIT"
19230   "stosw"
19231   [(set_attr "type" "str")
19232    (set_attr "memory" "store")
19233    (set_attr "mode" "HI")])
19234
19235 (define_insn "*strsethi_rex_1"
19236   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19237         (match_operand:HI 2 "register_operand" "a"))
19238    (set (match_operand:DI 0 "register_operand" "=D")
19239         (plus:DI (match_dup 1)
19240                  (const_int 2)))]
19241   "TARGET_64BIT"
19242   "stosw"
19243   [(set_attr "type" "str")
19244    (set_attr "memory" "store")
19245    (set_attr "mode" "HI")])
19246
19247 (define_insn "*strsetqi_1"
19248   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19249         (match_operand:QI 2 "register_operand" "a"))
19250    (set (match_operand:SI 0 "register_operand" "=D")
19251         (plus:SI (match_dup 1)
19252                  (const_int 1)))]
19253   "!TARGET_64BIT"
19254   "stosb"
19255   [(set_attr "type" "str")
19256    (set_attr "memory" "store")
19257    (set_attr "mode" "QI")])
19258
19259 (define_insn "*strsetqi_rex_1"
19260   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19261         (match_operand:QI 2 "register_operand" "a"))
19262    (set (match_operand:DI 0 "register_operand" "=D")
19263         (plus:DI (match_dup 1)
19264                  (const_int 1)))]
19265   "TARGET_64BIT"
19266   "stosb"
19267   [(set_attr "type" "str")
19268    (set_attr "memory" "store")
19269    (set_attr "prefix_rex" "0")
19270    (set_attr "mode" "QI")])
19271
19272 (define_expand "rep_stos"
19273   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19274               (set (match_operand 0 "register_operand" "")
19275                    (match_operand 4 "" ""))
19276               (set (match_operand 2 "memory_operand" "") (const_int 0))
19277               (use (match_operand 3 "register_operand" ""))
19278               (use (match_dup 1))])]
19279   ""
19280   "ix86_current_function_needs_cld = 1;")
19281
19282 (define_insn "*rep_stosdi_rex64"
19283   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19284    (set (match_operand:DI 0 "register_operand" "=D")
19285         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19286                             (const_int 3))
19287                  (match_operand:DI 3 "register_operand" "0")))
19288    (set (mem:BLK (match_dup 3))
19289         (const_int 0))
19290    (use (match_operand:DI 2 "register_operand" "a"))
19291    (use (match_dup 4))]
19292   "TARGET_64BIT"
19293   "rep stosq"
19294   [(set_attr "type" "str")
19295    (set_attr "prefix_rep" "1")
19296    (set_attr "memory" "store")
19297    (set_attr "mode" "DI")])
19298
19299 (define_insn "*rep_stossi"
19300   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19301    (set (match_operand:SI 0 "register_operand" "=D")
19302         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19303                             (const_int 2))
19304                  (match_operand:SI 3 "register_operand" "0")))
19305    (set (mem:BLK (match_dup 3))
19306         (const_int 0))
19307    (use (match_operand:SI 2 "register_operand" "a"))
19308    (use (match_dup 4))]
19309   "!TARGET_64BIT"
19310   "rep stos{l|d}"
19311   [(set_attr "type" "str")
19312    (set_attr "prefix_rep" "1")
19313    (set_attr "memory" "store")
19314    (set_attr "mode" "SI")])
19315
19316 (define_insn "*rep_stossi_rex64"
19317   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19318    (set (match_operand:DI 0 "register_operand" "=D")
19319         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19320                             (const_int 2))
19321                  (match_operand:DI 3 "register_operand" "0")))
19322    (set (mem:BLK (match_dup 3))
19323         (const_int 0))
19324    (use (match_operand:SI 2 "register_operand" "a"))
19325    (use (match_dup 4))]
19326   "TARGET_64BIT"
19327   "rep stos{l|d}"
19328   [(set_attr "type" "str")
19329    (set_attr "prefix_rep" "1")
19330    (set_attr "memory" "store")
19331    (set_attr "mode" "SI")])
19332
19333 (define_insn "*rep_stosqi"
19334   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19335    (set (match_operand:SI 0 "register_operand" "=D")
19336         (plus:SI (match_operand:SI 3 "register_operand" "0")
19337                  (match_operand:SI 4 "register_operand" "1")))
19338    (set (mem:BLK (match_dup 3))
19339         (const_int 0))
19340    (use (match_operand:QI 2 "register_operand" "a"))
19341    (use (match_dup 4))]
19342   "!TARGET_64BIT"
19343   "rep stosb"
19344   [(set_attr "type" "str")
19345    (set_attr "prefix_rep" "1")
19346    (set_attr "memory" "store")
19347    (set_attr "mode" "QI")])
19348
19349 (define_insn "*rep_stosqi_rex64"
19350   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19351    (set (match_operand:DI 0 "register_operand" "=D")
19352         (plus:DI (match_operand:DI 3 "register_operand" "0")
19353                  (match_operand:DI 4 "register_operand" "1")))
19354    (set (mem:BLK (match_dup 3))
19355         (const_int 0))
19356    (use (match_operand:QI 2 "register_operand" "a"))
19357    (use (match_dup 4))]
19358   "TARGET_64BIT"
19359   "rep stosb"
19360   [(set_attr "type" "str")
19361    (set_attr "prefix_rep" "1")
19362    (set_attr "memory" "store")
19363    (set_attr "prefix_rex" "0")
19364    (set_attr "mode" "QI")])
19365
19366 (define_expand "cmpstrnsi"
19367   [(set (match_operand:SI 0 "register_operand" "")
19368         (compare:SI (match_operand:BLK 1 "general_operand" "")
19369                     (match_operand:BLK 2 "general_operand" "")))
19370    (use (match_operand 3 "general_operand" ""))
19371    (use (match_operand 4 "immediate_operand" ""))]
19372   ""
19373 {
19374   rtx addr1, addr2, out, outlow, count, countreg, align;
19375
19376   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19377     FAIL;
19378
19379   /* Can't use this if the user has appropriated esi or edi.  */
19380   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19381     FAIL;
19382
19383   out = operands[0];
19384   if (!REG_P (out))
19385     out = gen_reg_rtx (SImode);
19386
19387   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19388   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19389   if (addr1 != XEXP (operands[1], 0))
19390     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19391   if (addr2 != XEXP (operands[2], 0))
19392     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19393
19394   count = operands[3];
19395   countreg = ix86_zero_extend_to_Pmode (count);
19396
19397   /* %%% Iff we are testing strict equality, we can use known alignment
19398      to good advantage.  This may be possible with combine, particularly
19399      once cc0 is dead.  */
19400   align = operands[4];
19401
19402   if (CONST_INT_P (count))
19403     {
19404       if (INTVAL (count) == 0)
19405         {
19406           emit_move_insn (operands[0], const0_rtx);
19407           DONE;
19408         }
19409       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19410                                      operands[1], operands[2]));
19411     }
19412   else
19413     {
19414       if (TARGET_64BIT)
19415         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19416       else
19417         emit_insn (gen_cmpsi_1 (countreg, countreg));
19418       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19419                                   operands[1], operands[2]));
19420     }
19421
19422   outlow = gen_lowpart (QImode, out);
19423   emit_insn (gen_cmpintqi (outlow));
19424   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19425
19426   if (operands[0] != out)
19427     emit_move_insn (operands[0], out);
19428
19429   DONE;
19430 })
19431
19432 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19433
19434 (define_expand "cmpintqi"
19435   [(set (match_dup 1)
19436         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19437    (set (match_dup 2)
19438         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19439    (parallel [(set (match_operand:QI 0 "register_operand" "")
19440                    (minus:QI (match_dup 1)
19441                              (match_dup 2)))
19442               (clobber (reg:CC FLAGS_REG))])]
19443   ""
19444   "operands[1] = gen_reg_rtx (QImode);
19445    operands[2] = gen_reg_rtx (QImode);")
19446
19447 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19448 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19449
19450 (define_expand "cmpstrnqi_nz_1"
19451   [(parallel [(set (reg:CC FLAGS_REG)
19452                    (compare:CC (match_operand 4 "memory_operand" "")
19453                                (match_operand 5 "memory_operand" "")))
19454               (use (match_operand 2 "register_operand" ""))
19455               (use (match_operand:SI 3 "immediate_operand" ""))
19456               (clobber (match_operand 0 "register_operand" ""))
19457               (clobber (match_operand 1 "register_operand" ""))
19458               (clobber (match_dup 2))])]
19459   ""
19460   "ix86_current_function_needs_cld = 1;")
19461
19462 (define_insn "*cmpstrnqi_nz_1"
19463   [(set (reg:CC FLAGS_REG)
19464         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19465                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19466    (use (match_operand:SI 6 "register_operand" "2"))
19467    (use (match_operand:SI 3 "immediate_operand" "i"))
19468    (clobber (match_operand:SI 0 "register_operand" "=S"))
19469    (clobber (match_operand:SI 1 "register_operand" "=D"))
19470    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19471   "!TARGET_64BIT"
19472   "repz cmpsb"
19473   [(set_attr "type" "str")
19474    (set_attr "mode" "QI")
19475    (set_attr "prefix_rep" "1")])
19476
19477 (define_insn "*cmpstrnqi_nz_rex_1"
19478   [(set (reg:CC FLAGS_REG)
19479         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19480                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19481    (use (match_operand:DI 6 "register_operand" "2"))
19482    (use (match_operand:SI 3 "immediate_operand" "i"))
19483    (clobber (match_operand:DI 0 "register_operand" "=S"))
19484    (clobber (match_operand:DI 1 "register_operand" "=D"))
19485    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19486   "TARGET_64BIT"
19487   "repz cmpsb"
19488   [(set_attr "type" "str")
19489    (set_attr "mode" "QI")
19490    (set_attr "prefix_rex" "0")
19491    (set_attr "prefix_rep" "1")])
19492
19493 ;; The same, but the count is not known to not be zero.
19494
19495 (define_expand "cmpstrnqi_1"
19496   [(parallel [(set (reg:CC FLAGS_REG)
19497                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19498                                      (const_int 0))
19499                   (compare:CC (match_operand 4 "memory_operand" "")
19500                               (match_operand 5 "memory_operand" ""))
19501                   (const_int 0)))
19502               (use (match_operand:SI 3 "immediate_operand" ""))
19503               (use (reg:CC FLAGS_REG))
19504               (clobber (match_operand 0 "register_operand" ""))
19505               (clobber (match_operand 1 "register_operand" ""))
19506               (clobber (match_dup 2))])]
19507   ""
19508   "ix86_current_function_needs_cld = 1;")
19509
19510 (define_insn "*cmpstrnqi_1"
19511   [(set (reg:CC FLAGS_REG)
19512         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19513                              (const_int 0))
19514           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19515                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19516           (const_int 0)))
19517    (use (match_operand:SI 3 "immediate_operand" "i"))
19518    (use (reg:CC FLAGS_REG))
19519    (clobber (match_operand:SI 0 "register_operand" "=S"))
19520    (clobber (match_operand:SI 1 "register_operand" "=D"))
19521    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19522   "!TARGET_64BIT"
19523   "repz cmpsb"
19524   [(set_attr "type" "str")
19525    (set_attr "mode" "QI")
19526    (set_attr "prefix_rep" "1")])
19527
19528 (define_insn "*cmpstrnqi_rex_1"
19529   [(set (reg:CC FLAGS_REG)
19530         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19531                              (const_int 0))
19532           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19533                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19534           (const_int 0)))
19535    (use (match_operand:SI 3 "immediate_operand" "i"))
19536    (use (reg:CC FLAGS_REG))
19537    (clobber (match_operand:DI 0 "register_operand" "=S"))
19538    (clobber (match_operand:DI 1 "register_operand" "=D"))
19539    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19540   "TARGET_64BIT"
19541   "repz cmpsb"
19542   [(set_attr "type" "str")
19543    (set_attr "mode" "QI")
19544    (set_attr "prefix_rex" "0")
19545    (set_attr "prefix_rep" "1")])
19546
19547 (define_expand "strlensi"
19548   [(set (match_operand:SI 0 "register_operand" "")
19549         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19550                     (match_operand:QI 2 "immediate_operand" "")
19551                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19552   ""
19553 {
19554  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19555    DONE;
19556  else
19557    FAIL;
19558 })
19559
19560 (define_expand "strlendi"
19561   [(set (match_operand:DI 0 "register_operand" "")
19562         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19563                     (match_operand:QI 2 "immediate_operand" "")
19564                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19565   ""
19566 {
19567  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19568    DONE;
19569  else
19570    FAIL;
19571 })
19572
19573 (define_expand "strlenqi_1"
19574   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19575               (clobber (match_operand 1 "register_operand" ""))
19576               (clobber (reg:CC FLAGS_REG))])]
19577   ""
19578   "ix86_current_function_needs_cld = 1;")
19579
19580 (define_insn "*strlenqi_1"
19581   [(set (match_operand:SI 0 "register_operand" "=&c")
19582         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19583                     (match_operand:QI 2 "register_operand" "a")
19584                     (match_operand:SI 3 "immediate_operand" "i")
19585                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19586    (clobber (match_operand:SI 1 "register_operand" "=D"))
19587    (clobber (reg:CC FLAGS_REG))]
19588   "!TARGET_64BIT"
19589   "repnz scasb"
19590   [(set_attr "type" "str")
19591    (set_attr "mode" "QI")
19592    (set_attr "prefix_rep" "1")])
19593
19594 (define_insn "*strlenqi_rex_1"
19595   [(set (match_operand:DI 0 "register_operand" "=&c")
19596         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19597                     (match_operand:QI 2 "register_operand" "a")
19598                     (match_operand:DI 3 "immediate_operand" "i")
19599                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19600    (clobber (match_operand:DI 1 "register_operand" "=D"))
19601    (clobber (reg:CC FLAGS_REG))]
19602   "TARGET_64BIT"
19603   "repnz scasb"
19604   [(set_attr "type" "str")
19605    (set_attr "mode" "QI")
19606    (set_attr "prefix_rex" "0")
19607    (set_attr "prefix_rep" "1")])
19608
19609 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19610 ;; handled in combine, but it is not currently up to the task.
19611 ;; When used for their truth value, the cmpstrn* expanders generate
19612 ;; code like this:
19613 ;;
19614 ;;   repz cmpsb
19615 ;;   seta       %al
19616 ;;   setb       %dl
19617 ;;   cmpb       %al, %dl
19618 ;;   jcc        label
19619 ;;
19620 ;; The intermediate three instructions are unnecessary.
19621
19622 ;; This one handles cmpstrn*_nz_1...
19623 (define_peephole2
19624   [(parallel[
19625      (set (reg:CC FLAGS_REG)
19626           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19627                       (mem:BLK (match_operand 5 "register_operand" ""))))
19628      (use (match_operand 6 "register_operand" ""))
19629      (use (match_operand:SI 3 "immediate_operand" ""))
19630      (clobber (match_operand 0 "register_operand" ""))
19631      (clobber (match_operand 1 "register_operand" ""))
19632      (clobber (match_operand 2 "register_operand" ""))])
19633    (set (match_operand:QI 7 "register_operand" "")
19634         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19635    (set (match_operand:QI 8 "register_operand" "")
19636         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19637    (set (reg FLAGS_REG)
19638         (compare (match_dup 7) (match_dup 8)))
19639   ]
19640   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19641   [(parallel[
19642      (set (reg:CC FLAGS_REG)
19643           (compare:CC (mem:BLK (match_dup 4))
19644                       (mem:BLK (match_dup 5))))
19645      (use (match_dup 6))
19646      (use (match_dup 3))
19647      (clobber (match_dup 0))
19648      (clobber (match_dup 1))
19649      (clobber (match_dup 2))])]
19650   "")
19651
19652 ;; ...and this one handles cmpstrn*_1.
19653 (define_peephole2
19654   [(parallel[
19655      (set (reg:CC FLAGS_REG)
19656           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19657                                (const_int 0))
19658             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19659                         (mem:BLK (match_operand 5 "register_operand" "")))
19660             (const_int 0)))
19661      (use (match_operand:SI 3 "immediate_operand" ""))
19662      (use (reg:CC FLAGS_REG))
19663      (clobber (match_operand 0 "register_operand" ""))
19664      (clobber (match_operand 1 "register_operand" ""))
19665      (clobber (match_operand 2 "register_operand" ""))])
19666    (set (match_operand:QI 7 "register_operand" "")
19667         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19668    (set (match_operand:QI 8 "register_operand" "")
19669         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19670    (set (reg FLAGS_REG)
19671         (compare (match_dup 7) (match_dup 8)))
19672   ]
19673   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19674   [(parallel[
19675      (set (reg:CC FLAGS_REG)
19676           (if_then_else:CC (ne (match_dup 6)
19677                                (const_int 0))
19678             (compare:CC (mem:BLK (match_dup 4))
19679                         (mem:BLK (match_dup 5)))
19680             (const_int 0)))
19681      (use (match_dup 3))
19682      (use (reg:CC FLAGS_REG))
19683      (clobber (match_dup 0))
19684      (clobber (match_dup 1))
19685      (clobber (match_dup 2))])]
19686   "")
19687
19688
19689 \f
19690 ;; Conditional move instructions.
19691
19692 (define_expand "movdicc"
19693   [(set (match_operand:DI 0 "register_operand" "")
19694         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19695                          (match_operand:DI 2 "general_operand" "")
19696                          (match_operand:DI 3 "general_operand" "")))]
19697   "TARGET_64BIT"
19698   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19699
19700 (define_insn "x86_movdicc_0_m1_rex64"
19701   [(set (match_operand:DI 0 "register_operand" "=r")
19702         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19703           (const_int -1)
19704           (const_int 0)))
19705    (clobber (reg:CC FLAGS_REG))]
19706   "TARGET_64BIT"
19707   "sbb{q}\t%0, %0"
19708   ; Since we don't have the proper number of operands for an alu insn,
19709   ; fill in all the blanks.
19710   [(set_attr "type" "alu")
19711    (set_attr "use_carry" "1")
19712    (set_attr "pent_pair" "pu")
19713    (set_attr "memory" "none")
19714    (set_attr "imm_disp" "false")
19715    (set_attr "mode" "DI")
19716    (set_attr "length_immediate" "0")])
19717
19718 (define_insn "*x86_movdicc_0_m1_se"
19719   [(set (match_operand:DI 0 "register_operand" "=r")
19720         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19721                          (const_int 1)
19722                          (const_int 0)))
19723    (clobber (reg:CC FLAGS_REG))]
19724   ""
19725   "sbb{q}\t%0, %0"
19726   [(set_attr "type" "alu")
19727    (set_attr "use_carry" "1")
19728    (set_attr "pent_pair" "pu")
19729    (set_attr "memory" "none")
19730    (set_attr "imm_disp" "false")
19731    (set_attr "mode" "DI")
19732    (set_attr "length_immediate" "0")])
19733
19734 (define_insn "*movdicc_c_rex64"
19735   [(set (match_operand:DI 0 "register_operand" "=r,r")
19736         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19737                                 [(reg FLAGS_REG) (const_int 0)])
19738                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19739                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19740   "TARGET_64BIT && TARGET_CMOVE
19741    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19742   "@
19743    cmov%O2%C1\t{%2, %0|%0, %2}
19744    cmov%O2%c1\t{%3, %0|%0, %3}"
19745   [(set_attr "type" "icmov")
19746    (set_attr "mode" "DI")])
19747
19748 (define_expand "movsicc"
19749   [(set (match_operand:SI 0 "register_operand" "")
19750         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19751                          (match_operand:SI 2 "general_operand" "")
19752                          (match_operand:SI 3 "general_operand" "")))]
19753   ""
19754   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19755
19756 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19757 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19758 ;; So just document what we're doing explicitly.
19759
19760 (define_insn "x86_movsicc_0_m1"
19761   [(set (match_operand:SI 0 "register_operand" "=r")
19762         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19763           (const_int -1)
19764           (const_int 0)))
19765    (clobber (reg:CC FLAGS_REG))]
19766   ""
19767   "sbb{l}\t%0, %0"
19768   ; Since we don't have the proper number of operands for an alu insn,
19769   ; fill in all the blanks.
19770   [(set_attr "type" "alu")
19771    (set_attr "use_carry" "1")
19772    (set_attr "pent_pair" "pu")
19773    (set_attr "memory" "none")
19774    (set_attr "imm_disp" "false")
19775    (set_attr "mode" "SI")
19776    (set_attr "length_immediate" "0")])
19777
19778 (define_insn "*x86_movsicc_0_m1_se"
19779   [(set (match_operand:SI 0 "register_operand" "=r")
19780         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19781                          (const_int 1)
19782                          (const_int 0)))
19783    (clobber (reg:CC FLAGS_REG))]
19784   ""
19785   "sbb{l}\t%0, %0"
19786   [(set_attr "type" "alu")
19787    (set_attr "use_carry" "1")
19788    (set_attr "pent_pair" "pu")
19789    (set_attr "memory" "none")
19790    (set_attr "imm_disp" "false")
19791    (set_attr "mode" "SI")
19792    (set_attr "length_immediate" "0")])
19793
19794 (define_insn "*movsicc_noc"
19795   [(set (match_operand:SI 0 "register_operand" "=r,r")
19796         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19797                                 [(reg FLAGS_REG) (const_int 0)])
19798                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19799                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19800   "TARGET_CMOVE
19801    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19802   "@
19803    cmov%O2%C1\t{%2, %0|%0, %2}
19804    cmov%O2%c1\t{%3, %0|%0, %3}"
19805   [(set_attr "type" "icmov")
19806    (set_attr "mode" "SI")])
19807
19808 (define_expand "movhicc"
19809   [(set (match_operand:HI 0 "register_operand" "")
19810         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19811                          (match_operand:HI 2 "general_operand" "")
19812                          (match_operand:HI 3 "general_operand" "")))]
19813   "TARGET_HIMODE_MATH"
19814   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19815
19816 (define_insn "*movhicc_noc"
19817   [(set (match_operand:HI 0 "register_operand" "=r,r")
19818         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19819                                 [(reg FLAGS_REG) (const_int 0)])
19820                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19821                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19822   "TARGET_CMOVE
19823    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19824   "@
19825    cmov%O2%C1\t{%2, %0|%0, %2}
19826    cmov%O2%c1\t{%3, %0|%0, %3}"
19827   [(set_attr "type" "icmov")
19828    (set_attr "mode" "HI")])
19829
19830 (define_expand "movqicc"
19831   [(set (match_operand:QI 0 "register_operand" "")
19832         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19833                          (match_operand:QI 2 "general_operand" "")
19834                          (match_operand:QI 3 "general_operand" "")))]
19835   "TARGET_QIMODE_MATH"
19836   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19837
19838 (define_insn_and_split "*movqicc_noc"
19839   [(set (match_operand:QI 0 "register_operand" "=r,r")
19840         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19841                                 [(match_operand 4 "flags_reg_operand" "")
19842                                  (const_int 0)])
19843                       (match_operand:QI 2 "register_operand" "r,0")
19844                       (match_operand:QI 3 "register_operand" "0,r")))]
19845   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19846   "#"
19847   "&& reload_completed"
19848   [(set (match_dup 0)
19849         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19850                       (match_dup 2)
19851                       (match_dup 3)))]
19852   "operands[0] = gen_lowpart (SImode, operands[0]);
19853    operands[2] = gen_lowpart (SImode, operands[2]);
19854    operands[3] = gen_lowpart (SImode, operands[3]);"
19855   [(set_attr "type" "icmov")
19856    (set_attr "mode" "SI")])
19857
19858 (define_expand "mov<mode>cc"
19859   [(set (match_operand:X87MODEF 0 "register_operand" "")
19860         (if_then_else:X87MODEF
19861           (match_operand 1 "ix86_fp_comparison_operator" "")
19862           (match_operand:X87MODEF 2 "register_operand" "")
19863           (match_operand:X87MODEF 3 "register_operand" "")))]
19864   "(TARGET_80387 && TARGET_CMOVE)
19865    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19866   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19867
19868 (define_insn "*movsfcc_1_387"
19869   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19870         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19871                                 [(reg FLAGS_REG) (const_int 0)])
19872                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19873                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19874   "TARGET_80387 && TARGET_CMOVE
19875    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19876   "@
19877    fcmov%F1\t{%2, %0|%0, %2}
19878    fcmov%f1\t{%3, %0|%0, %3}
19879    cmov%O2%C1\t{%2, %0|%0, %2}
19880    cmov%O2%c1\t{%3, %0|%0, %3}"
19881   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19882    (set_attr "mode" "SF,SF,SI,SI")])
19883
19884 (define_insn "*movdfcc_1"
19885   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19886         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19887                                 [(reg FLAGS_REG) (const_int 0)])
19888                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19889                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19890   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19891    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19892   "@
19893    fcmov%F1\t{%2, %0|%0, %2}
19894    fcmov%f1\t{%3, %0|%0, %3}
19895    #
19896    #"
19897   [(set_attr "type" "fcmov,fcmov,multi,multi")
19898    (set_attr "mode" "DF")])
19899
19900 (define_insn "*movdfcc_1_rex64"
19901   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19902         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19903                                 [(reg FLAGS_REG) (const_int 0)])
19904                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19905                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19906   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19907    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19908   "@
19909    fcmov%F1\t{%2, %0|%0, %2}
19910    fcmov%f1\t{%3, %0|%0, %3}
19911    cmov%O2%C1\t{%2, %0|%0, %2}
19912    cmov%O2%c1\t{%3, %0|%0, %3}"
19913   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19914    (set_attr "mode" "DF")])
19915
19916 (define_split
19917   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19918         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19919                                 [(match_operand 4 "flags_reg_operand" "")
19920                                  (const_int 0)])
19921                       (match_operand:DF 2 "nonimmediate_operand" "")
19922                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19923   "!TARGET_64BIT && reload_completed"
19924   [(set (match_dup 2)
19925         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19926                       (match_dup 5)
19927                       (match_dup 6)))
19928    (set (match_dup 3)
19929         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19930                       (match_dup 7)
19931                       (match_dup 8)))]
19932   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19933    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19934
19935 (define_insn "*movxfcc_1"
19936   [(set (match_operand:XF 0 "register_operand" "=f,f")
19937         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19938                                 [(reg FLAGS_REG) (const_int 0)])
19939                       (match_operand:XF 2 "register_operand" "f,0")
19940                       (match_operand:XF 3 "register_operand" "0,f")))]
19941   "TARGET_80387 && TARGET_CMOVE"
19942   "@
19943    fcmov%F1\t{%2, %0|%0, %2}
19944    fcmov%f1\t{%3, %0|%0, %3}"
19945   [(set_attr "type" "fcmov")
19946    (set_attr "mode" "XF")])
19947
19948 ;; These versions of the min/max patterns are intentionally ignorant of
19949 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19950 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19951 ;; are undefined in this condition, we're certain this is correct.
19952
19953 (define_insn "*avx_<code><mode>3"
19954   [(set (match_operand:MODEF 0 "register_operand" "=x")
19955         (smaxmin:MODEF
19956           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19957           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19958   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19959   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19960   [(set_attr "type" "sseadd")
19961    (set_attr "prefix" "vex")
19962    (set_attr "mode" "<MODE>")])
19963
19964 (define_insn "<code><mode>3"
19965   [(set (match_operand:MODEF 0 "register_operand" "=x")
19966         (smaxmin:MODEF
19967           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19968           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19969   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19970   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19971   [(set_attr "type" "sseadd")
19972    (set_attr "mode" "<MODE>")])
19973
19974 ;; These versions of the min/max patterns implement exactly the operations
19975 ;;   min = (op1 < op2 ? op1 : op2)
19976 ;;   max = (!(op1 < op2) ? op1 : op2)
19977 ;; Their operands are not commutative, and thus they may be used in the
19978 ;; presence of -0.0 and NaN.
19979
19980 (define_insn "*avx_ieee_smin<mode>3"
19981   [(set (match_operand:MODEF 0 "register_operand" "=x")
19982         (unspec:MODEF
19983           [(match_operand:MODEF 1 "register_operand" "x")
19984            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19985          UNSPEC_IEEE_MIN))]
19986   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19987   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19988   [(set_attr "type" "sseadd")
19989    (set_attr "prefix" "vex")
19990    (set_attr "mode" "<MODE>")])
19991
19992 (define_insn "*ieee_smin<mode>3"
19993   [(set (match_operand:MODEF 0 "register_operand" "=x")
19994         (unspec:MODEF
19995           [(match_operand:MODEF 1 "register_operand" "0")
19996            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19997          UNSPEC_IEEE_MIN))]
19998   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19999   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20000   [(set_attr "type" "sseadd")
20001    (set_attr "mode" "<MODE>")])
20002
20003 (define_insn "*avx_ieee_smax<mode>3"
20004   [(set (match_operand:MODEF 0 "register_operand" "=x")
20005         (unspec:MODEF
20006           [(match_operand:MODEF 1 "register_operand" "0")
20007            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20008          UNSPEC_IEEE_MAX))]
20009   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20010   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20011   [(set_attr "type" "sseadd")
20012    (set_attr "prefix" "vex")
20013    (set_attr "mode" "<MODE>")])
20014
20015 (define_insn "*ieee_smax<mode>3"
20016   [(set (match_operand:MODEF 0 "register_operand" "=x")
20017         (unspec:MODEF
20018           [(match_operand:MODEF 1 "register_operand" "0")
20019            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20020          UNSPEC_IEEE_MAX))]
20021   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20022   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20023   [(set_attr "type" "sseadd")
20024    (set_attr "mode" "<MODE>")])
20025
20026 ;; Make two stack loads independent:
20027 ;;   fld aa              fld aa
20028 ;;   fld %st(0)     ->   fld bb
20029 ;;   fmul bb             fmul %st(1), %st
20030 ;;
20031 ;; Actually we only match the last two instructions for simplicity.
20032 (define_peephole2
20033   [(set (match_operand 0 "fp_register_operand" "")
20034         (match_operand 1 "fp_register_operand" ""))
20035    (set (match_dup 0)
20036         (match_operator 2 "binary_fp_operator"
20037            [(match_dup 0)
20038             (match_operand 3 "memory_operand" "")]))]
20039   "REGNO (operands[0]) != REGNO (operands[1])"
20040   [(set (match_dup 0) (match_dup 3))
20041    (set (match_dup 0) (match_dup 4))]
20042
20043   ;; The % modifier is not operational anymore in peephole2's, so we have to
20044   ;; swap the operands manually in the case of addition and multiplication.
20045   "if (COMMUTATIVE_ARITH_P (operands[2]))
20046      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20047                                  operands[0], operands[1]);
20048    else
20049      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20050                                  operands[1], operands[0]);")
20051
20052 ;; Conditional addition patterns
20053 (define_expand "add<mode>cc"
20054   [(match_operand:SWI 0 "register_operand" "")
20055    (match_operand 1 "comparison_operator" "")
20056    (match_operand:SWI 2 "register_operand" "")
20057    (match_operand:SWI 3 "const_int_operand" "")]
20058   ""
20059   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20060
20061 \f
20062 ;; Misc patterns (?)
20063
20064 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20065 ;; Otherwise there will be nothing to keep
20066 ;;
20067 ;; [(set (reg ebp) (reg esp))]
20068 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20069 ;;  (clobber (eflags)]
20070 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20071 ;;
20072 ;; in proper program order.
20073 (define_insn "pro_epilogue_adjust_stack_1"
20074   [(set (match_operand:SI 0 "register_operand" "=r,r")
20075         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20076                  (match_operand:SI 2 "immediate_operand" "i,i")))
20077    (clobber (reg:CC FLAGS_REG))
20078    (clobber (mem:BLK (scratch)))]
20079   "!TARGET_64BIT"
20080 {
20081   switch (get_attr_type (insn))
20082     {
20083     case TYPE_IMOV:
20084       return "mov{l}\t{%1, %0|%0, %1}";
20085
20086     case TYPE_ALU:
20087       if (CONST_INT_P (operands[2])
20088           && (INTVAL (operands[2]) == 128
20089               || (INTVAL (operands[2]) < 0
20090                   && INTVAL (operands[2]) != -128)))
20091         {
20092           operands[2] = GEN_INT (-INTVAL (operands[2]));
20093           return "sub{l}\t{%2, %0|%0, %2}";
20094         }
20095       return "add{l}\t{%2, %0|%0, %2}";
20096
20097     case TYPE_LEA:
20098       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20099       return "lea{l}\t{%a2, %0|%0, %a2}";
20100
20101     default:
20102       gcc_unreachable ();
20103     }
20104 }
20105   [(set (attr "type")
20106         (cond [(and (eq_attr "alternative" "0") 
20107                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20108                  (const_string "alu")
20109                (match_operand:SI 2 "const0_operand" "")
20110                  (const_string "imov")
20111               ]
20112               (const_string "lea")))
20113    (set (attr "length_immediate")
20114         (cond [(eq_attr "type" "imov")
20115                  (const_string "0")
20116                (and (eq_attr "type" "alu")
20117                     (match_operand 2 "const128_operand" ""))
20118                  (const_string "1")
20119               ]
20120               (const_string "*")))
20121    (set_attr "mode" "SI")])
20122
20123 (define_insn "pro_epilogue_adjust_stack_rex64"
20124   [(set (match_operand:DI 0 "register_operand" "=r,r")
20125         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20126                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20127    (clobber (reg:CC FLAGS_REG))
20128    (clobber (mem:BLK (scratch)))]
20129   "TARGET_64BIT"
20130 {
20131   switch (get_attr_type (insn))
20132     {
20133     case TYPE_IMOV:
20134       return "mov{q}\t{%1, %0|%0, %1}";
20135
20136     case TYPE_ALU:
20137       if (CONST_INT_P (operands[2])
20138           /* Avoid overflows.  */
20139           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20140           && (INTVAL (operands[2]) == 128
20141               || (INTVAL (operands[2]) < 0
20142                   && INTVAL (operands[2]) != -128)))
20143         {
20144           operands[2] = GEN_INT (-INTVAL (operands[2]));
20145           return "sub{q}\t{%2, %0|%0, %2}";
20146         }
20147       return "add{q}\t{%2, %0|%0, %2}";
20148
20149     case TYPE_LEA:
20150       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20151       return "lea{q}\t{%a2, %0|%0, %a2}";
20152
20153     default:
20154       gcc_unreachable ();
20155     }
20156 }
20157   [(set (attr "type")
20158         (cond [(and (eq_attr "alternative" "0")
20159                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20160                  (const_string "alu")
20161                (match_operand:DI 2 "const0_operand" "")
20162                  (const_string "imov")
20163               ]
20164               (const_string "lea")))
20165    (set (attr "length_immediate")
20166         (cond [(eq_attr "type" "imov")
20167                  (const_string "0")
20168                (and (eq_attr "type" "alu")
20169                     (match_operand 2 "const128_operand" ""))
20170                  (const_string "1")
20171               ]
20172               (const_string "*")))
20173    (set_attr "mode" "DI")])
20174
20175 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20176   [(set (match_operand:DI 0 "register_operand" "=r,r")
20177         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20178                  (match_operand:DI 3 "immediate_operand" "i,i")))
20179    (use (match_operand:DI 2 "register_operand" "r,r"))
20180    (clobber (reg:CC FLAGS_REG))
20181    (clobber (mem:BLK (scratch)))]
20182   "TARGET_64BIT"
20183 {
20184   switch (get_attr_type (insn))
20185     {
20186     case TYPE_ALU:
20187       return "add{q}\t{%2, %0|%0, %2}";
20188
20189     case TYPE_LEA:
20190       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20191       return "lea{q}\t{%a2, %0|%0, %a2}";
20192
20193     default:
20194       gcc_unreachable ();
20195     }
20196 }
20197   [(set_attr "type" "alu,lea")
20198    (set_attr "mode" "DI")])
20199
20200 (define_insn "allocate_stack_worker_32"
20201   [(set (match_operand:SI 0 "register_operand" "=a")
20202         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20203                             UNSPECV_STACK_PROBE))
20204    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20205    (clobber (reg:CC FLAGS_REG))]
20206   "!TARGET_64BIT && TARGET_STACK_PROBE"
20207   "call\t___chkstk"
20208   [(set_attr "type" "multi")
20209    (set_attr "length" "5")])
20210
20211 (define_insn "allocate_stack_worker_64"
20212   [(set (match_operand:DI 0 "register_operand" "=a")
20213         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20214                             UNSPECV_STACK_PROBE))
20215    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20216    (clobber (reg:DI R10_REG))
20217    (clobber (reg:DI R11_REG))
20218    (clobber (reg:CC FLAGS_REG))]
20219   "TARGET_64BIT && TARGET_STACK_PROBE"
20220   "call\t___chkstk"
20221   [(set_attr "type" "multi")
20222    (set_attr "length" "5")])
20223
20224 (define_expand "allocate_stack"
20225   [(match_operand 0 "register_operand" "")
20226    (match_operand 1 "general_operand" "")]
20227   "TARGET_STACK_PROBE"
20228 {
20229   rtx x;
20230
20231 #ifndef CHECK_STACK_LIMIT
20232 #define CHECK_STACK_LIMIT 0
20233 #endif
20234
20235   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20236       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20237     {
20238       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20239                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20240       if (x != stack_pointer_rtx)
20241         emit_move_insn (stack_pointer_rtx, x);
20242     }
20243   else
20244     {
20245       x = copy_to_mode_reg (Pmode, operands[1]);
20246       if (TARGET_64BIT)
20247         x = gen_allocate_stack_worker_64 (x, x);
20248       else
20249         x = gen_allocate_stack_worker_32 (x, x);
20250       emit_insn (x);
20251     }
20252
20253   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20254   DONE;
20255 })
20256
20257 (define_expand "builtin_setjmp_receiver"
20258   [(label_ref (match_operand 0 "" ""))]
20259   "!TARGET_64BIT && flag_pic"
20260 {
20261 #if TARGET_MACHO
20262   if (TARGET_MACHO)
20263     {
20264       rtx xops[3];
20265       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20266       rtx label_rtx = gen_label_rtx ();
20267       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20268       xops[0] = xops[1] = picreg;
20269       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20270       ix86_expand_binary_operator (MINUS, SImode, xops);
20271     }
20272   else
20273 #endif
20274     emit_insn (gen_set_got (pic_offset_table_rtx));
20275   DONE;
20276 })
20277 \f
20278 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20279
20280 (define_split
20281   [(set (match_operand 0 "register_operand" "")
20282         (match_operator 3 "promotable_binary_operator"
20283            [(match_operand 1 "register_operand" "")
20284             (match_operand 2 "aligned_operand" "")]))
20285    (clobber (reg:CC FLAGS_REG))]
20286   "! TARGET_PARTIAL_REG_STALL && reload_completed
20287    && ((GET_MODE (operands[0]) == HImode
20288         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20289             /* ??? next two lines just !satisfies_constraint_K (...) */
20290             || !CONST_INT_P (operands[2])
20291             || satisfies_constraint_K (operands[2])))
20292        || (GET_MODE (operands[0]) == QImode
20293            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20294   [(parallel [(set (match_dup 0)
20295                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20296               (clobber (reg:CC FLAGS_REG))])]
20297   "operands[0] = gen_lowpart (SImode, operands[0]);
20298    operands[1] = gen_lowpart (SImode, operands[1]);
20299    if (GET_CODE (operands[3]) != ASHIFT)
20300      operands[2] = gen_lowpart (SImode, operands[2]);
20301    PUT_MODE (operands[3], SImode);")
20302
20303 ; Promote the QImode tests, as i386 has encoding of the AND
20304 ; instruction with 32-bit sign-extended immediate and thus the
20305 ; instruction size is unchanged, except in the %eax case for
20306 ; which it is increased by one byte, hence the ! optimize_size.
20307 (define_split
20308   [(set (match_operand 0 "flags_reg_operand" "")
20309         (match_operator 2 "compare_operator"
20310           [(and (match_operand 3 "aligned_operand" "")
20311                 (match_operand 4 "const_int_operand" ""))
20312            (const_int 0)]))
20313    (set (match_operand 1 "register_operand" "")
20314         (and (match_dup 3) (match_dup 4)))]
20315   "! TARGET_PARTIAL_REG_STALL && reload_completed
20316    && optimize_insn_for_speed_p ()
20317    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20318        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20319    /* Ensure that the operand will remain sign-extended immediate.  */
20320    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20321   [(parallel [(set (match_dup 0)
20322                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20323                                     (const_int 0)]))
20324               (set (match_dup 1)
20325                    (and:SI (match_dup 3) (match_dup 4)))])]
20326 {
20327   operands[4]
20328     = gen_int_mode (INTVAL (operands[4])
20329                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20330   operands[1] = gen_lowpart (SImode, operands[1]);
20331   operands[3] = gen_lowpart (SImode, operands[3]);
20332 })
20333
20334 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20335 ; the TEST instruction with 32-bit sign-extended immediate and thus
20336 ; the instruction size would at least double, which is not what we
20337 ; want even with ! optimize_size.
20338 (define_split
20339   [(set (match_operand 0 "flags_reg_operand" "")
20340         (match_operator 1 "compare_operator"
20341           [(and (match_operand:HI 2 "aligned_operand" "")
20342                 (match_operand:HI 3 "const_int_operand" ""))
20343            (const_int 0)]))]
20344   "! TARGET_PARTIAL_REG_STALL && reload_completed
20345    && ! TARGET_FAST_PREFIX
20346    && optimize_insn_for_speed_p ()
20347    /* Ensure that the operand will remain sign-extended immediate.  */
20348    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20349   [(set (match_dup 0)
20350         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20351                          (const_int 0)]))]
20352 {
20353   operands[3]
20354     = gen_int_mode (INTVAL (operands[3])
20355                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20356   operands[2] = gen_lowpart (SImode, operands[2]);
20357 })
20358
20359 (define_split
20360   [(set (match_operand 0 "register_operand" "")
20361         (neg (match_operand 1 "register_operand" "")))
20362    (clobber (reg:CC FLAGS_REG))]
20363   "! TARGET_PARTIAL_REG_STALL && reload_completed
20364    && (GET_MODE (operands[0]) == HImode
20365        || (GET_MODE (operands[0]) == QImode
20366            && (TARGET_PROMOTE_QImode
20367                || optimize_insn_for_size_p ())))"
20368   [(parallel [(set (match_dup 0)
20369                    (neg:SI (match_dup 1)))
20370               (clobber (reg:CC FLAGS_REG))])]
20371   "operands[0] = gen_lowpart (SImode, operands[0]);
20372    operands[1] = gen_lowpart (SImode, operands[1]);")
20373
20374 (define_split
20375   [(set (match_operand 0 "register_operand" "")
20376         (not (match_operand 1 "register_operand" "")))]
20377   "! TARGET_PARTIAL_REG_STALL && reload_completed
20378    && (GET_MODE (operands[0]) == HImode
20379        || (GET_MODE (operands[0]) == QImode
20380            && (TARGET_PROMOTE_QImode
20381                || optimize_insn_for_size_p ())))"
20382   [(set (match_dup 0)
20383         (not:SI (match_dup 1)))]
20384   "operands[0] = gen_lowpart (SImode, operands[0]);
20385    operands[1] = gen_lowpart (SImode, operands[1]);")
20386
20387 (define_split
20388   [(set (match_operand 0 "register_operand" "")
20389         (if_then_else (match_operator 1 "comparison_operator"
20390                                 [(reg FLAGS_REG) (const_int 0)])
20391                       (match_operand 2 "register_operand" "")
20392                       (match_operand 3 "register_operand" "")))]
20393   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20394    && (GET_MODE (operands[0]) == HImode
20395        || (GET_MODE (operands[0]) == QImode
20396            && (TARGET_PROMOTE_QImode
20397                || optimize_insn_for_size_p ())))"
20398   [(set (match_dup 0)
20399         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20400   "operands[0] = gen_lowpart (SImode, operands[0]);
20401    operands[2] = gen_lowpart (SImode, operands[2]);
20402    operands[3] = gen_lowpart (SImode, operands[3]);")
20403
20404 \f
20405 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20406 ;; transform a complex memory operation into two memory to register operations.
20407
20408 ;; Don't push memory operands
20409 (define_peephole2
20410   [(set (match_operand:SI 0 "push_operand" "")
20411         (match_operand:SI 1 "memory_operand" ""))
20412    (match_scratch:SI 2 "r")]
20413   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20414    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20415   [(set (match_dup 2) (match_dup 1))
20416    (set (match_dup 0) (match_dup 2))]
20417   "")
20418
20419 (define_peephole2
20420   [(set (match_operand:DI 0 "push_operand" "")
20421         (match_operand:DI 1 "memory_operand" ""))
20422    (match_scratch:DI 2 "r")]
20423   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20424    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20425   [(set (match_dup 2) (match_dup 1))
20426    (set (match_dup 0) (match_dup 2))]
20427   "")
20428
20429 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20430 ;; SImode pushes.
20431 (define_peephole2
20432   [(set (match_operand:SF 0 "push_operand" "")
20433         (match_operand:SF 1 "memory_operand" ""))
20434    (match_scratch:SF 2 "r")]
20435   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20436    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20437   [(set (match_dup 2) (match_dup 1))
20438    (set (match_dup 0) (match_dup 2))]
20439   "")
20440
20441 (define_peephole2
20442   [(set (match_operand:HI 0 "push_operand" "")
20443         (match_operand:HI 1 "memory_operand" ""))
20444    (match_scratch:HI 2 "r")]
20445   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20446    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20447   [(set (match_dup 2) (match_dup 1))
20448    (set (match_dup 0) (match_dup 2))]
20449   "")
20450
20451 (define_peephole2
20452   [(set (match_operand:QI 0 "push_operand" "")
20453         (match_operand:QI 1 "memory_operand" ""))
20454    (match_scratch:QI 2 "q")]
20455   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20456    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20457   [(set (match_dup 2) (match_dup 1))
20458    (set (match_dup 0) (match_dup 2))]
20459   "")
20460
20461 ;; Don't move an immediate directly to memory when the instruction
20462 ;; gets too big.
20463 (define_peephole2
20464   [(match_scratch:SI 1 "r")
20465    (set (match_operand:SI 0 "memory_operand" "")
20466         (const_int 0))]
20467   "optimize_insn_for_speed_p ()
20468    && ! TARGET_USE_MOV0
20469    && TARGET_SPLIT_LONG_MOVES
20470    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20471    && peep2_regno_dead_p (0, FLAGS_REG)"
20472   [(parallel [(set (match_dup 1) (const_int 0))
20473               (clobber (reg:CC FLAGS_REG))])
20474    (set (match_dup 0) (match_dup 1))]
20475   "")
20476
20477 (define_peephole2
20478   [(match_scratch:HI 1 "r")
20479    (set (match_operand:HI 0 "memory_operand" "")
20480         (const_int 0))]
20481   "optimize_insn_for_speed_p ()
20482    && ! TARGET_USE_MOV0
20483    && TARGET_SPLIT_LONG_MOVES
20484    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20485    && peep2_regno_dead_p (0, FLAGS_REG)"
20486   [(parallel [(set (match_dup 2) (const_int 0))
20487               (clobber (reg:CC FLAGS_REG))])
20488    (set (match_dup 0) (match_dup 1))]
20489   "operands[2] = gen_lowpart (SImode, operands[1]);")
20490
20491 (define_peephole2
20492   [(match_scratch:QI 1 "q")
20493    (set (match_operand:QI 0 "memory_operand" "")
20494         (const_int 0))]
20495   "optimize_insn_for_speed_p ()
20496    && ! TARGET_USE_MOV0
20497    && TARGET_SPLIT_LONG_MOVES
20498    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20499    && peep2_regno_dead_p (0, FLAGS_REG)"
20500   [(parallel [(set (match_dup 2) (const_int 0))
20501               (clobber (reg:CC FLAGS_REG))])
20502    (set (match_dup 0) (match_dup 1))]
20503   "operands[2] = gen_lowpart (SImode, operands[1]);")
20504
20505 (define_peephole2
20506   [(match_scratch:SI 2 "r")
20507    (set (match_operand:SI 0 "memory_operand" "")
20508         (match_operand:SI 1 "immediate_operand" ""))]
20509   "optimize_insn_for_speed_p ()
20510    && TARGET_SPLIT_LONG_MOVES
20511    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20512   [(set (match_dup 2) (match_dup 1))
20513    (set (match_dup 0) (match_dup 2))]
20514   "")
20515
20516 (define_peephole2
20517   [(match_scratch:HI 2 "r")
20518    (set (match_operand:HI 0 "memory_operand" "")
20519         (match_operand:HI 1 "immediate_operand" ""))]
20520   "optimize_insn_for_speed_p ()
20521    && TARGET_SPLIT_LONG_MOVES
20522    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20523   [(set (match_dup 2) (match_dup 1))
20524    (set (match_dup 0) (match_dup 2))]
20525   "")
20526
20527 (define_peephole2
20528   [(match_scratch:QI 2 "q")
20529    (set (match_operand:QI 0 "memory_operand" "")
20530         (match_operand:QI 1 "immediate_operand" ""))]
20531   "optimize_insn_for_speed_p ()
20532    && TARGET_SPLIT_LONG_MOVES
20533    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20534   [(set (match_dup 2) (match_dup 1))
20535    (set (match_dup 0) (match_dup 2))]
20536   "")
20537
20538 ;; Don't compare memory with zero, load and use a test instead.
20539 (define_peephole2
20540   [(set (match_operand 0 "flags_reg_operand" "")
20541         (match_operator 1 "compare_operator"
20542           [(match_operand:SI 2 "memory_operand" "")
20543            (const_int 0)]))
20544    (match_scratch:SI 3 "r")]
20545   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20546   [(set (match_dup 3) (match_dup 2))
20547    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20548   "")
20549
20550 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20551 ;; Don't split NOTs with a displacement operand, because resulting XOR
20552 ;; will not be pairable anyway.
20553 ;;
20554 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20555 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20556 ;; so this split helps here as well.
20557 ;;
20558 ;; Note: Can't do this as a regular split because we can't get proper
20559 ;; lifetime information then.
20560
20561 (define_peephole2
20562   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20563         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20564   "optimize_insn_for_speed_p ()
20565    && ((TARGET_NOT_UNPAIRABLE
20566         && (!MEM_P (operands[0])
20567             || !memory_displacement_operand (operands[0], SImode)))
20568        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20569    && peep2_regno_dead_p (0, FLAGS_REG)"
20570   [(parallel [(set (match_dup 0)
20571                    (xor:SI (match_dup 1) (const_int -1)))
20572               (clobber (reg:CC FLAGS_REG))])]
20573   "")
20574
20575 (define_peephole2
20576   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20577         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20578   "optimize_insn_for_speed_p ()
20579    && ((TARGET_NOT_UNPAIRABLE
20580         && (!MEM_P (operands[0])
20581             || !memory_displacement_operand (operands[0], HImode)))
20582        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20583    && peep2_regno_dead_p (0, FLAGS_REG)"
20584   [(parallel [(set (match_dup 0)
20585                    (xor:HI (match_dup 1) (const_int -1)))
20586               (clobber (reg:CC FLAGS_REG))])]
20587   "")
20588
20589 (define_peephole2
20590   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20591         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20592   "optimize_insn_for_speed_p ()
20593    && ((TARGET_NOT_UNPAIRABLE
20594         && (!MEM_P (operands[0])
20595             || !memory_displacement_operand (operands[0], QImode)))
20596        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20597    && peep2_regno_dead_p (0, FLAGS_REG)"
20598   [(parallel [(set (match_dup 0)
20599                    (xor:QI (match_dup 1) (const_int -1)))
20600               (clobber (reg:CC FLAGS_REG))])]
20601   "")
20602
20603 ;; Non pairable "test imm, reg" instructions can be translated to
20604 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20605 ;; byte opcode instead of two, have a short form for byte operands),
20606 ;; so do it for other CPUs as well.  Given that the value was dead,
20607 ;; this should not create any new dependencies.  Pass on the sub-word
20608 ;; versions if we're concerned about partial register stalls.
20609
20610 (define_peephole2
20611   [(set (match_operand 0 "flags_reg_operand" "")
20612         (match_operator 1 "compare_operator"
20613           [(and:SI (match_operand:SI 2 "register_operand" "")
20614                    (match_operand:SI 3 "immediate_operand" ""))
20615            (const_int 0)]))]
20616   "ix86_match_ccmode (insn, CCNOmode)
20617    && (true_regnum (operands[2]) != AX_REG
20618        || satisfies_constraint_K (operands[3]))
20619    && peep2_reg_dead_p (1, operands[2])"
20620   [(parallel
20621      [(set (match_dup 0)
20622            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20623                             (const_int 0)]))
20624       (set (match_dup 2)
20625            (and:SI (match_dup 2) (match_dup 3)))])]
20626   "")
20627
20628 ;; We don't need to handle HImode case, because it will be promoted to SImode
20629 ;; on ! TARGET_PARTIAL_REG_STALL
20630
20631 (define_peephole2
20632   [(set (match_operand 0 "flags_reg_operand" "")
20633         (match_operator 1 "compare_operator"
20634           [(and:QI (match_operand:QI 2 "register_operand" "")
20635                    (match_operand:QI 3 "immediate_operand" ""))
20636            (const_int 0)]))]
20637   "! TARGET_PARTIAL_REG_STALL
20638    && ix86_match_ccmode (insn, CCNOmode)
20639    && true_regnum (operands[2]) != AX_REG
20640    && peep2_reg_dead_p (1, operands[2])"
20641   [(parallel
20642      [(set (match_dup 0)
20643            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20644                             (const_int 0)]))
20645       (set (match_dup 2)
20646            (and:QI (match_dup 2) (match_dup 3)))])]
20647   "")
20648
20649 (define_peephole2
20650   [(set (match_operand 0 "flags_reg_operand" "")
20651         (match_operator 1 "compare_operator"
20652           [(and:SI
20653              (zero_extract:SI
20654                (match_operand 2 "ext_register_operand" "")
20655                (const_int 8)
20656                (const_int 8))
20657              (match_operand 3 "const_int_operand" ""))
20658            (const_int 0)]))]
20659   "! TARGET_PARTIAL_REG_STALL
20660    && ix86_match_ccmode (insn, CCNOmode)
20661    && true_regnum (operands[2]) != AX_REG
20662    && peep2_reg_dead_p (1, operands[2])"
20663   [(parallel [(set (match_dup 0)
20664                    (match_op_dup 1
20665                      [(and:SI
20666                         (zero_extract:SI
20667                           (match_dup 2)
20668                           (const_int 8)
20669                           (const_int 8))
20670                         (match_dup 3))
20671                       (const_int 0)]))
20672               (set (zero_extract:SI (match_dup 2)
20673                                     (const_int 8)
20674                                     (const_int 8))
20675                    (and:SI
20676                      (zero_extract:SI
20677                        (match_dup 2)
20678                        (const_int 8)
20679                        (const_int 8))
20680                      (match_dup 3)))])]
20681   "")
20682
20683 ;; Don't do logical operations with memory inputs.
20684 (define_peephole2
20685   [(match_scratch:SI 2 "r")
20686    (parallel [(set (match_operand:SI 0 "register_operand" "")
20687                    (match_operator:SI 3 "arith_or_logical_operator"
20688                      [(match_dup 0)
20689                       (match_operand:SI 1 "memory_operand" "")]))
20690               (clobber (reg:CC FLAGS_REG))])]
20691   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20692   [(set (match_dup 2) (match_dup 1))
20693    (parallel [(set (match_dup 0)
20694                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20695               (clobber (reg:CC FLAGS_REG))])]
20696   "")
20697
20698 (define_peephole2
20699   [(match_scratch:SI 2 "r")
20700    (parallel [(set (match_operand:SI 0 "register_operand" "")
20701                    (match_operator:SI 3 "arith_or_logical_operator"
20702                      [(match_operand:SI 1 "memory_operand" "")
20703                       (match_dup 0)]))
20704               (clobber (reg:CC FLAGS_REG))])]
20705   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20706   [(set (match_dup 2) (match_dup 1))
20707    (parallel [(set (match_dup 0)
20708                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20709               (clobber (reg:CC FLAGS_REG))])]
20710   "")
20711
20712 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20713 ;; refers to the destination of the load!
20714
20715 (define_peephole2
20716   [(set (match_operand:SI 0 "register_operand" "")
20717         (match_operand:SI 1 "register_operand" ""))
20718    (parallel [(set (match_dup 0)
20719                    (match_operator:SI 3 "commutative_operator"
20720                      [(match_dup 0)
20721                       (match_operand:SI 2 "memory_operand" "")]))
20722               (clobber (reg:CC FLAGS_REG))])]
20723   "REGNO (operands[0]) != REGNO (operands[1])
20724    && GENERAL_REGNO_P (REGNO (operands[0]))
20725    && GENERAL_REGNO_P (REGNO (operands[1]))"
20726   [(set (match_dup 0) (match_dup 4))
20727    (parallel [(set (match_dup 0)
20728                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20729               (clobber (reg:CC FLAGS_REG))])]
20730   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20731
20732 (define_peephole2
20733   [(set (match_operand 0 "register_operand" "")
20734         (match_operand 1 "register_operand" ""))
20735    (set (match_dup 0)
20736                    (match_operator 3 "commutative_operator"
20737                      [(match_dup 0)
20738                       (match_operand 2 "memory_operand" "")]))]
20739   "REGNO (operands[0]) != REGNO (operands[1])
20740    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20741        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20742   [(set (match_dup 0) (match_dup 2))
20743    (set (match_dup 0)
20744         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20745   "")
20746
20747 ; Don't do logical operations with memory outputs
20748 ;
20749 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20750 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20751 ; the same decoder scheduling characteristics as the original.
20752
20753 (define_peephole2
20754   [(match_scratch:SI 2 "r")
20755    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20756                    (match_operator:SI 3 "arith_or_logical_operator"
20757                      [(match_dup 0)
20758                       (match_operand:SI 1 "nonmemory_operand" "")]))
20759               (clobber (reg:CC FLAGS_REG))])]
20760   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20761   [(set (match_dup 2) (match_dup 0))
20762    (parallel [(set (match_dup 2)
20763                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20764               (clobber (reg:CC FLAGS_REG))])
20765    (set (match_dup 0) (match_dup 2))]
20766   "")
20767
20768 (define_peephole2
20769   [(match_scratch:SI 2 "r")
20770    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20771                    (match_operator:SI 3 "arith_or_logical_operator"
20772                      [(match_operand:SI 1 "nonmemory_operand" "")
20773                       (match_dup 0)]))
20774               (clobber (reg:CC FLAGS_REG))])]
20775   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20776   [(set (match_dup 2) (match_dup 0))
20777    (parallel [(set (match_dup 2)
20778                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20779               (clobber (reg:CC FLAGS_REG))])
20780    (set (match_dup 0) (match_dup 2))]
20781   "")
20782
20783 ;; Attempt to always use XOR for zeroing registers.
20784 (define_peephole2
20785   [(set (match_operand 0 "register_operand" "")
20786         (match_operand 1 "const0_operand" ""))]
20787   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20788    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20789    && GENERAL_REG_P (operands[0])
20790    && peep2_regno_dead_p (0, FLAGS_REG)"
20791   [(parallel [(set (match_dup 0) (const_int 0))
20792               (clobber (reg:CC FLAGS_REG))])]
20793 {
20794   operands[0] = gen_lowpart (word_mode, operands[0]);
20795 })
20796
20797 (define_peephole2
20798   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20799         (const_int 0))]
20800   "(GET_MODE (operands[0]) == QImode
20801     || GET_MODE (operands[0]) == HImode)
20802    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20803    && peep2_regno_dead_p (0, FLAGS_REG)"
20804   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20805               (clobber (reg:CC FLAGS_REG))])])
20806
20807 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20808 (define_peephole2
20809   [(set (match_operand 0 "register_operand" "")
20810         (const_int -1))]
20811   "(GET_MODE (operands[0]) == HImode
20812     || GET_MODE (operands[0]) == SImode
20813     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20814    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20815    && peep2_regno_dead_p (0, FLAGS_REG)"
20816   [(parallel [(set (match_dup 0) (const_int -1))
20817               (clobber (reg:CC FLAGS_REG))])]
20818   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20819                               operands[0]);")
20820
20821 ;; Attempt to convert simple leas to adds. These can be created by
20822 ;; move expanders.
20823 (define_peephole2
20824   [(set (match_operand:SI 0 "register_operand" "")
20825         (plus:SI (match_dup 0)
20826                  (match_operand:SI 1 "nonmemory_operand" "")))]
20827   "peep2_regno_dead_p (0, FLAGS_REG)"
20828   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20829               (clobber (reg:CC FLAGS_REG))])]
20830   "")
20831
20832 (define_peephole2
20833   [(set (match_operand:SI 0 "register_operand" "")
20834         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20835                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20836   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20837   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20838               (clobber (reg:CC FLAGS_REG))])]
20839   "operands[2] = gen_lowpart (SImode, operands[2]);")
20840
20841 (define_peephole2
20842   [(set (match_operand:DI 0 "register_operand" "")
20843         (plus:DI (match_dup 0)
20844                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20845   "peep2_regno_dead_p (0, FLAGS_REG)"
20846   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20847               (clobber (reg:CC FLAGS_REG))])]
20848   "")
20849
20850 (define_peephole2
20851   [(set (match_operand:SI 0 "register_operand" "")
20852         (mult:SI (match_dup 0)
20853                  (match_operand:SI 1 "const_int_operand" "")))]
20854   "exact_log2 (INTVAL (operands[1])) >= 0
20855    && peep2_regno_dead_p (0, FLAGS_REG)"
20856   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20857               (clobber (reg:CC FLAGS_REG))])]
20858   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20859
20860 (define_peephole2
20861   [(set (match_operand:DI 0 "register_operand" "")
20862         (mult:DI (match_dup 0)
20863                  (match_operand:DI 1 "const_int_operand" "")))]
20864   "exact_log2 (INTVAL (operands[1])) >= 0
20865    && peep2_regno_dead_p (0, FLAGS_REG)"
20866   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20867               (clobber (reg:CC FLAGS_REG))])]
20868   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20869
20870 (define_peephole2
20871   [(set (match_operand:SI 0 "register_operand" "")
20872         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20873                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20874   "exact_log2 (INTVAL (operands[2])) >= 0
20875    && REGNO (operands[0]) == REGNO (operands[1])
20876    && peep2_regno_dead_p (0, FLAGS_REG)"
20877   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20878               (clobber (reg:CC FLAGS_REG))])]
20879   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20880
20881 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20882 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20883 ;; many CPUs it is also faster, since special hardware to avoid esp
20884 ;; dependencies is present.
20885
20886 ;; While some of these conversions may be done using splitters, we use peepholes
20887 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20888
20889 ;; Convert prologue esp subtractions to push.
20890 ;; We need register to push.  In order to keep verify_flow_info happy we have
20891 ;; two choices
20892 ;; - use scratch and clobber it in order to avoid dependencies
20893 ;; - use already live register
20894 ;; We can't use the second way right now, since there is no reliable way how to
20895 ;; verify that given register is live.  First choice will also most likely in
20896 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20897 ;; call clobbered registers are dead.  We may want to use base pointer as an
20898 ;; alternative when no register is available later.
20899
20900 (define_peephole2
20901   [(match_scratch:SI 0 "r")
20902    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20903               (clobber (reg:CC FLAGS_REG))
20904               (clobber (mem:BLK (scratch)))])]
20905   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20906   [(clobber (match_dup 0))
20907    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20908               (clobber (mem:BLK (scratch)))])])
20909
20910 (define_peephole2
20911   [(match_scratch:SI 0 "r")
20912    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20913               (clobber (reg:CC FLAGS_REG))
20914               (clobber (mem:BLK (scratch)))])]
20915   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20916   [(clobber (match_dup 0))
20917    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20918    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20919               (clobber (mem:BLK (scratch)))])])
20920
20921 ;; Convert esp subtractions to push.
20922 (define_peephole2
20923   [(match_scratch:SI 0 "r")
20924    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20925               (clobber (reg:CC FLAGS_REG))])]
20926   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20927   [(clobber (match_dup 0))
20928    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20929
20930 (define_peephole2
20931   [(match_scratch:SI 0 "r")
20932    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20933               (clobber (reg:CC FLAGS_REG))])]
20934   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20935   [(clobber (match_dup 0))
20936    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20937    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20938
20939 ;; Convert epilogue deallocator to pop.
20940 (define_peephole2
20941   [(match_scratch:SI 0 "r")
20942    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20943               (clobber (reg:CC FLAGS_REG))
20944               (clobber (mem:BLK (scratch)))])]
20945   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20946   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20947               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20948               (clobber (mem:BLK (scratch)))])]
20949   "")
20950
20951 ;; Two pops case is tricky, since pop causes dependency on destination register.
20952 ;; We use two registers if available.
20953 (define_peephole2
20954   [(match_scratch:SI 0 "r")
20955    (match_scratch:SI 1 "r")
20956    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20957               (clobber (reg:CC FLAGS_REG))
20958               (clobber (mem:BLK (scratch)))])]
20959   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20960   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20961               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20962               (clobber (mem:BLK (scratch)))])
20963    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20964               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20965   "")
20966
20967 (define_peephole2
20968   [(match_scratch:SI 0 "r")
20969    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20970               (clobber (reg:CC FLAGS_REG))
20971               (clobber (mem:BLK (scratch)))])]
20972   "optimize_insn_for_size_p ()"
20973   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20974               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20975               (clobber (mem:BLK (scratch)))])
20976    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20977               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20978   "")
20979
20980 ;; Convert esp additions to pop.
20981 (define_peephole2
20982   [(match_scratch:SI 0 "r")
20983    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20984               (clobber (reg:CC FLAGS_REG))])]
20985   ""
20986   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20987               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20988   "")
20989
20990 ;; Two pops case is tricky, since pop causes dependency on destination register.
20991 ;; We use two registers if available.
20992 (define_peephole2
20993   [(match_scratch:SI 0 "r")
20994    (match_scratch:SI 1 "r")
20995    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20996               (clobber (reg:CC FLAGS_REG))])]
20997   ""
20998   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20999               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21000    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21001               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21002   "")
21003
21004 (define_peephole2
21005   [(match_scratch:SI 0 "r")
21006    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21007               (clobber (reg:CC FLAGS_REG))])]
21008   "optimize_insn_for_size_p ()"
21009   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21010               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21011    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21012               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21013   "")
21014 \f
21015 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21016 ;; required and register dies.  Similarly for 128 to -128.
21017 (define_peephole2
21018   [(set (match_operand 0 "flags_reg_operand" "")
21019         (match_operator 1 "compare_operator"
21020           [(match_operand 2 "register_operand" "")
21021            (match_operand 3 "const_int_operand" "")]))]
21022   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21023      && incdec_operand (operands[3], GET_MODE (operands[3])))
21024     || (!TARGET_FUSE_CMP_AND_BRANCH
21025         && INTVAL (operands[3]) == 128))
21026    && ix86_match_ccmode (insn, CCGCmode)
21027    && peep2_reg_dead_p (1, operands[2])"
21028   [(parallel [(set (match_dup 0)
21029                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21030               (clobber (match_dup 2))])]
21031   "")
21032 \f
21033 (define_peephole2
21034   [(match_scratch:DI 0 "r")
21035    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21036               (clobber (reg:CC FLAGS_REG))
21037               (clobber (mem:BLK (scratch)))])]
21038   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21039   [(clobber (match_dup 0))
21040    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21041               (clobber (mem:BLK (scratch)))])])
21042
21043 (define_peephole2
21044   [(match_scratch:DI 0 "r")
21045    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21046               (clobber (reg:CC FLAGS_REG))
21047               (clobber (mem:BLK (scratch)))])]
21048   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21049   [(clobber (match_dup 0))
21050    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21051    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21052               (clobber (mem:BLK (scratch)))])])
21053
21054 ;; Convert esp subtractions to push.
21055 (define_peephole2
21056   [(match_scratch:DI 0 "r")
21057    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21058               (clobber (reg:CC FLAGS_REG))])]
21059   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21060   [(clobber (match_dup 0))
21061    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21062
21063 (define_peephole2
21064   [(match_scratch:DI 0 "r")
21065    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21066               (clobber (reg:CC FLAGS_REG))])]
21067   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21068   [(clobber (match_dup 0))
21069    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21070    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21071
21072 ;; Convert epilogue deallocator to pop.
21073 (define_peephole2
21074   [(match_scratch:DI 0 "r")
21075    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21076               (clobber (reg:CC FLAGS_REG))
21077               (clobber (mem:BLK (scratch)))])]
21078   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21079   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21080               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21081               (clobber (mem:BLK (scratch)))])]
21082   "")
21083
21084 ;; Two pops case is tricky, since pop causes dependency on destination register.
21085 ;; We use two registers if available.
21086 (define_peephole2
21087   [(match_scratch:DI 0 "r")
21088    (match_scratch:DI 1 "r")
21089    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21090               (clobber (reg:CC FLAGS_REG))
21091               (clobber (mem:BLK (scratch)))])]
21092   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21093   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21094               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21095               (clobber (mem:BLK (scratch)))])
21096    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21097               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21098   "")
21099
21100 (define_peephole2
21101   [(match_scratch:DI 0 "r")
21102    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21103               (clobber (reg:CC FLAGS_REG))
21104               (clobber (mem:BLK (scratch)))])]
21105   "optimize_insn_for_size_p ()"
21106   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21107               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21108               (clobber (mem:BLK (scratch)))])
21109    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21110               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21111   "")
21112
21113 ;; Convert esp additions to pop.
21114 (define_peephole2
21115   [(match_scratch:DI 0 "r")
21116    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21117               (clobber (reg:CC FLAGS_REG))])]
21118   ""
21119   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21120               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21121   "")
21122
21123 ;; Two pops case is tricky, since pop causes dependency on destination register.
21124 ;; We use two registers if available.
21125 (define_peephole2
21126   [(match_scratch:DI 0 "r")
21127    (match_scratch:DI 1 "r")
21128    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21129               (clobber (reg:CC FLAGS_REG))])]
21130   ""
21131   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21132               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21133    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21134               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21135   "")
21136
21137 (define_peephole2
21138   [(match_scratch:DI 0 "r")
21139    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21140               (clobber (reg:CC FLAGS_REG))])]
21141   "optimize_insn_for_size_p ()"
21142   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21143               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21144    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21145               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21146   "")
21147 \f
21148 ;; Convert imul by three, five and nine into lea
21149 (define_peephole2
21150   [(parallel
21151     [(set (match_operand:SI 0 "register_operand" "")
21152           (mult:SI (match_operand:SI 1 "register_operand" "")
21153                    (match_operand:SI 2 "const_int_operand" "")))
21154      (clobber (reg:CC FLAGS_REG))])]
21155   "INTVAL (operands[2]) == 3
21156    || INTVAL (operands[2]) == 5
21157    || INTVAL (operands[2]) == 9"
21158   [(set (match_dup 0)
21159         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21160                  (match_dup 1)))]
21161   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21162
21163 (define_peephole2
21164   [(parallel
21165     [(set (match_operand:SI 0 "register_operand" "")
21166           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21167                    (match_operand:SI 2 "const_int_operand" "")))
21168      (clobber (reg:CC FLAGS_REG))])]
21169   "optimize_insn_for_speed_p ()
21170    && (INTVAL (operands[2]) == 3
21171        || INTVAL (operands[2]) == 5
21172        || INTVAL (operands[2]) == 9)"
21173   [(set (match_dup 0) (match_dup 1))
21174    (set (match_dup 0)
21175         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21176                  (match_dup 0)))]
21177   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21178
21179 (define_peephole2
21180   [(parallel
21181     [(set (match_operand:DI 0 "register_operand" "")
21182           (mult:DI (match_operand:DI 1 "register_operand" "")
21183                    (match_operand:DI 2 "const_int_operand" "")))
21184      (clobber (reg:CC FLAGS_REG))])]
21185   "TARGET_64BIT
21186    && (INTVAL (operands[2]) == 3
21187        || INTVAL (operands[2]) == 5
21188        || INTVAL (operands[2]) == 9)"
21189   [(set (match_dup 0)
21190         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21191                  (match_dup 1)))]
21192   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21193
21194 (define_peephole2
21195   [(parallel
21196     [(set (match_operand:DI 0 "register_operand" "")
21197           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21198                    (match_operand:DI 2 "const_int_operand" "")))
21199      (clobber (reg:CC FLAGS_REG))])]
21200   "TARGET_64BIT
21201    && optimize_insn_for_speed_p ()
21202    && (INTVAL (operands[2]) == 3
21203        || INTVAL (operands[2]) == 5
21204        || INTVAL (operands[2]) == 9)"
21205   [(set (match_dup 0) (match_dup 1))
21206    (set (match_dup 0)
21207         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21208                  (match_dup 0)))]
21209   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21210
21211 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21212 ;; imul $32bit_imm, reg, reg is direct decoded.
21213 (define_peephole2
21214   [(match_scratch:DI 3 "r")
21215    (parallel [(set (match_operand:DI 0 "register_operand" "")
21216                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21217                             (match_operand:DI 2 "immediate_operand" "")))
21218               (clobber (reg:CC FLAGS_REG))])]
21219   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21220    && !satisfies_constraint_K (operands[2])"
21221   [(set (match_dup 3) (match_dup 1))
21222    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21223               (clobber (reg:CC FLAGS_REG))])]
21224 "")
21225
21226 (define_peephole2
21227   [(match_scratch:SI 3 "r")
21228    (parallel [(set (match_operand:SI 0 "register_operand" "")
21229                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21230                             (match_operand:SI 2 "immediate_operand" "")))
21231               (clobber (reg:CC FLAGS_REG))])]
21232   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21233    && !satisfies_constraint_K (operands[2])"
21234   [(set (match_dup 3) (match_dup 1))
21235    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21236               (clobber (reg:CC FLAGS_REG))])]
21237 "")
21238
21239 (define_peephole2
21240   [(match_scratch:SI 3 "r")
21241    (parallel [(set (match_operand:DI 0 "register_operand" "")
21242                    (zero_extend:DI
21243                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21244                               (match_operand:SI 2 "immediate_operand" ""))))
21245               (clobber (reg:CC FLAGS_REG))])]
21246   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21247    && !satisfies_constraint_K (operands[2])"
21248   [(set (match_dup 3) (match_dup 1))
21249    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21250               (clobber (reg:CC FLAGS_REG))])]
21251 "")
21252
21253 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21254 ;; Convert it into imul reg, reg
21255 ;; It would be better to force assembler to encode instruction using long
21256 ;; immediate, but there is apparently no way to do so.
21257 (define_peephole2
21258   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21259                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21260                             (match_operand:DI 2 "const_int_operand" "")))
21261               (clobber (reg:CC FLAGS_REG))])
21262    (match_scratch:DI 3 "r")]
21263   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21264    && satisfies_constraint_K (operands[2])"
21265   [(set (match_dup 3) (match_dup 2))
21266    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21267               (clobber (reg:CC FLAGS_REG))])]
21268 {
21269   if (!rtx_equal_p (operands[0], operands[1]))
21270     emit_move_insn (operands[0], operands[1]);
21271 })
21272
21273 (define_peephole2
21274   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21275                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21276                             (match_operand:SI 2 "const_int_operand" "")))
21277               (clobber (reg:CC FLAGS_REG))])
21278    (match_scratch:SI 3 "r")]
21279   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21280    && satisfies_constraint_K (operands[2])"
21281   [(set (match_dup 3) (match_dup 2))
21282    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21283               (clobber (reg:CC FLAGS_REG))])]
21284 {
21285   if (!rtx_equal_p (operands[0], operands[1]))
21286     emit_move_insn (operands[0], operands[1]);
21287 })
21288
21289 (define_peephole2
21290   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21291                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21292                             (match_operand:HI 2 "immediate_operand" "")))
21293               (clobber (reg:CC FLAGS_REG))])
21294    (match_scratch:HI 3 "r")]
21295   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21296   [(set (match_dup 3) (match_dup 2))
21297    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21298               (clobber (reg:CC FLAGS_REG))])]
21299 {
21300   if (!rtx_equal_p (operands[0], operands[1]))
21301     emit_move_insn (operands[0], operands[1]);
21302 })
21303
21304 ;; After splitting up read-modify operations, array accesses with memory
21305 ;; operands might end up in form:
21306 ;;  sall    $2, %eax
21307 ;;  movl    4(%esp), %edx
21308 ;;  addl    %edx, %eax
21309 ;; instead of pre-splitting:
21310 ;;  sall    $2, %eax
21311 ;;  addl    4(%esp), %eax
21312 ;; Turn it into:
21313 ;;  movl    4(%esp), %edx
21314 ;;  leal    (%edx,%eax,4), %eax
21315
21316 (define_peephole2
21317   [(parallel [(set (match_operand 0 "register_operand" "")
21318                    (ashift (match_operand 1 "register_operand" "")
21319                            (match_operand 2 "const_int_operand" "")))
21320                (clobber (reg:CC FLAGS_REG))])
21321    (set (match_operand 3 "register_operand")
21322         (match_operand 4 "x86_64_general_operand" ""))
21323    (parallel [(set (match_operand 5 "register_operand" "")
21324                    (plus (match_operand 6 "register_operand" "")
21325                          (match_operand 7 "register_operand" "")))
21326                    (clobber (reg:CC FLAGS_REG))])]
21327   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21328    /* Validate MODE for lea.  */
21329    && ((!TARGET_PARTIAL_REG_STALL
21330         && (GET_MODE (operands[0]) == QImode
21331             || GET_MODE (operands[0]) == HImode))
21332        || GET_MODE (operands[0]) == SImode
21333        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21334    /* We reorder load and the shift.  */
21335    && !rtx_equal_p (operands[1], operands[3])
21336    && !reg_overlap_mentioned_p (operands[0], operands[4])
21337    /* Last PLUS must consist of operand 0 and 3.  */
21338    && !rtx_equal_p (operands[0], operands[3])
21339    && (rtx_equal_p (operands[3], operands[6])
21340        || rtx_equal_p (operands[3], operands[7]))
21341    && (rtx_equal_p (operands[0], operands[6])
21342        || rtx_equal_p (operands[0], operands[7]))
21343    /* The intermediate operand 0 must die or be same as output.  */
21344    && (rtx_equal_p (operands[0], operands[5])
21345        || peep2_reg_dead_p (3, operands[0]))"
21346   [(set (match_dup 3) (match_dup 4))
21347    (set (match_dup 0) (match_dup 1))]
21348 {
21349   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21350   int scale = 1 << INTVAL (operands[2]);
21351   rtx index = gen_lowpart (Pmode, operands[1]);
21352   rtx base = gen_lowpart (Pmode, operands[3]);
21353   rtx dest = gen_lowpart (mode, operands[5]);
21354
21355   operands[1] = gen_rtx_PLUS (Pmode, base,
21356                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21357   if (mode != Pmode)
21358     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21359   operands[0] = dest;
21360 })
21361 \f
21362 ;; Call-value patterns last so that the wildcard operand does not
21363 ;; disrupt insn-recog's switch tables.
21364
21365 (define_insn "*call_value_pop_0"
21366   [(set (match_operand 0 "" "")
21367         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21368               (match_operand:SI 2 "" "")))
21369    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21370                             (match_operand:SI 3 "immediate_operand" "")))]
21371   "!TARGET_64BIT"
21372 {
21373   if (SIBLING_CALL_P (insn))
21374     return "jmp\t%P1";
21375   else
21376     return "call\t%P1";
21377 }
21378   [(set_attr "type" "callv")])
21379
21380 (define_insn "*call_value_pop_1"
21381   [(set (match_operand 0 "" "")
21382         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21383               (match_operand:SI 2 "" "")))
21384    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21385                             (match_operand:SI 3 "immediate_operand" "i")))]
21386   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21387 {
21388   if (constant_call_address_operand (operands[1], Pmode))
21389     return "call\t%P1";
21390   return "call\t%A1";
21391 }
21392   [(set_attr "type" "callv")])
21393
21394 (define_insn "*sibcall_value_pop_1"
21395   [(set (match_operand 0 "" "")
21396         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21397               (match_operand:SI 2 "" "")))
21398    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21399                             (match_operand:SI 3 "immediate_operand" "i,i")))]
21400   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21401   "@
21402    jmp\t%P1
21403    jmp\t%A1"
21404   [(set_attr "type" "callv")])
21405
21406 (define_insn "*call_value_0"
21407   [(set (match_operand 0 "" "")
21408         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21409               (match_operand:SI 2 "" "")))]
21410   "!TARGET_64BIT"
21411 {
21412   if (SIBLING_CALL_P (insn))
21413     return "jmp\t%P1";
21414   else
21415     return "call\t%P1";
21416 }
21417   [(set_attr "type" "callv")])
21418
21419 (define_insn "*call_value_0_rex64"
21420   [(set (match_operand 0 "" "")
21421         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21422               (match_operand:DI 2 "const_int_operand" "")))]
21423   "TARGET_64BIT"
21424 {
21425   if (SIBLING_CALL_P (insn))
21426     return "jmp\t%P1";
21427   else
21428     return "call\t%P1";
21429 }
21430   [(set_attr "type" "callv")])
21431
21432 (define_insn "*call_value_0_rex64_ms_sysv"
21433   [(set (match_operand 0 "" "")
21434         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21435               (match_operand:DI 2 "const_int_operand" "")))
21436    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21437    (clobber (reg:TI XMM6_REG))
21438    (clobber (reg:TI XMM7_REG))
21439    (clobber (reg:TI XMM8_REG))
21440    (clobber (reg:TI XMM9_REG))
21441    (clobber (reg:TI XMM10_REG))
21442    (clobber (reg:TI XMM11_REG))
21443    (clobber (reg:TI XMM12_REG))
21444    (clobber (reg:TI XMM13_REG))
21445    (clobber (reg:TI XMM14_REG))
21446    (clobber (reg:TI XMM15_REG))
21447    (clobber (reg:DI SI_REG))
21448    (clobber (reg:DI DI_REG))]
21449   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21450 {
21451   if (SIBLING_CALL_P (insn))
21452     return "jmp\t%P1";
21453   else
21454     return "call\t%P1";
21455 }
21456   [(set_attr "type" "callv")])
21457
21458 (define_insn "*call_value_1"
21459   [(set (match_operand 0 "" "")
21460         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21461               (match_operand:SI 2 "" "")))]
21462   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21463 {
21464   if (constant_call_address_operand (operands[1], Pmode))
21465     return "call\t%P1";
21466   return "call\t%A1";
21467 }
21468   [(set_attr "type" "callv")])
21469
21470 (define_insn "*sibcall_value_1"
21471   [(set (match_operand 0 "" "")
21472         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21473               (match_operand:SI 2 "" "")))]
21474   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21475   "@
21476    jmp\t%P1
21477    jmp\t%A1"
21478   [(set_attr "type" "callv")])
21479
21480 (define_insn "*call_value_1_rex64"
21481   [(set (match_operand 0 "" "")
21482         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21483               (match_operand:DI 2 "" "")))]
21484   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21485    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21486 {
21487   if (constant_call_address_operand (operands[1], Pmode))
21488     return "call\t%P1";
21489   return "call\t%A1";
21490 }
21491   [(set_attr "type" "callv")])
21492
21493 (define_insn "*call_value_1_rex64_ms_sysv"
21494   [(set (match_operand 0 "" "")
21495         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21496               (match_operand:DI 2 "" "")))
21497    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21498    (clobber (reg:TI 27))
21499    (clobber (reg:TI 28))
21500    (clobber (reg:TI 45))
21501    (clobber (reg:TI 46))
21502    (clobber (reg:TI 47))
21503    (clobber (reg:TI 48))
21504    (clobber (reg:TI 49))
21505    (clobber (reg:TI 50))
21506    (clobber (reg:TI 51))
21507    (clobber (reg:TI 52))
21508    (clobber (reg:DI SI_REG))
21509    (clobber (reg:DI DI_REG))]
21510   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21511 {
21512   if (constant_call_address_operand (operands[1], Pmode))
21513     return "call\t%P1";
21514   return "call\t%A1";
21515 }
21516   [(set_attr "type" "callv")])
21517
21518 (define_insn "*call_value_1_rex64_large"
21519   [(set (match_operand 0 "" "")
21520         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21521               (match_operand:DI 2 "" "")))]
21522   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21523   "call\t%A1"
21524   [(set_attr "type" "callv")])
21525
21526 (define_insn "*sibcall_value_1_rex64"
21527   [(set (match_operand 0 "" "")
21528         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21529               (match_operand:DI 2 "" "")))]
21530   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21531   "@
21532    jmp\t%P1
21533    jmp\t%A1"
21534   [(set_attr "type" "callv")])
21535 \f
21536 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21537 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21538 ;; caught for use by garbage collectors and the like.  Using an insn that
21539 ;; maps to SIGILL makes it more likely the program will rightfully die.
21540 ;; Keeping with tradition, "6" is in honor of #UD.
21541 (define_insn "trap"
21542   [(trap_if (const_int 1) (const_int 6))]
21543   ""
21544   { return ASM_SHORT "0x0b0f"; }
21545   [(set_attr "length" "2")])
21546
21547 (define_expand "sse_prologue_save"
21548   [(parallel [(set (match_operand:BLK 0 "" "")
21549                    (unspec:BLK [(reg:DI 21)
21550                                 (reg:DI 22)
21551                                 (reg:DI 23)
21552                                 (reg:DI 24)
21553                                 (reg:DI 25)
21554                                 (reg:DI 26)
21555                                 (reg:DI 27)
21556                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21557               (use (match_operand:DI 1 "register_operand" ""))
21558               (use (match_operand:DI 2 "immediate_operand" ""))
21559               (use (label_ref:DI (match_operand 3 "" "")))])]
21560   "TARGET_64BIT"
21561   "")
21562
21563 (define_insn "*sse_prologue_save_insn"
21564   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21565                           (match_operand:DI 4 "const_int_operand" "n")))
21566         (unspec:BLK [(reg:DI 21)
21567                      (reg:DI 22)
21568                      (reg:DI 23)
21569                      (reg:DI 24)
21570                      (reg:DI 25)
21571                      (reg:DI 26)
21572                      (reg:DI 27)
21573                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21574    (use (match_operand:DI 1 "register_operand" "r"))
21575    (use (match_operand:DI 2 "const_int_operand" "i"))
21576    (use (label_ref:DI (match_operand 3 "" "X")))]
21577   "TARGET_64BIT
21578    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21579    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21580 {
21581   int i;
21582   operands[0] = gen_rtx_MEM (Pmode,
21583                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21584   /* VEX instruction with a REX prefix will #UD.  */
21585   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21586     gcc_unreachable ();
21587
21588   output_asm_insn ("jmp\t%A1", operands);
21589   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21590     {
21591       operands[4] = adjust_address (operands[0], DImode, i*16);
21592       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21593       PUT_MODE (operands[4], TImode);
21594       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21595         output_asm_insn ("rex", operands);
21596       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21597     }
21598   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21599                                      CODE_LABEL_NUMBER (operands[3]));
21600   return "";
21601 }
21602   [(set_attr "type" "other")
21603    (set_attr "length_immediate" "0")
21604    (set_attr "length_address" "0")
21605    (set (attr "length")
21606      (if_then_else
21607        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21608        (const_string "34")
21609        (const_string "42")))
21610    (set_attr "memory" "store")
21611    (set_attr "modrm" "0")
21612    (set_attr "prefix" "maybe_vex")
21613    (set_attr "mode" "DI")])
21614
21615 (define_expand "prefetch"
21616   [(prefetch (match_operand 0 "address_operand" "")
21617              (match_operand:SI 1 "const_int_operand" "")
21618              (match_operand:SI 2 "const_int_operand" ""))]
21619   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21620 {
21621   int rw = INTVAL (operands[1]);
21622   int locality = INTVAL (operands[2]);
21623
21624   gcc_assert (rw == 0 || rw == 1);
21625   gcc_assert (locality >= 0 && locality <= 3);
21626   gcc_assert (GET_MODE (operands[0]) == Pmode
21627               || GET_MODE (operands[0]) == VOIDmode);
21628
21629   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21630      supported by SSE counterpart or the SSE prefetch is not available
21631      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21632      of locality.  */
21633   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21634     operands[2] = GEN_INT (3);
21635   else
21636     operands[1] = const0_rtx;
21637 })
21638
21639 (define_insn "*prefetch_sse"
21640   [(prefetch (match_operand:SI 0 "address_operand" "p")
21641              (const_int 0)
21642              (match_operand:SI 1 "const_int_operand" ""))]
21643   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21644 {
21645   static const char * const patterns[4] = {
21646    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21647   };
21648
21649   int locality = INTVAL (operands[1]);
21650   gcc_assert (locality >= 0 && locality <= 3);
21651
21652   return patterns[locality];
21653 }
21654   [(set_attr "type" "sse")
21655    (set_attr "atom_sse_attr" "prefetch")
21656    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21657    (set_attr "memory" "none")])
21658
21659 (define_insn "*prefetch_sse_rex"
21660   [(prefetch (match_operand:DI 0 "address_operand" "p")
21661              (const_int 0)
21662              (match_operand:SI 1 "const_int_operand" ""))]
21663   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21664 {
21665   static const char * const patterns[4] = {
21666    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21667   };
21668
21669   int locality = INTVAL (operands[1]);
21670   gcc_assert (locality >= 0 && locality <= 3);
21671
21672   return patterns[locality];
21673 }
21674   [(set_attr "type" "sse")
21675    (set_attr "atom_sse_attr" "prefetch")
21676    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21677    (set_attr "memory" "none")])
21678
21679 (define_insn "*prefetch_3dnow"
21680   [(prefetch (match_operand:SI 0 "address_operand" "p")
21681              (match_operand:SI 1 "const_int_operand" "n")
21682              (const_int 3))]
21683   "TARGET_3DNOW && !TARGET_64BIT"
21684 {
21685   if (INTVAL (operands[1]) == 0)
21686     return "prefetch\t%a0";
21687   else
21688     return "prefetchw\t%a0";
21689 }
21690   [(set_attr "type" "mmx")
21691    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21692    (set_attr "memory" "none")])
21693
21694 (define_insn "*prefetch_3dnow_rex"
21695   [(prefetch (match_operand:DI 0 "address_operand" "p")
21696              (match_operand:SI 1 "const_int_operand" "n")
21697              (const_int 3))]
21698   "TARGET_3DNOW && TARGET_64BIT"
21699 {
21700   if (INTVAL (operands[1]) == 0)
21701     return "prefetch\t%a0";
21702   else
21703     return "prefetchw\t%a0";
21704 }
21705   [(set_attr "type" "mmx")
21706    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21707    (set_attr "memory" "none")])
21708
21709 (define_expand "stack_protect_set"
21710   [(match_operand 0 "memory_operand" "")
21711    (match_operand 1 "memory_operand" "")]
21712   ""
21713 {
21714 #ifdef TARGET_THREAD_SSP_OFFSET
21715   if (TARGET_64BIT)
21716     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21717                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21718   else
21719     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21720                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21721 #else
21722   if (TARGET_64BIT)
21723     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21724   else
21725     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21726 #endif
21727   DONE;
21728 })
21729
21730 (define_insn "stack_protect_set_si"
21731   [(set (match_operand:SI 0 "memory_operand" "=m")
21732         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21733    (set (match_scratch:SI 2 "=&r") (const_int 0))
21734    (clobber (reg:CC FLAGS_REG))]
21735   ""
21736   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21737   [(set_attr "type" "multi")])
21738
21739 (define_insn "stack_protect_set_di"
21740   [(set (match_operand:DI 0 "memory_operand" "=m")
21741         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21742    (set (match_scratch:DI 2 "=&r") (const_int 0))
21743    (clobber (reg:CC FLAGS_REG))]
21744   "TARGET_64BIT"
21745   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21746   [(set_attr "type" "multi")])
21747
21748 (define_insn "stack_tls_protect_set_si"
21749   [(set (match_operand:SI 0 "memory_operand" "=m")
21750         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21751    (set (match_scratch:SI 2 "=&r") (const_int 0))
21752    (clobber (reg:CC FLAGS_REG))]
21753   ""
21754   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21755   [(set_attr "type" "multi")])
21756
21757 (define_insn "stack_tls_protect_set_di"
21758   [(set (match_operand:DI 0 "memory_operand" "=m")
21759         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21760    (set (match_scratch:DI 2 "=&r") (const_int 0))
21761    (clobber (reg:CC FLAGS_REG))]
21762   "TARGET_64BIT"
21763   {
21764      /* The kernel uses a different segment register for performance reasons; a
21765         system call would not have to trash the userspace segment register,
21766         which would be expensive */
21767      if (ix86_cmodel != CM_KERNEL)
21768         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21769      else
21770         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21771   }
21772   [(set_attr "type" "multi")])
21773
21774 (define_expand "stack_protect_test"
21775   [(match_operand 0 "memory_operand" "")
21776    (match_operand 1 "memory_operand" "")
21777    (match_operand 2 "" "")]
21778   ""
21779 {
21780   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21781
21782 #ifdef TARGET_THREAD_SSP_OFFSET
21783   if (TARGET_64BIT)
21784     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21785                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21786   else
21787     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21788                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21789 #else
21790   if (TARGET_64BIT)
21791     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21792   else
21793     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21794 #endif
21795
21796   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21797                                   flags, const0_rtx, operands[2]));
21798   DONE;
21799 })
21800
21801 (define_insn "stack_protect_test_si"
21802   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21803         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21804                      (match_operand:SI 2 "memory_operand" "m")]
21805                     UNSPEC_SP_TEST))
21806    (clobber (match_scratch:SI 3 "=&r"))]
21807   ""
21808   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21809   [(set_attr "type" "multi")])
21810
21811 (define_insn "stack_protect_test_di"
21812   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21813         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21814                      (match_operand:DI 2 "memory_operand" "m")]
21815                     UNSPEC_SP_TEST))
21816    (clobber (match_scratch:DI 3 "=&r"))]
21817   "TARGET_64BIT"
21818   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21819   [(set_attr "type" "multi")])
21820
21821 (define_insn "stack_tls_protect_test_si"
21822   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21823         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21824                      (match_operand:SI 2 "const_int_operand" "i")]
21825                     UNSPEC_SP_TLS_TEST))
21826    (clobber (match_scratch:SI 3 "=r"))]
21827   ""
21828   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21829   [(set_attr "type" "multi")])
21830
21831 (define_insn "stack_tls_protect_test_di"
21832   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21833         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21834                      (match_operand:DI 2 "const_int_operand" "i")]
21835                     UNSPEC_SP_TLS_TEST))
21836    (clobber (match_scratch:DI 3 "=r"))]
21837   "TARGET_64BIT"
21838   {
21839      /* The kernel uses a different segment register for performance reasons; a
21840         system call would not have to trash the userspace segment register,
21841         which would be expensive */
21842      if (ix86_cmodel != CM_KERNEL)
21843         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21844      else
21845         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21846   }
21847   [(set_attr "type" "multi")])
21848
21849 (define_mode_iterator CRC32MODE [QI HI SI])
21850 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21851 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21852
21853 (define_insn "sse4_2_crc32<mode>"
21854   [(set (match_operand:SI 0 "register_operand" "=r")
21855         (unspec:SI
21856           [(match_operand:SI 1 "register_operand" "0")
21857            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21858           UNSPEC_CRC32))]
21859   "TARGET_SSE4_2 || TARGET_CRC32"
21860   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21861   [(set_attr "type" "sselog1")
21862    (set_attr "prefix_rep" "1")
21863    (set_attr "prefix_extra" "1")
21864    (set (attr "prefix_data16")
21865      (if_then_else (match_operand:HI 2 "" "")
21866        (const_string "1")
21867        (const_string "*")))
21868    (set (attr "prefix_rex")
21869      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21870        (const_string "1")
21871        (const_string "*")))
21872    (set_attr "mode" "SI")])
21873
21874 (define_insn "sse4_2_crc32di"
21875   [(set (match_operand:DI 0 "register_operand" "=r")
21876         (unspec:DI
21877           [(match_operand:DI 1 "register_operand" "0")
21878            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21879           UNSPEC_CRC32))]
21880   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21881   "crc32q\t{%2, %0|%0, %2}"
21882   [(set_attr "type" "sselog1")
21883    (set_attr "prefix_rep" "1")
21884    (set_attr "prefix_extra" "1")
21885    (set_attr "mode" "DI")])
21886
21887 (define_expand "rdpmc"
21888   [(match_operand:DI 0 "register_operand" "")
21889    (match_operand:SI 1 "register_operand" "")]
21890   ""
21891 {
21892   rtx reg = gen_reg_rtx (DImode);
21893   rtx si;
21894
21895   /* Force operand 1 into ECX.  */
21896   rtx ecx = gen_rtx_REG (SImode, CX_REG);
21897   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21898   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21899                                 UNSPECV_RDPMC);
21900
21901   if (TARGET_64BIT)
21902     {
21903       rtvec vec = rtvec_alloc (2);
21904       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21905       rtx upper = gen_reg_rtx (DImode);
21906       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21907                                         gen_rtvec (1, const0_rtx),
21908                                         UNSPECV_RDPMC);
21909       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21910       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21911       emit_insn (load);
21912       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21913                                    NULL, 1, OPTAB_DIRECT);
21914       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21915                                  OPTAB_DIRECT);
21916     }
21917   else
21918     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21919   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21920   DONE;
21921 })
21922
21923 (define_insn "*rdpmc"
21924   [(set (match_operand:DI 0 "register_operand" "=A")
21925         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21926                             UNSPECV_RDPMC))]
21927   "!TARGET_64BIT"
21928   "rdpmc"
21929   [(set_attr "type" "other")
21930    (set_attr "length" "2")])
21931
21932 (define_insn "*rdpmc_rex64"
21933   [(set (match_operand:DI 0 "register_operand" "=a")
21934         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21935                             UNSPECV_RDPMC))
21936   (set (match_operand:DI 1 "register_operand" "=d")
21937        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21938   "TARGET_64BIT"
21939   "rdpmc"
21940   [(set_attr "type" "other")
21941    (set_attr "length" "2")])
21942
21943 (define_expand "rdtsc"
21944   [(set (match_operand:DI 0 "register_operand" "")
21945         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21946   ""
21947 {
21948   if (TARGET_64BIT)
21949     {
21950       rtvec vec = rtvec_alloc (2);
21951       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21952       rtx upper = gen_reg_rtx (DImode);
21953       rtx lower = gen_reg_rtx (DImode);
21954       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21955                                          gen_rtvec (1, const0_rtx),
21956                                          UNSPECV_RDTSC);
21957       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21958       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21959       emit_insn (load);
21960       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21961                                    NULL, 1, OPTAB_DIRECT);
21962       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21963                                    OPTAB_DIRECT);
21964       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21965       DONE;
21966     }
21967 })
21968
21969 (define_insn "*rdtsc"
21970   [(set (match_operand:DI 0 "register_operand" "=A")
21971         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21972   "!TARGET_64BIT"
21973   "rdtsc"
21974   [(set_attr "type" "other")
21975    (set_attr "length" "2")])
21976
21977 (define_insn "*rdtsc_rex64"
21978   [(set (match_operand:DI 0 "register_operand" "=a")
21979         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21980    (set (match_operand:DI 1 "register_operand" "=d")
21981         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21982   "TARGET_64BIT"
21983   "rdtsc"
21984   [(set_attr "type" "other")
21985    (set_attr "length" "2")])
21986
21987 (define_expand "rdtscp"
21988   [(match_operand:DI 0 "register_operand" "")
21989    (match_operand:SI 1 "memory_operand" "")]
21990   ""
21991 {
21992   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21993                                     gen_rtvec (1, const0_rtx),
21994                                     UNSPECV_RDTSCP);
21995   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21996                                     gen_rtvec (1, const0_rtx),
21997                                     UNSPECV_RDTSCP);
21998   rtx reg = gen_reg_rtx (DImode);
21999   rtx tmp = gen_reg_rtx (SImode);
22000
22001   if (TARGET_64BIT)
22002     {
22003       rtvec vec = rtvec_alloc (3);
22004       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22005       rtx upper = gen_reg_rtx (DImode);
22006       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22007       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22008       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
22009       emit_insn (load);
22010       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22011                                    NULL, 1, OPTAB_DIRECT);
22012       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22013                                  OPTAB_DIRECT);
22014     }
22015   else
22016     {
22017       rtvec vec = rtvec_alloc (2);
22018       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22019       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22020       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
22021       emit_insn (load);
22022     }
22023   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22024   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
22025   DONE;
22026 })
22027
22028 (define_insn "*rdtscp"
22029   [(set (match_operand:DI 0 "register_operand" "=A")
22030         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22031    (set (match_operand:SI 1 "register_operand" "=c")
22032         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22033   "!TARGET_64BIT"
22034   "rdtscp"
22035   [(set_attr "type" "other")
22036    (set_attr "length" "3")])
22037
22038 (define_insn "*rdtscp_rex64"
22039   [(set (match_operand:DI 0 "register_operand" "=a")
22040         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22041    (set (match_operand:DI 1 "register_operand" "=d")
22042         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22043    (set (match_operand:SI 2 "register_operand" "=c")
22044         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22045   "TARGET_64BIT"
22046   "rdtscp"
22047   [(set_attr "type" "other")
22048    (set_attr "length" "3")])
22049
22050 (include "mmx.md")
22051 (include "sse.md")
22052 (include "sync.md")