OSDN Git Service

PR target/38904
[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 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61    (UNSPEC_MACHOPIC_OFFSET      10)
62
63    ; Prologue support
64    (UNSPEC_STACK_ALLOC          11)
65    (UNSPEC_SET_GOT              12)
66    (UNSPEC_SSE_PROLOGUE_SAVE    13)
67    (UNSPEC_REG_SAVE             14)
68    (UNSPEC_DEF_CFA              15)
69    (UNSPEC_SET_RIP              16)
70    (UNSPEC_SET_GOT_OFFSET       17)
71
72    ; TLS support
73    (UNSPEC_TP                   18)
74    (UNSPEC_TLS_GD               19)
75    (UNSPEC_TLS_LD_BASE          20)
76    (UNSPEC_TLSDESC              21)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 30)
80    (UNSPEC_FNSTSW               31)
81    (UNSPEC_SAHF                 32)
82    (UNSPEC_FSTCW                33)
83    (UNSPEC_ADD_CARRY            34)
84    (UNSPEC_FLDCW                35)
85    (UNSPEC_REP                  36)
86    (UNSPEC_EH_RETURN            37)
87    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           39)
89
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          40)
92    (UNSPEC_MASKMOV              41)
93    (UNSPEC_MOVMSK               42)
94    (UNSPEC_MOVNT                43)
95    (UNSPEC_MOVU                 44)
96    (UNSPEC_RCP                  45)
97    (UNSPEC_RSQRT                46)
98    (UNSPEC_SFENCE               47)
99    (UNSPEC_PFRCP                49)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
108    (UNSPEC_MS_TO_SYSV_CALL      48)
109
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
114
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124    (UNSPEC_TAN                  68)
125    (UNSPEC_FXAM                 69)
126
127    ; x87 Rounding
128    (UNSPEC_FRNDINT_FLOOR        70)
129    (UNSPEC_FRNDINT_CEIL         71)
130    (UNSPEC_FRNDINT_TRUNC        72)
131    (UNSPEC_FRNDINT_MASK_PM      73)
132    (UNSPEC_FIST_FLOOR           74)
133    (UNSPEC_FIST_CEIL            75)
134
135    ; x87 Double output FP
136    (UNSPEC_SINCOS_COS           80)
137    (UNSPEC_SINCOS_SIN           81)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
146
147    (UNSPEC_C2_FLAG              95)
148
149    ; SSP patterns
150    (UNSPEC_SP_SET               100)
151    (UNSPEC_SP_TEST              101)
152    (UNSPEC_SP_TLS_SET           102)
153    (UNSPEC_SP_TLS_TEST          103)
154
155    ; SSSE3
156    (UNSPEC_PSHUFB               120)
157    (UNSPEC_PSIGN                121)
158    (UNSPEC_PALIGNR              122)
159
160    ; For SSE4A support
161    (UNSPEC_EXTRQI               130)
162    (UNSPEC_EXTRQ                131)
163    (UNSPEC_INSERTQI             132)
164    (UNSPEC_INSERTQ              133)
165
166    ; For SSE4.1 support
167    (UNSPEC_BLENDV               134)
168    (UNSPEC_INSERTPS             135)
169    (UNSPEC_DP                   136)
170    (UNSPEC_MOVNTDQA             137)
171    (UNSPEC_MPSADBW              138)
172    (UNSPEC_PHMINPOSUW           139)
173    (UNSPEC_PTEST                140)
174    (UNSPEC_ROUND                141)
175
176    ; For SSE4.2 support
177    (UNSPEC_CRC32                143)
178    (UNSPEC_PCMPESTR             144)
179    (UNSPEC_PCMPISTR             145)
180
181    ;; For SSE5
182    (UNSPEC_SSE5_INTRINSIC       150)
183    (UNSPEC_SSE5_UNSIGNED_CMP    151)
184    (UNSPEC_SSE5_TRUEFALSE       152)
185    (UNSPEC_SSE5_PERMUTE         153)
186    (UNSPEC_FRCZ                 154)
187    (UNSPEC_CVTPH2PS             155)
188    (UNSPEC_CVTPS2PH             156)
189
190    ; For AES support
191    (UNSPEC_AESENC               159)
192    (UNSPEC_AESENCLAST           160)
193    (UNSPEC_AESDEC               161)
194    (UNSPEC_AESDECLAST           162)
195    (UNSPEC_AESIMC               163)
196    (UNSPEC_AESKEYGENASSIST      164)
197
198    ; For PCLMUL support
199    (UNSPEC_PCLMUL               165)
200
201    ; For AVX support
202    (UNSPEC_PCMP                 166)
203    (UNSPEC_VPERMIL              167)
204    (UNSPEC_VPERMIL2F128         168)
205    (UNSPEC_MASKLOAD             169)
206    (UNSPEC_MASKSTORE            170)
207    (UNSPEC_CAST                 171)
208    (UNSPEC_VTESTP               172)
209   ])
210
211 (define_constants
212   [(UNSPECV_BLOCKAGE            0)
213    (UNSPECV_STACK_PROBE         1)
214    (UNSPECV_EMMS                2)
215    (UNSPECV_LDMXCSR             3)
216    (UNSPECV_STMXCSR             4)
217    (UNSPECV_FEMMS               5)
218    (UNSPECV_CLFLUSH             6)
219    (UNSPECV_ALIGN               7)
220    (UNSPECV_MONITOR             8)
221    (UNSPECV_MWAIT               9)
222    (UNSPECV_CMPXCHG             10)
223    (UNSPECV_XCHG                12)
224    (UNSPECV_LOCK                13)
225    (UNSPECV_PROLOGUE_USE        14)
226    (UNSPECV_CLD                 15)
227    (UNSPECV_VZEROALL            16)
228    (UNSPECV_VZEROUPPER          17)
229   ])
230
231 ;; Constants to represent pcomtrue/pcomfalse variants
232 (define_constants
233   [(PCOM_FALSE                  0)
234    (PCOM_TRUE                   1)
235    (COM_FALSE_S                 2)
236    (COM_FALSE_P                 3)
237    (COM_TRUE_S                  4)
238    (COM_TRUE_P                  5)
239   ])
240
241 ;; Constants used in the SSE5 pperm instruction
242 (define_constants
243   [(PPERM_SRC                   0x00)   /* copy source */
244    (PPERM_INVERT                0x20)   /* invert source */
245    (PPERM_REVERSE               0x40)   /* bit reverse source */
246    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
247    (PPERM_ZERO                  0x80)   /* all 0's */
248    (PPERM_ONES                  0xa0)   /* all 1's */
249    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
250    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
251    (PPERM_SRC1                  0x00)   /* use first source byte */
252    (PPERM_SRC2                  0x10)   /* use second source byte */
253    ])
254
255 ;; Registers by name.
256 (define_constants
257   [(AX_REG                       0)
258    (DX_REG                       1)
259    (CX_REG                       2)
260    (BX_REG                       3)
261    (SI_REG                       4)
262    (DI_REG                       5)
263    (BP_REG                       6)
264    (SP_REG                       7)
265    (FLAGS_REG                   17)
266    (FPSR_REG                    18)
267    (FPCR_REG                    19)
268    (XMM0_REG                    21)
269    (XMM1_REG                    22)
270    (XMM2_REG                    23)
271    (XMM3_REG                    24)
272    (XMM4_REG                    25)
273    (XMM5_REG                    26)
274    (XMM6_REG                    27)
275    (XMM7_REG                    28)
276    (R10_REG                     39)
277    (R11_REG                     40)
278    (R13_REG                     42)
279    (XMM8_REG                    45)
280    (XMM9_REG                    46)
281    (XMM10_REG                   47)
282    (XMM11_REG                   48)
283    (XMM12_REG                   49)
284    (XMM13_REG                   50)
285    (XMM14_REG                   51)
286    (XMM15_REG                   52)
287   ])
288
289 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
290 ;; from i386.c.
291
292 ;; In C guard expressions, put expressions which may be compile-time
293 ;; constants first.  This allows for better optimization.  For
294 ;; example, write "TARGET_64BIT && reload_completed", not
295 ;; "reload_completed && TARGET_64BIT".
296
297 \f
298 ;; Processor type.
299 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
300                     generic64,amdfam10"
301   (const (symbol_ref "ix86_schedule")))
302
303 ;; A basic instruction type.  Refinements due to arguments to be
304 ;; provided in other attributes.
305 (define_attr "type"
306   "other,multi,
307    alu,alu1,negnot,imov,imovx,lea,
308    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
309    icmp,test,ibr,setcc,icmov,
310    push,pop,call,callv,leave,
311    str,bitmanip,
312    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
313    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
314    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
315    ssemuladd,sse4arg,
316    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
317   (const_string "other"))
318
319 ;; Main data type used by the insn
320 (define_attr "mode"
321   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
322   (const_string "unknown"))
323
324 ;; The CPU unit operations uses.
325 (define_attr "unit" "integer,i387,sse,mmx,unknown"
326   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
327            (const_string "i387")
328          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
329                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
330                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
331            (const_string "sse")
332          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
333            (const_string "mmx")
334          (eq_attr "type" "other")
335            (const_string "unknown")]
336          (const_string "integer")))
337
338 ;; The (bounding maximum) length of an instruction immediate.
339 (define_attr "length_immediate" ""
340   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
341                           bitmanip")
342            (const_int 0)
343          (eq_attr "unit" "i387,sse,mmx")
344            (const_int 0)
345          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
346                           imul,icmp,push,pop")
347            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
348          (eq_attr "type" "imov,test")
349            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
350          (eq_attr "type" "call")
351            (if_then_else (match_operand 0 "constant_call_address_operand" "")
352              (const_int 4)
353              (const_int 0))
354          (eq_attr "type" "callv")
355            (if_then_else (match_operand 1 "constant_call_address_operand" "")
356              (const_int 4)
357              (const_int 0))
358          ;; We don't know the size before shorten_branches.  Expect
359          ;; the instruction to fit for better scheduling.
360          (eq_attr "type" "ibr")
361            (const_int 1)
362          ]
363          (symbol_ref "/* Update immediate_length and other attributes! */
364                       gcc_unreachable (),1")))
365
366 ;; The (bounding maximum) length of an instruction address.
367 (define_attr "length_address" ""
368   (cond [(eq_attr "type" "str,other,multi,fxch")
369            (const_int 0)
370          (and (eq_attr "type" "call")
371               (match_operand 0 "constant_call_address_operand" ""))
372              (const_int 0)
373          (and (eq_attr "type" "callv")
374               (match_operand 1 "constant_call_address_operand" ""))
375              (const_int 0)
376          ]
377          (symbol_ref "ix86_attr_length_address_default (insn)")))
378
379 ;; Set when length prefix is used.
380 (define_attr "prefix_data16" ""
381   (if_then_else (ior (eq_attr "mode" "HI")
382                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
383     (const_int 1)
384     (const_int 0)))
385
386 ;; Set when string REP prefix is used.
387 (define_attr "prefix_rep" ""
388   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
389     (const_int 1)
390     (const_int 0)))
391
392 ;; Set when 0f opcode prefix is used.
393 (define_attr "prefix_0f" ""
394   (if_then_else
395     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
396          (eq_attr "unit" "sse,mmx"))
397     (const_int 1)
398     (const_int 0)))
399
400 ;; Set when REX opcode prefix is used.
401 (define_attr "prefix_rex" ""
402   (cond [(and (eq_attr "mode" "DI")
403               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
404            (const_int 1)
405          (and (eq_attr "mode" "QI")
406               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
407                   (const_int 0)))
408            (const_int 1)
409          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
410              (const_int 0))
411            (const_int 1)
412         ]
413         (const_int 0)))
414
415 ;; There are also additional prefixes in SSSE3.
416 (define_attr "prefix_extra" "" (const_int 0))
417
418 ;; Prefix used: original, VEX or maybe VEX.
419 (define_attr "prefix" "orig,vex,maybe_vex"
420   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
421     (const_string "vex")
422     (const_string "orig")))
423
424 ;; There is a 8bit immediate for VEX.
425 (define_attr "prefix_vex_imm8" "" (const_int 0))
426
427 ;; VEX W bit is used.
428 (define_attr "prefix_vex_w" "" (const_int 0))
429
430 ;; The length of VEX prefix
431 (define_attr "length_vex" ""
432   (if_then_else (eq_attr "prefix_0f" "1")
433     (if_then_else (eq_attr "prefix_vex_w" "1")
434       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
435       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
436     (if_then_else (eq_attr "prefix_vex_w" "1")
437       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
438       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
439
440 ;; Set when modrm byte is used.
441 (define_attr "modrm" ""
442   (cond [(eq_attr "type" "str,leave")
443            (const_int 0)
444          (eq_attr "unit" "i387")
445            (const_int 0)
446          (and (eq_attr "type" "incdec")
447               (ior (match_operand:SI 1 "register_operand" "")
448                    (match_operand:HI 1 "register_operand" "")))
449            (const_int 0)
450          (and (eq_attr "type" "push")
451               (not (match_operand 1 "memory_operand" "")))
452            (const_int 0)
453          (and (eq_attr "type" "pop")
454               (not (match_operand 0 "memory_operand" "")))
455            (const_int 0)
456          (and (eq_attr "type" "imov")
457               (ior (and (match_operand 0 "register_operand" "")
458                         (match_operand 1 "immediate_operand" ""))
459                    (ior (and (match_operand 0 "ax_reg_operand" "")
460                              (match_operand 1 "memory_displacement_only_operand" ""))
461                         (and (match_operand 0 "memory_displacement_only_operand" "")
462                              (match_operand 1 "ax_reg_operand" "")))))
463            (const_int 0)
464          (and (eq_attr "type" "call")
465               (match_operand 0 "constant_call_address_operand" ""))
466              (const_int 0)
467          (and (eq_attr "type" "callv")
468               (match_operand 1 "constant_call_address_operand" ""))
469              (const_int 0)
470          ]
471          (const_int 1)))
472
473 ;; The (bounding maximum) length of an instruction in bytes.
474 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
475 ;; Later we may want to split them and compute proper length as for
476 ;; other insns.
477 (define_attr "length" ""
478   (cond [(eq_attr "type" "other,multi,fistp,frndint")
479            (const_int 16)
480          (eq_attr "type" "fcmp")
481            (const_int 4)
482          (eq_attr "unit" "i387")
483            (plus (const_int 2)
484                  (plus (attr "prefix_data16")
485                        (attr "length_address")))
486          (ior (eq_attr "prefix" "vex")
487               (and (eq_attr "prefix" "maybe_vex")
488                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
489            (plus (attr "length_vex")
490                  (plus (attr "prefix_vex_imm8")
491                        (plus (attr "modrm")
492                              (attr "length_address"))))]
493          (plus (plus (attr "modrm")
494                      (plus (attr "prefix_0f")
495                            (plus (attr "prefix_rex")
496                                  (plus (attr "prefix_extra")
497                                        (const_int 1)))))
498                (plus (attr "prefix_rep")
499                      (plus (attr "prefix_data16")
500                            (plus (attr "length_immediate")
501                                  (attr "length_address")))))))
502
503 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
504 ;; `store' if there is a simple memory reference therein, or `unknown'
505 ;; if the instruction is complex.
506
507 (define_attr "memory" "none,load,store,both,unknown"
508   (cond [(eq_attr "type" "other,multi,str")
509            (const_string "unknown")
510          (eq_attr "type" "lea,fcmov,fpspc")
511            (const_string "none")
512          (eq_attr "type" "fistp,leave")
513            (const_string "both")
514          (eq_attr "type" "frndint")
515            (const_string "load")
516          (eq_attr "type" "push")
517            (if_then_else (match_operand 1 "memory_operand" "")
518              (const_string "both")
519              (const_string "store"))
520          (eq_attr "type" "pop")
521            (if_then_else (match_operand 0 "memory_operand" "")
522              (const_string "both")
523              (const_string "load"))
524          (eq_attr "type" "setcc")
525            (if_then_else (match_operand 0 "memory_operand" "")
526              (const_string "store")
527              (const_string "none"))
528          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
529            (if_then_else (ior (match_operand 0 "memory_operand" "")
530                               (match_operand 1 "memory_operand" ""))
531              (const_string "load")
532              (const_string "none"))
533          (eq_attr "type" "ibr")
534            (if_then_else (match_operand 0 "memory_operand" "")
535              (const_string "load")
536              (const_string "none"))
537          (eq_attr "type" "call")
538            (if_then_else (match_operand 0 "constant_call_address_operand" "")
539              (const_string "none")
540              (const_string "load"))
541          (eq_attr "type" "callv")
542            (if_then_else (match_operand 1 "constant_call_address_operand" "")
543              (const_string "none")
544              (const_string "load"))
545          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
546               (match_operand 1 "memory_operand" ""))
547            (const_string "both")
548          (and (match_operand 0 "memory_operand" "")
549               (match_operand 1 "memory_operand" ""))
550            (const_string "both")
551          (match_operand 0 "memory_operand" "")
552            (const_string "store")
553          (match_operand 1 "memory_operand" "")
554            (const_string "load")
555          (and (eq_attr "type"
556                  "!alu1,negnot,ishift1,
557                    imov,imovx,icmp,test,bitmanip,
558                    fmov,fcmp,fsgn,
559                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
560                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
561               (match_operand 2 "memory_operand" ""))
562            (const_string "load")
563          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
564               (match_operand 3 "memory_operand" ""))
565            (const_string "load")
566         ]
567         (const_string "none")))
568
569 ;; Indicates if an instruction has both an immediate and a displacement.
570
571 (define_attr "imm_disp" "false,true,unknown"
572   (cond [(eq_attr "type" "other,multi")
573            (const_string "unknown")
574          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
575               (and (match_operand 0 "memory_displacement_operand" "")
576                    (match_operand 1 "immediate_operand" "")))
577            (const_string "true")
578          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
579               (and (match_operand 0 "memory_displacement_operand" "")
580                    (match_operand 2 "immediate_operand" "")))
581            (const_string "true")
582         ]
583         (const_string "false")))
584
585 ;; Indicates if an FP operation has an integer source.
586
587 (define_attr "fp_int_src" "false,true"
588   (const_string "false"))
589
590 ;; Defines rounding mode of an FP operation.
591
592 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
593   (const_string "any"))
594
595 ;; Describe a user's asm statement.
596 (define_asm_attributes
597   [(set_attr "length" "128")
598    (set_attr "type" "multi")])
599
600 ;; All integer comparison codes.
601 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
602
603 ;; All floating-point comparison codes.
604 (define_code_iterator fp_cond [unordered ordered
605                                uneq unge ungt unle unlt ltgt ])
606
607 (define_code_iterator plusminus [plus minus])
608
609 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
610
611 ;; Base name for define_insn
612 (define_code_attr plusminus_insn
613   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
614    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
615
616 ;; Base name for insn mnemonic.
617 (define_code_attr plusminus_mnemonic
618   [(plus "add") (ss_plus "adds") (us_plus "addus")
619    (minus "sub") (ss_minus "subs") (us_minus "subus")])
620
621 ;; Mark commutative operators as such in constraints.
622 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
623                         (minus "") (ss_minus "") (us_minus "")])
624
625 ;; Mapping of signed max and min
626 (define_code_iterator smaxmin [smax smin])
627
628 ;; Mapping of unsigned max and min
629 (define_code_iterator umaxmin [umax umin])
630
631 ;; Mapping of signed/unsigned max and min
632 (define_code_iterator maxmin [smax smin umax umin])
633
634 ;; Base name for integer and FP insn mnemonic
635 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
636                                  (umax "maxu") (umin "minu")])
637 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
638
639 ;; Mapping of parallel logic operators
640 (define_code_iterator plogic [and ior xor])
641
642 ;; Base name for insn mnemonic.
643 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
644
645 ;; Mapping of abs neg operators
646 (define_code_iterator absneg [abs neg])
647
648 ;; Base name for x87 insn mnemonic.
649 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
650
651 ;; All single word integer modes.
652 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
653
654 ;; Single word integer modes without QImode.
655 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
656
657 ;; Instruction suffix for integer modes.
658 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
659
660 ;; Register class for integer modes.
661 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
662
663 ;; Immediate operand constraint for integer modes.
664 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
665
666 ;; General operand predicate for integer modes.
667 (define_mode_attr general_operand
668         [(QI "general_operand")
669          (HI "general_operand")
670          (SI "general_operand")
671          (DI "x86_64_general_operand")])
672
673 ;; SSE and x87 SFmode and DFmode floating point modes
674 (define_mode_iterator MODEF [SF DF])
675
676 ;; All x87 floating point modes
677 (define_mode_iterator X87MODEF [SF DF XF])
678
679 ;; All integer modes handled by x87 fisttp operator.
680 (define_mode_iterator X87MODEI [HI SI DI])
681
682 ;; All integer modes handled by integer x87 operators.
683 (define_mode_iterator X87MODEI12 [HI SI])
684
685 ;; All integer modes handled by SSE cvtts?2si* operators.
686 (define_mode_iterator SSEMODEI24 [SI DI])
687
688 ;; SSE asm suffix for floating point modes
689 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
690
691 ;; SSE vector mode corresponding to a scalar mode
692 (define_mode_attr ssevecmode
693   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
694
695 ;; Instruction suffix for REX 64bit operators.
696 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
697
698 ;; This mode iterator allows :P to be used for patterns that operate on
699 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
700 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
701
702 \f
703 ;; Scheduling descriptions
704
705 (include "pentium.md")
706 (include "ppro.md")
707 (include "k6.md")
708 (include "athlon.md")
709 (include "geode.md")
710
711 \f
712 ;; Operand and operator predicates and constraints
713
714 (include "predicates.md")
715 (include "constraints.md")
716
717 \f
718 ;; Compare instructions.
719
720 ;; All compare insns have expanders that save the operands away without
721 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
722 ;; after the cmp) will actually emit the cmpM.
723
724 (define_expand "cmpti"
725   [(set (reg:CC FLAGS_REG)
726         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
727                     (match_operand:TI 1 "x86_64_general_operand" "")))]
728   "TARGET_64BIT"
729 {
730   if (MEM_P (operands[0]) && MEM_P (operands[1]))
731     operands[0] = force_reg (TImode, operands[0]);
732   ix86_compare_op0 = operands[0];
733   ix86_compare_op1 = operands[1];
734   DONE;
735 })
736
737 (define_expand "cmpdi"
738   [(set (reg:CC FLAGS_REG)
739         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
740                     (match_operand:DI 1 "x86_64_general_operand" "")))]
741   ""
742 {
743   if (MEM_P (operands[0]) && MEM_P (operands[1]))
744     operands[0] = force_reg (DImode, operands[0]);
745   ix86_compare_op0 = operands[0];
746   ix86_compare_op1 = operands[1];
747   DONE;
748 })
749
750 (define_expand "cmpsi"
751   [(set (reg:CC FLAGS_REG)
752         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
753                     (match_operand:SI 1 "general_operand" "")))]
754   ""
755 {
756   if (MEM_P (operands[0]) && MEM_P (operands[1]))
757     operands[0] = force_reg (SImode, operands[0]);
758   ix86_compare_op0 = operands[0];
759   ix86_compare_op1 = operands[1];
760   DONE;
761 })
762
763 (define_expand "cmphi"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
766                     (match_operand:HI 1 "general_operand" "")))]
767   ""
768 {
769   if (MEM_P (operands[0]) && MEM_P (operands[1]))
770     operands[0] = force_reg (HImode, operands[0]);
771   ix86_compare_op0 = operands[0];
772   ix86_compare_op1 = operands[1];
773   DONE;
774 })
775
776 (define_expand "cmpqi"
777   [(set (reg:CC FLAGS_REG)
778         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
779                     (match_operand:QI 1 "general_operand" "")))]
780   "TARGET_QIMODE_MATH"
781 {
782   if (MEM_P (operands[0]) && MEM_P (operands[1]))
783     operands[0] = force_reg (QImode, operands[0]);
784   ix86_compare_op0 = operands[0];
785   ix86_compare_op1 = operands[1];
786   DONE;
787 })
788
789 (define_insn "cmpdi_ccno_1_rex64"
790   [(set (reg FLAGS_REG)
791         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
792                  (match_operand:DI 1 "const0_operand" "")))]
793   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
794   "@
795    test{q}\t%0, %0
796    cmp{q}\t{%1, %0|%0, %1}"
797   [(set_attr "type" "test,icmp")
798    (set_attr "length_immediate" "0,1")
799    (set_attr "mode" "DI")])
800
801 (define_insn "*cmpdi_minus_1_rex64"
802   [(set (reg FLAGS_REG)
803         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
804                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
805                  (const_int 0)))]
806   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
807   "cmp{q}\t{%1, %0|%0, %1}"
808   [(set_attr "type" "icmp")
809    (set_attr "mode" "DI")])
810
811 (define_expand "cmpdi_1_rex64"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
814                     (match_operand:DI 1 "general_operand" "")))]
815   "TARGET_64BIT"
816   "")
817
818 (define_insn "cmpdi_1_insn_rex64"
819   [(set (reg FLAGS_REG)
820         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
821                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
822   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
823   "cmp{q}\t{%1, %0|%0, %1}"
824   [(set_attr "type" "icmp")
825    (set_attr "mode" "DI")])
826
827
828 (define_insn "*cmpsi_ccno_1"
829   [(set (reg FLAGS_REG)
830         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
831                  (match_operand:SI 1 "const0_operand" "")))]
832   "ix86_match_ccmode (insn, CCNOmode)"
833   "@
834    test{l}\t%0, %0
835    cmp{l}\t{%1, %0|%0, %1}"
836   [(set_attr "type" "test,icmp")
837    (set_attr "length_immediate" "0,1")
838    (set_attr "mode" "SI")])
839
840 (define_insn "*cmpsi_minus_1"
841   [(set (reg FLAGS_REG)
842         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
843                            (match_operand:SI 1 "general_operand" "ri,mr"))
844                  (const_int 0)))]
845   "ix86_match_ccmode (insn, CCGOCmode)"
846   "cmp{l}\t{%1, %0|%0, %1}"
847   [(set_attr "type" "icmp")
848    (set_attr "mode" "SI")])
849
850 (define_expand "cmpsi_1"
851   [(set (reg:CC FLAGS_REG)
852         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
853                     (match_operand:SI 1 "general_operand" "")))]
854   ""
855   "")
856
857 (define_insn "*cmpsi_1_insn"
858   [(set (reg FLAGS_REG)
859         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
860                  (match_operand:SI 1 "general_operand" "ri,mr")))]
861   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
862     && ix86_match_ccmode (insn, CCmode)"
863   "cmp{l}\t{%1, %0|%0, %1}"
864   [(set_attr "type" "icmp")
865    (set_attr "mode" "SI")])
866
867 (define_insn "*cmphi_ccno_1"
868   [(set (reg FLAGS_REG)
869         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
870                  (match_operand:HI 1 "const0_operand" "")))]
871   "ix86_match_ccmode (insn, CCNOmode)"
872   "@
873    test{w}\t%0, %0
874    cmp{w}\t{%1, %0|%0, %1}"
875   [(set_attr "type" "test,icmp")
876    (set_attr "length_immediate" "0,1")
877    (set_attr "mode" "HI")])
878
879 (define_insn "*cmphi_minus_1"
880   [(set (reg FLAGS_REG)
881         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
882                            (match_operand:HI 1 "general_operand" "rn,mr"))
883                  (const_int 0)))]
884   "ix86_match_ccmode (insn, CCGOCmode)"
885   "cmp{w}\t{%1, %0|%0, %1}"
886   [(set_attr "type" "icmp")
887    (set_attr "mode" "HI")])
888
889 (define_insn "*cmphi_1"
890   [(set (reg FLAGS_REG)
891         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
892                  (match_operand:HI 1 "general_operand" "rn,mr")))]
893   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
894    && ix86_match_ccmode (insn, CCmode)"
895   "cmp{w}\t{%1, %0|%0, %1}"
896   [(set_attr "type" "icmp")
897    (set_attr "mode" "HI")])
898
899 (define_insn "*cmpqi_ccno_1"
900   [(set (reg FLAGS_REG)
901         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
902                  (match_operand:QI 1 "const0_operand" "")))]
903   "ix86_match_ccmode (insn, CCNOmode)"
904   "@
905    test{b}\t%0, %0
906    cmp{b}\t{$0, %0|%0, 0}"
907   [(set_attr "type" "test,icmp")
908    (set_attr "length_immediate" "0,1")
909    (set_attr "mode" "QI")])
910
911 (define_insn "*cmpqi_1"
912   [(set (reg FLAGS_REG)
913         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
914                  (match_operand:QI 1 "general_operand" "qn,mq")))]
915   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
916     && ix86_match_ccmode (insn, CCmode)"
917   "cmp{b}\t{%1, %0|%0, %1}"
918   [(set_attr "type" "icmp")
919    (set_attr "mode" "QI")])
920
921 (define_insn "*cmpqi_minus_1"
922   [(set (reg FLAGS_REG)
923         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
924                            (match_operand:QI 1 "general_operand" "qn,mq"))
925                  (const_int 0)))]
926   "ix86_match_ccmode (insn, CCGOCmode)"
927   "cmp{b}\t{%1, %0|%0, %1}"
928   [(set_attr "type" "icmp")
929    (set_attr "mode" "QI")])
930
931 (define_insn "*cmpqi_ext_1"
932   [(set (reg FLAGS_REG)
933         (compare
934           (match_operand:QI 0 "general_operand" "Qm")
935           (subreg:QI
936             (zero_extract:SI
937               (match_operand 1 "ext_register_operand" "Q")
938               (const_int 8)
939               (const_int 8)) 0)))]
940   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
941   "cmp{b}\t{%h1, %0|%0, %h1}"
942   [(set_attr "type" "icmp")
943    (set_attr "mode" "QI")])
944
945 (define_insn "*cmpqi_ext_1_rex64"
946   [(set (reg FLAGS_REG)
947         (compare
948           (match_operand:QI 0 "register_operand" "Q")
949           (subreg:QI
950             (zero_extract:SI
951               (match_operand 1 "ext_register_operand" "Q")
952               (const_int 8)
953               (const_int 8)) 0)))]
954   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
955   "cmp{b}\t{%h1, %0|%0, %h1}"
956   [(set_attr "type" "icmp")
957    (set_attr "mode" "QI")])
958
959 (define_insn "*cmpqi_ext_2"
960   [(set (reg FLAGS_REG)
961         (compare
962           (subreg:QI
963             (zero_extract:SI
964               (match_operand 0 "ext_register_operand" "Q")
965               (const_int 8)
966               (const_int 8)) 0)
967           (match_operand:QI 1 "const0_operand" "")))]
968   "ix86_match_ccmode (insn, CCNOmode)"
969   "test{b}\t%h0, %h0"
970   [(set_attr "type" "test")
971    (set_attr "length_immediate" "0")
972    (set_attr "mode" "QI")])
973
974 (define_expand "cmpqi_ext_3"
975   [(set (reg:CC FLAGS_REG)
976         (compare:CC
977           (subreg:QI
978             (zero_extract:SI
979               (match_operand 0 "ext_register_operand" "")
980               (const_int 8)
981               (const_int 8)) 0)
982           (match_operand:QI 1 "general_operand" "")))]
983   ""
984   "")
985
986 (define_insn "cmpqi_ext_3_insn"
987   [(set (reg FLAGS_REG)
988         (compare
989           (subreg:QI
990             (zero_extract:SI
991               (match_operand 0 "ext_register_operand" "Q")
992               (const_int 8)
993               (const_int 8)) 0)
994           (match_operand:QI 1 "general_operand" "Qmn")))]
995   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
996   "cmp{b}\t{%1, %h0|%h0, %1}"
997   [(set_attr "type" "icmp")
998    (set_attr "mode" "QI")])
999
1000 (define_insn "cmpqi_ext_3_insn_rex64"
1001   [(set (reg FLAGS_REG)
1002         (compare
1003           (subreg:QI
1004             (zero_extract:SI
1005               (match_operand 0 "ext_register_operand" "Q")
1006               (const_int 8)
1007               (const_int 8)) 0)
1008           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1009   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1010   "cmp{b}\t{%1, %h0|%h0, %1}"
1011   [(set_attr "type" "icmp")
1012    (set_attr "mode" "QI")])
1013
1014 (define_insn "*cmpqi_ext_4"
1015   [(set (reg FLAGS_REG)
1016         (compare
1017           (subreg:QI
1018             (zero_extract:SI
1019               (match_operand 0 "ext_register_operand" "Q")
1020               (const_int 8)
1021               (const_int 8)) 0)
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 1 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)))]
1027   "ix86_match_ccmode (insn, CCmode)"
1028   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1029   [(set_attr "type" "icmp")
1030    (set_attr "mode" "QI")])
1031
1032 ;; These implement float point compares.
1033 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1034 ;; which would allow mix and match FP modes on the compares.  Which is what
1035 ;; the old patterns did, but with many more of them.
1036
1037 (define_expand "cmpxf"
1038   [(set (reg:CC FLAGS_REG)
1039         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1040                     (match_operand:XF 1 "nonmemory_operand" "")))]
1041   "TARGET_80387"
1042 {
1043   ix86_compare_op0 = operands[0];
1044   ix86_compare_op1 = operands[1];
1045   DONE;
1046 })
1047
1048 (define_expand "cmp<mode>"
1049   [(set (reg:CC FLAGS_REG)
1050         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1051                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1052   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1053 {
1054   ix86_compare_op0 = operands[0];
1055   ix86_compare_op1 = operands[1];
1056   DONE;
1057 })
1058
1059 ;; FP compares, step 1:
1060 ;; Set the FP condition codes.
1061 ;;
1062 ;; CCFPmode     compare with exceptions
1063 ;; CCFPUmode    compare with no exceptions
1064
1065 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1066 ;; used to manage the reg stack popping would not be preserved.
1067
1068 (define_insn "*cmpfp_0"
1069   [(set (match_operand:HI 0 "register_operand" "=a")
1070         (unspec:HI
1071           [(compare:CCFP
1072              (match_operand 1 "register_operand" "f")
1073              (match_operand 2 "const0_operand" ""))]
1074         UNSPEC_FNSTSW))]
1075   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1077   "* return output_fp_compare (insn, operands, 0, 0);"
1078   [(set_attr "type" "multi")
1079    (set_attr "unit" "i387")
1080    (set (attr "mode")
1081      (cond [(match_operand:SF 1 "" "")
1082               (const_string "SF")
1083             (match_operand:DF 1 "" "")
1084               (const_string "DF")
1085            ]
1086            (const_string "XF")))])
1087
1088 (define_insn_and_split "*cmpfp_0_cc"
1089   [(set (reg:CCFP FLAGS_REG)
1090         (compare:CCFP
1091           (match_operand 1 "register_operand" "f")
1092           (match_operand 2 "const0_operand" "")))
1093    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1094   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1095    && TARGET_SAHF && !TARGET_CMOVE
1096    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097   "#"
1098   "&& reload_completed"
1099   [(set (match_dup 0)
1100         (unspec:HI
1101           [(compare:CCFP (match_dup 1)(match_dup 2))]
1102         UNSPEC_FNSTSW))
1103    (set (reg:CC FLAGS_REG)
1104         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1105   ""
1106   [(set_attr "type" "multi")
1107    (set_attr "unit" "i387")
1108    (set (attr "mode")
1109      (cond [(match_operand:SF 1 "" "")
1110               (const_string "SF")
1111             (match_operand:DF 1 "" "")
1112               (const_string "DF")
1113            ]
1114            (const_string "XF")))])
1115
1116 (define_insn "*cmpfp_xf"
1117   [(set (match_operand:HI 0 "register_operand" "=a")
1118         (unspec:HI
1119           [(compare:CCFP
1120              (match_operand:XF 1 "register_operand" "f")
1121              (match_operand:XF 2 "register_operand" "f"))]
1122           UNSPEC_FNSTSW))]
1123   "TARGET_80387"
1124   "* return output_fp_compare (insn, operands, 0, 0);"
1125   [(set_attr "type" "multi")
1126    (set_attr "unit" "i387")
1127    (set_attr "mode" "XF")])
1128
1129 (define_insn_and_split "*cmpfp_xf_cc"
1130   [(set (reg:CCFP FLAGS_REG)
1131         (compare:CCFP
1132           (match_operand:XF 1 "register_operand" "f")
1133           (match_operand:XF 2 "register_operand" "f")))
1134    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1135   "TARGET_80387
1136    && TARGET_SAHF && !TARGET_CMOVE"
1137   "#"
1138   "&& reload_completed"
1139   [(set (match_dup 0)
1140         (unspec:HI
1141           [(compare:CCFP (match_dup 1)(match_dup 2))]
1142         UNSPEC_FNSTSW))
1143    (set (reg:CC FLAGS_REG)
1144         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1145   ""
1146   [(set_attr "type" "multi")
1147    (set_attr "unit" "i387")
1148    (set_attr "mode" "XF")])
1149
1150 (define_insn "*cmpfp_<mode>"
1151   [(set (match_operand:HI 0 "register_operand" "=a")
1152         (unspec:HI
1153           [(compare:CCFP
1154              (match_operand:MODEF 1 "register_operand" "f")
1155              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1156           UNSPEC_FNSTSW))]
1157   "TARGET_80387"
1158   "* return output_fp_compare (insn, operands, 0, 0);"
1159   [(set_attr "type" "multi")
1160    (set_attr "unit" "i387")
1161    (set_attr "mode" "<MODE>")])
1162
1163 (define_insn_and_split "*cmpfp_<mode>_cc"
1164   [(set (reg:CCFP FLAGS_REG)
1165         (compare:CCFP
1166           (match_operand:MODEF 1 "register_operand" "f")
1167           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1168    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1169   "TARGET_80387
1170    && TARGET_SAHF && !TARGET_CMOVE"
1171   "#"
1172   "&& reload_completed"
1173   [(set (match_dup 0)
1174         (unspec:HI
1175           [(compare:CCFP (match_dup 1)(match_dup 2))]
1176         UNSPEC_FNSTSW))
1177    (set (reg:CC FLAGS_REG)
1178         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1179   ""
1180   [(set_attr "type" "multi")
1181    (set_attr "unit" "i387")
1182    (set_attr "mode" "<MODE>")])
1183
1184 (define_insn "*cmpfp_u"
1185   [(set (match_operand:HI 0 "register_operand" "=a")
1186         (unspec:HI
1187           [(compare:CCFPU
1188              (match_operand 1 "register_operand" "f")
1189              (match_operand 2 "register_operand" "f"))]
1190           UNSPEC_FNSTSW))]
1191   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1192    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1193   "* return output_fp_compare (insn, operands, 0, 1);"
1194   [(set_attr "type" "multi")
1195    (set_attr "unit" "i387")
1196    (set (attr "mode")
1197      (cond [(match_operand:SF 1 "" "")
1198               (const_string "SF")
1199             (match_operand:DF 1 "" "")
1200               (const_string "DF")
1201            ]
1202            (const_string "XF")))])
1203
1204 (define_insn_and_split "*cmpfp_u_cc"
1205   [(set (reg:CCFPU FLAGS_REG)
1206         (compare:CCFPU
1207           (match_operand 1 "register_operand" "f")
1208           (match_operand 2 "register_operand" "f")))
1209    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1210   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1211    && TARGET_SAHF && !TARGET_CMOVE
1212    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213   "#"
1214   "&& reload_completed"
1215   [(set (match_dup 0)
1216         (unspec:HI
1217           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1218         UNSPEC_FNSTSW))
1219    (set (reg:CC FLAGS_REG)
1220         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1221   ""
1222   [(set_attr "type" "multi")
1223    (set_attr "unit" "i387")
1224    (set (attr "mode")
1225      (cond [(match_operand:SF 1 "" "")
1226               (const_string "SF")
1227             (match_operand:DF 1 "" "")
1228               (const_string "DF")
1229            ]
1230            (const_string "XF")))])
1231
1232 (define_insn "*cmpfp_<mode>"
1233   [(set (match_operand:HI 0 "register_operand" "=a")
1234         (unspec:HI
1235           [(compare:CCFP
1236              (match_operand 1 "register_operand" "f")
1237              (match_operator 3 "float_operator"
1238                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1239           UNSPEC_FNSTSW))]
1240   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1241    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1242    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1243   "* return output_fp_compare (insn, operands, 0, 0);"
1244   [(set_attr "type" "multi")
1245    (set_attr "unit" "i387")
1246    (set_attr "fp_int_src" "true")
1247    (set_attr "mode" "<MODE>")])
1248
1249 (define_insn_and_split "*cmpfp_<mode>_cc"
1250   [(set (reg:CCFP FLAGS_REG)
1251         (compare:CCFP
1252           (match_operand 1 "register_operand" "f")
1253           (match_operator 3 "float_operator"
1254             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1255    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1256   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1257    && TARGET_SAHF && !TARGET_CMOVE
1258    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1259    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1260   "#"
1261   "&& reload_completed"
1262   [(set (match_dup 0)
1263         (unspec:HI
1264           [(compare:CCFP
1265              (match_dup 1)
1266              (match_op_dup 3 [(match_dup 2)]))]
1267         UNSPEC_FNSTSW))
1268    (set (reg:CC FLAGS_REG)
1269         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1270   ""
1271   [(set_attr "type" "multi")
1272    (set_attr "unit" "i387")
1273    (set_attr "fp_int_src" "true")
1274    (set_attr "mode" "<MODE>")])
1275
1276 ;; FP compares, step 2
1277 ;; Move the fpsw to ax.
1278
1279 (define_insn "x86_fnstsw_1"
1280   [(set (match_operand:HI 0 "register_operand" "=a")
1281         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1282   "TARGET_80387"
1283   "fnstsw\t%0"
1284   [(set_attr "length" "2")
1285    (set_attr "mode" "SI")
1286    (set_attr "unit" "i387")])
1287
1288 ;; FP compares, step 3
1289 ;; Get ax into flags, general case.
1290
1291 (define_insn "x86_sahf_1"
1292   [(set (reg:CC FLAGS_REG)
1293         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1294                    UNSPEC_SAHF))]
1295   "TARGET_SAHF"
1296 {
1297 #ifdef HAVE_AS_IX86_SAHF
1298   return "sahf";
1299 #else
1300   return ".byte\t0x9e";
1301 #endif
1302 }
1303   [(set_attr "length" "1")
1304    (set_attr "athlon_decode" "vector")
1305    (set_attr "amdfam10_decode" "direct")
1306    (set_attr "mode" "SI")])
1307
1308 ;; Pentium Pro can do steps 1 through 3 in one go.
1309 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1310 (define_insn "*cmpfp_i_mixed"
1311   [(set (reg:CCFP FLAGS_REG)
1312         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1313                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1314   "TARGET_MIX_SSE_I387
1315    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1316    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1317   "* return output_fp_compare (insn, operands, 1, 0);"
1318   [(set_attr "type" "fcmp,ssecomi")
1319    (set_attr "prefix" "orig,maybe_vex")
1320    (set (attr "mode")
1321      (if_then_else (match_operand:SF 1 "" "")
1322         (const_string "SF")
1323         (const_string "DF")))
1324    (set_attr "athlon_decode" "vector")
1325    (set_attr "amdfam10_decode" "direct")])
1326
1327 (define_insn "*cmpfp_i_sse"
1328   [(set (reg:CCFP FLAGS_REG)
1329         (compare:CCFP (match_operand 0 "register_operand" "x")
1330                       (match_operand 1 "nonimmediate_operand" "xm")))]
1331   "TARGET_SSE_MATH
1332    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1333    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1334   "* return output_fp_compare (insn, operands, 1, 0);"
1335   [(set_attr "type" "ssecomi")
1336    (set_attr "prefix" "maybe_vex")
1337    (set (attr "mode")
1338      (if_then_else (match_operand:SF 1 "" "")
1339         (const_string "SF")
1340         (const_string "DF")))
1341    (set_attr "athlon_decode" "vector")
1342    (set_attr "amdfam10_decode" "direct")])
1343
1344 (define_insn "*cmpfp_i_i387"
1345   [(set (reg:CCFP FLAGS_REG)
1346         (compare:CCFP (match_operand 0 "register_operand" "f")
1347                       (match_operand 1 "register_operand" "f")))]
1348   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1349    && TARGET_CMOVE
1350    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1351    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1352   "* return output_fp_compare (insn, operands, 1, 0);"
1353   [(set_attr "type" "fcmp")
1354    (set (attr "mode")
1355      (cond [(match_operand:SF 1 "" "")
1356               (const_string "SF")
1357             (match_operand:DF 1 "" "")
1358               (const_string "DF")
1359            ]
1360            (const_string "XF")))
1361    (set_attr "athlon_decode" "vector")
1362    (set_attr "amdfam10_decode" "direct")])
1363
1364 (define_insn "*cmpfp_iu_mixed"
1365   [(set (reg:CCFPU FLAGS_REG)
1366         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1367                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1368   "TARGET_MIX_SSE_I387
1369    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1370    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1371   "* return output_fp_compare (insn, operands, 1, 1);"
1372   [(set_attr "type" "fcmp,ssecomi")
1373    (set_attr "prefix" "orig,maybe_vex")
1374    (set (attr "mode")
1375      (if_then_else (match_operand:SF 1 "" "")
1376         (const_string "SF")
1377         (const_string "DF")))
1378    (set_attr "athlon_decode" "vector")
1379    (set_attr "amdfam10_decode" "direct")])
1380
1381 (define_insn "*cmpfp_iu_sse"
1382   [(set (reg:CCFPU FLAGS_REG)
1383         (compare:CCFPU (match_operand 0 "register_operand" "x")
1384                        (match_operand 1 "nonimmediate_operand" "xm")))]
1385   "TARGET_SSE_MATH
1386    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1387    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1388   "* return output_fp_compare (insn, operands, 1, 1);"
1389   [(set_attr "type" "ssecomi")
1390    (set_attr "prefix" "maybe_vex")
1391    (set (attr "mode")
1392      (if_then_else (match_operand:SF 1 "" "")
1393         (const_string "SF")
1394         (const_string "DF")))
1395    (set_attr "athlon_decode" "vector")
1396    (set_attr "amdfam10_decode" "direct")])
1397
1398 (define_insn "*cmpfp_iu_387"
1399   [(set (reg:CCFPU FLAGS_REG)
1400         (compare:CCFPU (match_operand 0 "register_operand" "f")
1401                        (match_operand 1 "register_operand" "f")))]
1402   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1403    && TARGET_CMOVE
1404    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1405    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1406   "* return output_fp_compare (insn, operands, 1, 1);"
1407   [(set_attr "type" "fcmp")
1408    (set (attr "mode")
1409      (cond [(match_operand:SF 1 "" "")
1410               (const_string "SF")
1411             (match_operand:DF 1 "" "")
1412               (const_string "DF")
1413            ]
1414            (const_string "XF")))
1415    (set_attr "athlon_decode" "vector")
1416    (set_attr "amdfam10_decode" "direct")])
1417 \f
1418 ;; Move instructions.
1419
1420 ;; General case of fullword move.
1421
1422 (define_expand "movsi"
1423   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1424         (match_operand:SI 1 "general_operand" ""))]
1425   ""
1426   "ix86_expand_move (SImode, operands); DONE;")
1427
1428 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1429 ;; general_operand.
1430 ;;
1431 ;; %%% We don't use a post-inc memory reference because x86 is not a
1432 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1433 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1434 ;; targets without our curiosities, and it is just as easy to represent
1435 ;; this differently.
1436
1437 (define_insn "*pushsi2"
1438   [(set (match_operand:SI 0 "push_operand" "=<")
1439         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1440   "!TARGET_64BIT"
1441   "push{l}\t%1"
1442   [(set_attr "type" "push")
1443    (set_attr "mode" "SI")])
1444
1445 ;; For 64BIT abi we always round up to 8 bytes.
1446 (define_insn "*pushsi2_rex64"
1447   [(set (match_operand:SI 0 "push_operand" "=X")
1448         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1449   "TARGET_64BIT"
1450   "push{q}\t%q1"
1451   [(set_attr "type" "push")
1452    (set_attr "mode" "SI")])
1453
1454 (define_insn "*pushsi2_prologue"
1455   [(set (match_operand:SI 0 "push_operand" "=<")
1456         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1457    (clobber (mem:BLK (scratch)))]
1458   "!TARGET_64BIT"
1459   "push{l}\t%1"
1460   [(set_attr "type" "push")
1461    (set_attr "mode" "SI")])
1462
1463 (define_insn "*popsi1_epilogue"
1464   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1465         (mem:SI (reg:SI SP_REG)))
1466    (set (reg:SI SP_REG)
1467         (plus:SI (reg:SI SP_REG) (const_int 4)))
1468    (clobber (mem:BLK (scratch)))]
1469   "!TARGET_64BIT"
1470   "pop{l}\t%0"
1471   [(set_attr "type" "pop")
1472    (set_attr "mode" "SI")])
1473
1474 (define_insn "popsi1"
1475   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1476         (mem:SI (reg:SI SP_REG)))
1477    (set (reg:SI SP_REG)
1478         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1479   "!TARGET_64BIT"
1480   "pop{l}\t%0"
1481   [(set_attr "type" "pop")
1482    (set_attr "mode" "SI")])
1483
1484 (define_insn "*movsi_xor"
1485   [(set (match_operand:SI 0 "register_operand" "=r")
1486         (match_operand:SI 1 "const0_operand" ""))
1487    (clobber (reg:CC FLAGS_REG))]
1488   "reload_completed"
1489   "xor{l}\t%0, %0"
1490   [(set_attr "type" "alu1")
1491    (set_attr "mode" "SI")
1492    (set_attr "length_immediate" "0")])
1493
1494 (define_insn "*movsi_or"
1495   [(set (match_operand:SI 0 "register_operand" "=r")
1496         (match_operand:SI 1 "immediate_operand" "i"))
1497    (clobber (reg:CC FLAGS_REG))]
1498   "reload_completed
1499    && operands[1] == constm1_rtx"
1500 {
1501   operands[1] = constm1_rtx;
1502   return "or{l}\t{%1, %0|%0, %1}";
1503 }
1504   [(set_attr "type" "alu1")
1505    (set_attr "mode" "SI")
1506    (set_attr "length_immediate" "1")])
1507
1508 (define_insn "*movsi_1"
1509   [(set (match_operand:SI 0 "nonimmediate_operand"
1510                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1511         (match_operand:SI 1 "general_operand"
1512                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1513   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1514 {
1515   switch (get_attr_type (insn))
1516     {
1517     case TYPE_SSELOG1:
1518       if (get_attr_mode (insn) == MODE_TI)
1519         return "%vpxor\t%0, %d0";
1520       return "%vxorps\t%0, %d0";
1521
1522     case TYPE_SSEMOV:
1523       switch (get_attr_mode (insn))
1524         {
1525         case MODE_TI:
1526           return "%vmovdqa\t{%1, %0|%0, %1}";
1527         case MODE_V4SF:
1528           return "%vmovaps\t{%1, %0|%0, %1}";
1529         case MODE_SI:
1530           return "%vmovd\t{%1, %0|%0, %1}";
1531         case MODE_SF:
1532           return "%vmovss\t{%1, %0|%0, %1}";
1533         default:
1534           gcc_unreachable ();
1535         }
1536
1537     case TYPE_MMX:
1538       return "pxor\t%0, %0";
1539
1540     case TYPE_MMXMOV:
1541       if (get_attr_mode (insn) == MODE_DI)
1542         return "movq\t{%1, %0|%0, %1}";
1543       return "movd\t{%1, %0|%0, %1}";
1544
1545     case TYPE_LEA:
1546       return "lea{l}\t{%1, %0|%0, %1}";
1547
1548     default:
1549       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1550       return "mov{l}\t{%1, %0|%0, %1}";
1551     }
1552 }
1553   [(set (attr "type")
1554      (cond [(eq_attr "alternative" "2")
1555               (const_string "mmx")
1556             (eq_attr "alternative" "3,4,5")
1557               (const_string "mmxmov")
1558             (eq_attr "alternative" "6")
1559               (const_string "sselog1")
1560             (eq_attr "alternative" "7,8,9,10,11")
1561               (const_string "ssemov")
1562             (match_operand:DI 1 "pic_32bit_operand" "")
1563               (const_string "lea")
1564            ]
1565            (const_string "imov")))
1566    (set (attr "prefix")
1567      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1568        (const_string "orig")
1569        (const_string "maybe_vex")))
1570    (set (attr "mode")
1571      (cond [(eq_attr "alternative" "2,3")
1572               (const_string "DI")
1573             (eq_attr "alternative" "6,7")
1574               (if_then_else
1575                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1576                 (const_string "V4SF")
1577                 (const_string "TI"))
1578             (and (eq_attr "alternative" "8,9,10,11")
1579                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1580               (const_string "SF")
1581            ]
1582            (const_string "SI")))])
1583
1584 ;; Stores and loads of ax to arbitrary constant address.
1585 ;; We fake an second form of instruction to force reload to load address
1586 ;; into register when rax is not available
1587 (define_insn "*movabssi_1_rex64"
1588   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1589         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1590   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1591   "@
1592    movabs{l}\t{%1, %P0|%P0, %1}
1593    mov{l}\t{%1, %a0|%a0, %1}"
1594   [(set_attr "type" "imov")
1595    (set_attr "modrm" "0,*")
1596    (set_attr "length_address" "8,0")
1597    (set_attr "length_immediate" "0,*")
1598    (set_attr "memory" "store")
1599    (set_attr "mode" "SI")])
1600
1601 (define_insn "*movabssi_2_rex64"
1602   [(set (match_operand:SI 0 "register_operand" "=a,r")
1603         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1604   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1605   "@
1606    movabs{l}\t{%P1, %0|%0, %P1}
1607    mov{l}\t{%a1, %0|%0, %a1}"
1608   [(set_attr "type" "imov")
1609    (set_attr "modrm" "0,*")
1610    (set_attr "length_address" "8,0")
1611    (set_attr "length_immediate" "0")
1612    (set_attr "memory" "load")
1613    (set_attr "mode" "SI")])
1614
1615 (define_insn "*swapsi"
1616   [(set (match_operand:SI 0 "register_operand" "+r")
1617         (match_operand:SI 1 "register_operand" "+r"))
1618    (set (match_dup 1)
1619         (match_dup 0))]
1620   ""
1621   "xchg{l}\t%1, %0"
1622   [(set_attr "type" "imov")
1623    (set_attr "mode" "SI")
1624    (set_attr "pent_pair" "np")
1625    (set_attr "athlon_decode" "vector")
1626    (set_attr "amdfam10_decode" "double")])
1627
1628 (define_expand "movhi"
1629   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1630         (match_operand:HI 1 "general_operand" ""))]
1631   ""
1632   "ix86_expand_move (HImode, operands); DONE;")
1633
1634 (define_insn "*pushhi2"
1635   [(set (match_operand:HI 0 "push_operand" "=X")
1636         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1637   "!TARGET_64BIT"
1638   "push{l}\t%k1"
1639   [(set_attr "type" "push")
1640    (set_attr "mode" "SI")])
1641
1642 ;; For 64BIT abi we always round up to 8 bytes.
1643 (define_insn "*pushhi2_rex64"
1644   [(set (match_operand:HI 0 "push_operand" "=X")
1645         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1646   "TARGET_64BIT"
1647   "push{q}\t%q1"
1648   [(set_attr "type" "push")
1649    (set_attr "mode" "DI")])
1650
1651 (define_insn "*movhi_1"
1652   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1653         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1654   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1655 {
1656   switch (get_attr_type (insn))
1657     {
1658     case TYPE_IMOVX:
1659       /* movzwl is faster than movw on p2 due to partial word stalls,
1660          though not as fast as an aligned movl.  */
1661       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1662     default:
1663       if (get_attr_mode (insn) == MODE_SI)
1664         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1665       else
1666         return "mov{w}\t{%1, %0|%0, %1}";
1667     }
1668 }
1669   [(set (attr "type")
1670      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1671               (const_string "imov")
1672             (and (eq_attr "alternative" "0")
1673                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1674                           (const_int 0))
1675                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1676                           (const_int 0))))
1677               (const_string "imov")
1678             (and (eq_attr "alternative" "1,2")
1679                  (match_operand:HI 1 "aligned_operand" ""))
1680               (const_string "imov")
1681             (and (ne (symbol_ref "TARGET_MOVX")
1682                      (const_int 0))
1683                  (eq_attr "alternative" "0,2"))
1684               (const_string "imovx")
1685            ]
1686            (const_string "imov")))
1687     (set (attr "mode")
1688       (cond [(eq_attr "type" "imovx")
1689                (const_string "SI")
1690              (and (eq_attr "alternative" "1,2")
1691                   (match_operand:HI 1 "aligned_operand" ""))
1692                (const_string "SI")
1693              (and (eq_attr "alternative" "0")
1694                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1695                            (const_int 0))
1696                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1697                            (const_int 0))))
1698                (const_string "SI")
1699             ]
1700             (const_string "HI")))])
1701
1702 ;; Stores and loads of ax to arbitrary constant address.
1703 ;; We fake an second form of instruction to force reload to load address
1704 ;; into register when rax is not available
1705 (define_insn "*movabshi_1_rex64"
1706   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1707         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1708   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1709   "@
1710    movabs{w}\t{%1, %P0|%P0, %1}
1711    mov{w}\t{%1, %a0|%a0, %1}"
1712   [(set_attr "type" "imov")
1713    (set_attr "modrm" "0,*")
1714    (set_attr "length_address" "8,0")
1715    (set_attr "length_immediate" "0,*")
1716    (set_attr "memory" "store")
1717    (set_attr "mode" "HI")])
1718
1719 (define_insn "*movabshi_2_rex64"
1720   [(set (match_operand:HI 0 "register_operand" "=a,r")
1721         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1722   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1723   "@
1724    movabs{w}\t{%P1, %0|%0, %P1}
1725    mov{w}\t{%a1, %0|%0, %a1}"
1726   [(set_attr "type" "imov")
1727    (set_attr "modrm" "0,*")
1728    (set_attr "length_address" "8,0")
1729    (set_attr "length_immediate" "0")
1730    (set_attr "memory" "load")
1731    (set_attr "mode" "HI")])
1732
1733 (define_insn "*swaphi_1"
1734   [(set (match_operand:HI 0 "register_operand" "+r")
1735         (match_operand:HI 1 "register_operand" "+r"))
1736    (set (match_dup 1)
1737         (match_dup 0))]
1738   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1739   "xchg{l}\t%k1, %k0"
1740   [(set_attr "type" "imov")
1741    (set_attr "mode" "SI")
1742    (set_attr "pent_pair" "np")
1743    (set_attr "athlon_decode" "vector")
1744    (set_attr "amdfam10_decode" "double")])
1745
1746 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1747 (define_insn "*swaphi_2"
1748   [(set (match_operand:HI 0 "register_operand" "+r")
1749         (match_operand:HI 1 "register_operand" "+r"))
1750    (set (match_dup 1)
1751         (match_dup 0))]
1752   "TARGET_PARTIAL_REG_STALL"
1753   "xchg{w}\t%1, %0"
1754   [(set_attr "type" "imov")
1755    (set_attr "mode" "HI")
1756    (set_attr "pent_pair" "np")
1757    (set_attr "athlon_decode" "vector")])
1758
1759 (define_expand "movstricthi"
1760   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1761         (match_operand:HI 1 "general_operand" ""))]
1762   ""
1763 {
1764   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1765     FAIL;
1766   /* Don't generate memory->memory moves, go through a register */
1767   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1768     operands[1] = force_reg (HImode, operands[1]);
1769 })
1770
1771 (define_insn "*movstricthi_1"
1772   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1773         (match_operand:HI 1 "general_operand" "rn,m"))]
1774   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1775    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1776   "mov{w}\t{%1, %0|%0, %1}"
1777   [(set_attr "type" "imov")
1778    (set_attr "mode" "HI")])
1779
1780 (define_insn "*movstricthi_xor"
1781   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1782         (match_operand:HI 1 "const0_operand" ""))
1783    (clobber (reg:CC FLAGS_REG))]
1784   "reload_completed"
1785   "xor{w}\t%0, %0"
1786   [(set_attr "type" "alu1")
1787    (set_attr "mode" "HI")
1788    (set_attr "length_immediate" "0")])
1789
1790 (define_expand "movqi"
1791   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1792         (match_operand:QI 1 "general_operand" ""))]
1793   ""
1794   "ix86_expand_move (QImode, operands); DONE;")
1795
1796 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1797 ;; "push a byte".  But actually we use pushl, which has the effect
1798 ;; of rounding the amount pushed up to a word.
1799
1800 (define_insn "*pushqi2"
1801   [(set (match_operand:QI 0 "push_operand" "=X")
1802         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1803   "!TARGET_64BIT"
1804   "push{l}\t%k1"
1805   [(set_attr "type" "push")
1806    (set_attr "mode" "SI")])
1807
1808 ;; For 64BIT abi we always round up to 8 bytes.
1809 (define_insn "*pushqi2_rex64"
1810   [(set (match_operand:QI 0 "push_operand" "=X")
1811         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1812   "TARGET_64BIT"
1813   "push{q}\t%q1"
1814   [(set_attr "type" "push")
1815    (set_attr "mode" "DI")])
1816
1817 ;; Situation is quite tricky about when to choose full sized (SImode) move
1818 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1819 ;; partial register dependency machines (such as AMD Athlon), where QImode
1820 ;; moves issue extra dependency and for partial register stalls machines
1821 ;; that don't use QImode patterns (and QImode move cause stall on the next
1822 ;; instruction).
1823 ;;
1824 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1825 ;; register stall machines with, where we use QImode instructions, since
1826 ;; partial register stall can be caused there.  Then we use movzx.
1827 (define_insn "*movqi_1"
1828   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1829         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1830   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831 {
1832   switch (get_attr_type (insn))
1833     {
1834     case TYPE_IMOVX:
1835       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1836       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1837     default:
1838       if (get_attr_mode (insn) == MODE_SI)
1839         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1840       else
1841         return "mov{b}\t{%1, %0|%0, %1}";
1842     }
1843 }
1844   [(set (attr "type")
1845      (cond [(and (eq_attr "alternative" "5")
1846                  (not (match_operand:QI 1 "aligned_operand" "")))
1847               (const_string "imovx")
1848             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1849               (const_string "imov")
1850             (and (eq_attr "alternative" "3")
1851                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1852                           (const_int 0))
1853                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1854                           (const_int 0))))
1855               (const_string "imov")
1856             (eq_attr "alternative" "3,5")
1857               (const_string "imovx")
1858             (and (ne (symbol_ref "TARGET_MOVX")
1859                      (const_int 0))
1860                  (eq_attr "alternative" "2"))
1861               (const_string "imovx")
1862            ]
1863            (const_string "imov")))
1864    (set (attr "mode")
1865       (cond [(eq_attr "alternative" "3,4,5")
1866                (const_string "SI")
1867              (eq_attr "alternative" "6")
1868                (const_string "QI")
1869              (eq_attr "type" "imovx")
1870                (const_string "SI")
1871              (and (eq_attr "type" "imov")
1872                   (and (eq_attr "alternative" "0,1")
1873                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1874                                 (const_int 0))
1875                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1876                                      (const_int 0))
1877                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1878                                      (const_int 0))))))
1879                (const_string "SI")
1880              ;; Avoid partial register stalls when not using QImode arithmetic
1881              (and (eq_attr "type" "imov")
1882                   (and (eq_attr "alternative" "0,1")
1883                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1884                                 (const_int 0))
1885                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1886                                 (const_int 0)))))
1887                (const_string "SI")
1888            ]
1889            (const_string "QI")))])
1890
1891 (define_insn "*swapqi_1"
1892   [(set (match_operand:QI 0 "register_operand" "+r")
1893         (match_operand:QI 1 "register_operand" "+r"))
1894    (set (match_dup 1)
1895         (match_dup 0))]
1896   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1897   "xchg{l}\t%k1, %k0"
1898   [(set_attr "type" "imov")
1899    (set_attr "mode" "SI")
1900    (set_attr "pent_pair" "np")
1901    (set_attr "athlon_decode" "vector")
1902    (set_attr "amdfam10_decode" "vector")])
1903
1904 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1905 (define_insn "*swapqi_2"
1906   [(set (match_operand:QI 0 "register_operand" "+q")
1907         (match_operand:QI 1 "register_operand" "+q"))
1908    (set (match_dup 1)
1909         (match_dup 0))]
1910   "TARGET_PARTIAL_REG_STALL"
1911   "xchg{b}\t%1, %0"
1912   [(set_attr "type" "imov")
1913    (set_attr "mode" "QI")
1914    (set_attr "pent_pair" "np")
1915    (set_attr "athlon_decode" "vector")])
1916
1917 (define_expand "movstrictqi"
1918   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1919         (match_operand:QI 1 "general_operand" ""))]
1920   ""
1921 {
1922   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1923     FAIL;
1924   /* Don't generate memory->memory moves, go through a register.  */
1925   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1926     operands[1] = force_reg (QImode, operands[1]);
1927 })
1928
1929 (define_insn "*movstrictqi_1"
1930   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1931         (match_operand:QI 1 "general_operand" "*qn,m"))]
1932   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1933    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1934   "mov{b}\t{%1, %0|%0, %1}"
1935   [(set_attr "type" "imov")
1936    (set_attr "mode" "QI")])
1937
1938 (define_insn "*movstrictqi_xor"
1939   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1940         (match_operand:QI 1 "const0_operand" ""))
1941    (clobber (reg:CC FLAGS_REG))]
1942   "reload_completed"
1943   "xor{b}\t%0, %0"
1944   [(set_attr "type" "alu1")
1945    (set_attr "mode" "QI")
1946    (set_attr "length_immediate" "0")])
1947
1948 (define_insn "*movsi_extv_1"
1949   [(set (match_operand:SI 0 "register_operand" "=R")
1950         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1951                          (const_int 8)
1952                          (const_int 8)))]
1953   ""
1954   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1955   [(set_attr "type" "imovx")
1956    (set_attr "mode" "SI")])
1957
1958 (define_insn "*movhi_extv_1"
1959   [(set (match_operand:HI 0 "register_operand" "=R")
1960         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1961                          (const_int 8)
1962                          (const_int 8)))]
1963   ""
1964   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1965   [(set_attr "type" "imovx")
1966    (set_attr "mode" "SI")])
1967
1968 (define_insn "*movqi_extv_1"
1969   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1970         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1971                          (const_int 8)
1972                          (const_int 8)))]
1973   "!TARGET_64BIT"
1974 {
1975   switch (get_attr_type (insn))
1976     {
1977     case TYPE_IMOVX:
1978       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1979     default:
1980       return "mov{b}\t{%h1, %0|%0, %h1}";
1981     }
1982 }
1983   [(set (attr "type")
1984      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1985                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1986                              (ne (symbol_ref "TARGET_MOVX")
1987                                  (const_int 0))))
1988         (const_string "imovx")
1989         (const_string "imov")))
1990    (set (attr "mode")
1991      (if_then_else (eq_attr "type" "imovx")
1992         (const_string "SI")
1993         (const_string "QI")))])
1994
1995 (define_insn "*movqi_extv_1_rex64"
1996   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1997         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1998                          (const_int 8)
1999                          (const_int 8)))]
2000   "TARGET_64BIT"
2001 {
2002   switch (get_attr_type (insn))
2003     {
2004     case TYPE_IMOVX:
2005       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2006     default:
2007       return "mov{b}\t{%h1, %0|%0, %h1}";
2008     }
2009 }
2010   [(set (attr "type")
2011      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2012                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2013                              (ne (symbol_ref "TARGET_MOVX")
2014                                  (const_int 0))))
2015         (const_string "imovx")
2016         (const_string "imov")))
2017    (set (attr "mode")
2018      (if_then_else (eq_attr "type" "imovx")
2019         (const_string "SI")
2020         (const_string "QI")))])
2021
2022 ;; Stores and loads of ax to arbitrary constant address.
2023 ;; We fake an second form of instruction to force reload to load address
2024 ;; into register when rax is not available
2025 (define_insn "*movabsqi_1_rex64"
2026   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2027         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2028   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2029   "@
2030    movabs{b}\t{%1, %P0|%P0, %1}
2031    mov{b}\t{%1, %a0|%a0, %1}"
2032   [(set_attr "type" "imov")
2033    (set_attr "modrm" "0,*")
2034    (set_attr "length_address" "8,0")
2035    (set_attr "length_immediate" "0,*")
2036    (set_attr "memory" "store")
2037    (set_attr "mode" "QI")])
2038
2039 (define_insn "*movabsqi_2_rex64"
2040   [(set (match_operand:QI 0 "register_operand" "=a,r")
2041         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2042   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2043   "@
2044    movabs{b}\t{%P1, %0|%0, %P1}
2045    mov{b}\t{%a1, %0|%0, %a1}"
2046   [(set_attr "type" "imov")
2047    (set_attr "modrm" "0,*")
2048    (set_attr "length_address" "8,0")
2049    (set_attr "length_immediate" "0")
2050    (set_attr "memory" "load")
2051    (set_attr "mode" "QI")])
2052
2053 (define_insn "*movdi_extzv_1"
2054   [(set (match_operand:DI 0 "register_operand" "=R")
2055         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2056                          (const_int 8)
2057                          (const_int 8)))]
2058   "TARGET_64BIT"
2059   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2060   [(set_attr "type" "imovx")
2061    (set_attr "mode" "DI")])
2062
2063 (define_insn "*movsi_extzv_1"
2064   [(set (match_operand:SI 0 "register_operand" "=R")
2065         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2066                          (const_int 8)
2067                          (const_int 8)))]
2068   ""
2069   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2070   [(set_attr "type" "imovx")
2071    (set_attr "mode" "SI")])
2072
2073 (define_insn "*movqi_extzv_2"
2074   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2075         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2076                                     (const_int 8)
2077                                     (const_int 8)) 0))]
2078   "!TARGET_64BIT"
2079 {
2080   switch (get_attr_type (insn))
2081     {
2082     case TYPE_IMOVX:
2083       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2084     default:
2085       return "mov{b}\t{%h1, %0|%0, %h1}";
2086     }
2087 }
2088   [(set (attr "type")
2089      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2090                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2091                              (ne (symbol_ref "TARGET_MOVX")
2092                                  (const_int 0))))
2093         (const_string "imovx")
2094         (const_string "imov")))
2095    (set (attr "mode")
2096      (if_then_else (eq_attr "type" "imovx")
2097         (const_string "SI")
2098         (const_string "QI")))])
2099
2100 (define_insn "*movqi_extzv_2_rex64"
2101   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2102         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2103                                     (const_int 8)
2104                                     (const_int 8)) 0))]
2105   "TARGET_64BIT"
2106 {
2107   switch (get_attr_type (insn))
2108     {
2109     case TYPE_IMOVX:
2110       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2111     default:
2112       return "mov{b}\t{%h1, %0|%0, %h1}";
2113     }
2114 }
2115   [(set (attr "type")
2116      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2117                         (ne (symbol_ref "TARGET_MOVX")
2118                             (const_int 0)))
2119         (const_string "imovx")
2120         (const_string "imov")))
2121    (set (attr "mode")
2122      (if_then_else (eq_attr "type" "imovx")
2123         (const_string "SI")
2124         (const_string "QI")))])
2125
2126 (define_insn "movsi_insv_1"
2127   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2128                          (const_int 8)
2129                          (const_int 8))
2130         (match_operand:SI 1 "general_operand" "Qmn"))]
2131   "!TARGET_64BIT"
2132   "mov{b}\t{%b1, %h0|%h0, %b1}"
2133   [(set_attr "type" "imov")
2134    (set_attr "mode" "QI")])
2135
2136 (define_insn "*movsi_insv_1_rex64"
2137   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2138                          (const_int 8)
2139                          (const_int 8))
2140         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2141   "TARGET_64BIT"
2142   "mov{b}\t{%b1, %h0|%h0, %b1}"
2143   [(set_attr "type" "imov")
2144    (set_attr "mode" "QI")])
2145
2146 (define_insn "movdi_insv_1_rex64"
2147   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2148                          (const_int 8)
2149                          (const_int 8))
2150         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2151   "TARGET_64BIT"
2152   "mov{b}\t{%b1, %h0|%h0, %b1}"
2153   [(set_attr "type" "imov")
2154    (set_attr "mode" "QI")])
2155
2156 (define_insn "*movqi_insv_2"
2157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2158                          (const_int 8)
2159                          (const_int 8))
2160         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2161                      (const_int 8)))]
2162   ""
2163   "mov{b}\t{%h1, %h0|%h0, %h1}"
2164   [(set_attr "type" "imov")
2165    (set_attr "mode" "QI")])
2166
2167 (define_expand "movdi"
2168   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2169         (match_operand:DI 1 "general_operand" ""))]
2170   ""
2171   "ix86_expand_move (DImode, operands); DONE;")
2172
2173 (define_insn "*pushdi"
2174   [(set (match_operand:DI 0 "push_operand" "=<")
2175         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2176   "!TARGET_64BIT"
2177   "#")
2178
2179 (define_insn "*pushdi2_rex64"
2180   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2181         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2182   "TARGET_64BIT"
2183   "@
2184    push{q}\t%1
2185    #"
2186   [(set_attr "type" "push,multi")
2187    (set_attr "mode" "DI")])
2188
2189 ;; Convert impossible pushes of immediate to existing instructions.
2190 ;; First try to get scratch register and go through it.  In case this
2191 ;; fails, push sign extended lower part first and then overwrite
2192 ;; upper part by 32bit move.
2193 (define_peephole2
2194   [(match_scratch:DI 2 "r")
2195    (set (match_operand:DI 0 "push_operand" "")
2196         (match_operand:DI 1 "immediate_operand" ""))]
2197   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2198    && !x86_64_immediate_operand (operands[1], DImode)"
2199   [(set (match_dup 2) (match_dup 1))
2200    (set (match_dup 0) (match_dup 2))]
2201   "")
2202
2203 ;; We need to define this as both peepholer and splitter for case
2204 ;; peephole2 pass is not run.
2205 ;; "&& 1" is needed to keep it from matching the previous pattern.
2206 (define_peephole2
2207   [(set (match_operand:DI 0 "push_operand" "")
2208         (match_operand:DI 1 "immediate_operand" ""))]
2209   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2210    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2211   [(set (match_dup 0) (match_dup 1))
2212    (set (match_dup 2) (match_dup 3))]
2213   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2214    operands[1] = gen_lowpart (DImode, operands[2]);
2215    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2216                                                     GEN_INT (4)));
2217   ")
2218
2219 (define_split
2220   [(set (match_operand:DI 0 "push_operand" "")
2221         (match_operand:DI 1 "immediate_operand" ""))]
2222   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2223                     ? epilogue_completed : reload_completed)
2224    && !symbolic_operand (operands[1], DImode)
2225    && !x86_64_immediate_operand (operands[1], DImode)"
2226   [(set (match_dup 0) (match_dup 1))
2227    (set (match_dup 2) (match_dup 3))]
2228   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2229    operands[1] = gen_lowpart (DImode, operands[2]);
2230    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2231                                                     GEN_INT (4)));
2232   ")
2233
2234 (define_insn "*pushdi2_prologue_rex64"
2235   [(set (match_operand:DI 0 "push_operand" "=<")
2236         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2237    (clobber (mem:BLK (scratch)))]
2238   "TARGET_64BIT"
2239   "push{q}\t%1"
2240   [(set_attr "type" "push")
2241    (set_attr "mode" "DI")])
2242
2243 (define_insn "*popdi1_epilogue_rex64"
2244   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2245         (mem:DI (reg:DI SP_REG)))
2246    (set (reg:DI SP_REG)
2247         (plus:DI (reg:DI SP_REG) (const_int 8)))
2248    (clobber (mem:BLK (scratch)))]
2249   "TARGET_64BIT"
2250   "pop{q}\t%0"
2251   [(set_attr "type" "pop")
2252    (set_attr "mode" "DI")])
2253
2254 (define_insn "popdi1"
2255   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2256         (mem:DI (reg:DI SP_REG)))
2257    (set (reg:DI SP_REG)
2258         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2259   "TARGET_64BIT"
2260   "pop{q}\t%0"
2261   [(set_attr "type" "pop")
2262    (set_attr "mode" "DI")])
2263
2264 (define_insn "*movdi_xor_rex64"
2265   [(set (match_operand:DI 0 "register_operand" "=r")
2266         (match_operand:DI 1 "const0_operand" ""))
2267    (clobber (reg:CC FLAGS_REG))]
2268   "TARGET_64BIT
2269    && reload_completed"
2270   "xor{l}\t%k0, %k0";
2271   [(set_attr "type" "alu1")
2272    (set_attr "mode" "SI")
2273    (set_attr "length_immediate" "0")])
2274
2275 (define_insn "*movdi_or_rex64"
2276   [(set (match_operand:DI 0 "register_operand" "=r")
2277         (match_operand:DI 1 "const_int_operand" "i"))
2278    (clobber (reg:CC FLAGS_REG))]
2279   "TARGET_64BIT
2280    && reload_completed
2281    && operands[1] == constm1_rtx"
2282 {
2283   operands[1] = constm1_rtx;
2284   return "or{q}\t{%1, %0|%0, %1}";
2285 }
2286   [(set_attr "type" "alu1")
2287    (set_attr "mode" "DI")
2288    (set_attr "length_immediate" "1")])
2289
2290 (define_insn "*movdi_2"
2291   [(set (match_operand:DI 0 "nonimmediate_operand"
2292                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2293         (match_operand:DI 1 "general_operand"
2294                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2295   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2296   "@
2297    #
2298    #
2299    pxor\t%0, %0
2300    movq\t{%1, %0|%0, %1}
2301    movq\t{%1, %0|%0, %1}
2302    %vpxor\t%0, %d0
2303    %vmovq\t{%1, %0|%0, %1}
2304    %vmovdqa\t{%1, %0|%0, %1}
2305    %vmovq\t{%1, %0|%0, %1}
2306    xorps\t%0, %0
2307    movlps\t{%1, %0|%0, %1}
2308    movaps\t{%1, %0|%0, %1}
2309    movlps\t{%1, %0|%0, %1}"
2310   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2311    (set (attr "prefix")
2312      (if_then_else (eq_attr "alternative" "5,6,7,8")
2313        (const_string "vex")
2314        (const_string "orig")))
2315    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2316
2317 (define_split
2318   [(set (match_operand:DI 0 "push_operand" "")
2319         (match_operand:DI 1 "general_operand" ""))]
2320   "!TARGET_64BIT && reload_completed
2321    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2322   [(const_int 0)]
2323   "ix86_split_long_move (operands); DONE;")
2324
2325 ;; %%% This multiword shite has got to go.
2326 (define_split
2327   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2328         (match_operand:DI 1 "general_operand" ""))]
2329   "!TARGET_64BIT && reload_completed
2330    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2331    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2332   [(const_int 0)]
2333   "ix86_split_long_move (operands); DONE;")
2334
2335 (define_insn "*movdi_1_rex64"
2336   [(set (match_operand:DI 0 "nonimmediate_operand"
2337           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2338         (match_operand:DI 1 "general_operand"
2339           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2340   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2341 {
2342   switch (get_attr_type (insn))
2343     {
2344     case TYPE_SSECVT:
2345       if (SSE_REG_P (operands[0]))
2346         return "movq2dq\t{%1, %0|%0, %1}";
2347       else
2348         return "movdq2q\t{%1, %0|%0, %1}";
2349
2350     case TYPE_SSEMOV:
2351       if (TARGET_AVX)
2352         {
2353           if (get_attr_mode (insn) == MODE_TI)
2354             return "vmovdqa\t{%1, %0|%0, %1}";
2355           else
2356             return "vmovq\t{%1, %0|%0, %1}";
2357         }
2358
2359       if (get_attr_mode (insn) == MODE_TI)
2360         return "movdqa\t{%1, %0|%0, %1}";
2361       /* FALLTHRU */
2362
2363     case TYPE_MMXMOV:
2364       /* Moves from and into integer register is done using movd
2365          opcode with REX prefix.  */
2366       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2367         return "movd\t{%1, %0|%0, %1}";
2368       return "movq\t{%1, %0|%0, %1}";
2369
2370     case TYPE_SSELOG1:
2371       return "%vpxor\t%0, %d0";
2372
2373     case TYPE_MMX:
2374       return "pxor\t%0, %0";
2375
2376     case TYPE_MULTI:
2377       return "#";
2378
2379     case TYPE_LEA:
2380       return "lea{q}\t{%a1, %0|%0, %a1}";
2381
2382     default:
2383       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2384       if (get_attr_mode (insn) == MODE_SI)
2385         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2386       else if (which_alternative == 2)
2387         return "movabs{q}\t{%1, %0|%0, %1}";
2388       else
2389         return "mov{q}\t{%1, %0|%0, %1}";
2390     }
2391 }
2392   [(set (attr "type")
2393      (cond [(eq_attr "alternative" "5")
2394               (const_string "mmx")
2395             (eq_attr "alternative" "6,7,8,9,10")
2396               (const_string "mmxmov")
2397             (eq_attr "alternative" "11")
2398               (const_string "sselog1")
2399             (eq_attr "alternative" "12,13,14,15,16")
2400               (const_string "ssemov")
2401             (eq_attr "alternative" "17,18")
2402               (const_string "ssecvt")
2403             (eq_attr "alternative" "4")
2404               (const_string "multi")
2405             (match_operand:DI 1 "pic_32bit_operand" "")
2406               (const_string "lea")
2407            ]
2408            (const_string "imov")))
2409    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2410    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411    (set (attr "prefix")
2412      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2413        (const_string "maybe_vex")
2414        (const_string "orig")))
2415    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2416
2417 ;; Stores and loads of ax to arbitrary constant address.
2418 ;; We fake an second form of instruction to force reload to load address
2419 ;; into register when rax is not available
2420 (define_insn "*movabsdi_1_rex64"
2421   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2422         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2423   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2424   "@
2425    movabs{q}\t{%1, %P0|%P0, %1}
2426    mov{q}\t{%1, %a0|%a0, %1}"
2427   [(set_attr "type" "imov")
2428    (set_attr "modrm" "0,*")
2429    (set_attr "length_address" "8,0")
2430    (set_attr "length_immediate" "0,*")
2431    (set_attr "memory" "store")
2432    (set_attr "mode" "DI")])
2433
2434 (define_insn "*movabsdi_2_rex64"
2435   [(set (match_operand:DI 0 "register_operand" "=a,r")
2436         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2437   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2438   "@
2439    movabs{q}\t{%P1, %0|%0, %P1}
2440    mov{q}\t{%a1, %0|%0, %a1}"
2441   [(set_attr "type" "imov")
2442    (set_attr "modrm" "0,*")
2443    (set_attr "length_address" "8,0")
2444    (set_attr "length_immediate" "0")
2445    (set_attr "memory" "load")
2446    (set_attr "mode" "DI")])
2447
2448 ;; Convert impossible stores of immediate to existing instructions.
2449 ;; First try to get scratch register and go through it.  In case this
2450 ;; fails, move by 32bit parts.
2451 (define_peephole2
2452   [(match_scratch:DI 2 "r")
2453    (set (match_operand:DI 0 "memory_operand" "")
2454         (match_operand:DI 1 "immediate_operand" ""))]
2455   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2456    && !x86_64_immediate_operand (operands[1], DImode)"
2457   [(set (match_dup 2) (match_dup 1))
2458    (set (match_dup 0) (match_dup 2))]
2459   "")
2460
2461 ;; We need to define this as both peepholer and splitter for case
2462 ;; peephole2 pass is not run.
2463 ;; "&& 1" is needed to keep it from matching the previous pattern.
2464 (define_peephole2
2465   [(set (match_operand:DI 0 "memory_operand" "")
2466         (match_operand:DI 1 "immediate_operand" ""))]
2467   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2468    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2469   [(set (match_dup 2) (match_dup 3))
2470    (set (match_dup 4) (match_dup 5))]
2471   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2472
2473 (define_split
2474   [(set (match_operand:DI 0 "memory_operand" "")
2475         (match_operand:DI 1 "immediate_operand" ""))]
2476   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2477                     ? epilogue_completed : reload_completed)
2478    && !symbolic_operand (operands[1], DImode)
2479    && !x86_64_immediate_operand (operands[1], DImode)"
2480   [(set (match_dup 2) (match_dup 3))
2481    (set (match_dup 4) (match_dup 5))]
2482   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2483
2484 (define_insn "*swapdi_rex64"
2485   [(set (match_operand:DI 0 "register_operand" "+r")
2486         (match_operand:DI 1 "register_operand" "+r"))
2487    (set (match_dup 1)
2488         (match_dup 0))]
2489   "TARGET_64BIT"
2490   "xchg{q}\t%1, %0"
2491   [(set_attr "type" "imov")
2492    (set_attr "mode" "DI")
2493    (set_attr "pent_pair" "np")
2494    (set_attr "athlon_decode" "vector")
2495    (set_attr "amdfam10_decode" "double")])
2496
2497 (define_expand "movoi"
2498   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2499         (match_operand:OI 1 "general_operand" ""))]
2500   "TARGET_AVX"
2501   "ix86_expand_move (OImode, operands); DONE;")
2502
2503 (define_insn "*movoi_internal"
2504   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2505         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2506   "TARGET_AVX
2507    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2508 {
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       return "vxorps\t%0, %0, %0";
2513     case 1:
2514     case 2:
2515       if (misaligned_operand (operands[0], OImode)
2516           || misaligned_operand (operands[1], OImode))
2517         return "vmovdqu\t{%1, %0|%0, %1}";
2518       else
2519         return "vmovdqa\t{%1, %0|%0, %1}";
2520     default:
2521       gcc_unreachable ();
2522     }
2523 }
2524   [(set_attr "type" "sselog1,ssemov,ssemov")
2525    (set_attr "prefix" "vex")
2526    (set_attr "mode" "OI")])
2527
2528 (define_expand "movti"
2529   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2530         (match_operand:TI 1 "nonimmediate_operand" ""))]
2531   "TARGET_SSE || TARGET_64BIT"
2532 {
2533   if (TARGET_64BIT)
2534     ix86_expand_move (TImode, operands);
2535   else if (push_operand (operands[0], TImode))
2536     ix86_expand_push (TImode, operands[1]);
2537   else
2538     ix86_expand_vector_move (TImode, operands);
2539   DONE;
2540 })
2541
2542 (define_insn "*movti_internal"
2543   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2544         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2545   "TARGET_SSE && !TARGET_64BIT
2546    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2547 {
2548   switch (which_alternative)
2549     {
2550     case 0:
2551       if (get_attr_mode (insn) == MODE_V4SF)
2552         return "%vxorps\t%0, %d0";
2553       else
2554         return "%vpxor\t%0, %d0";
2555     case 1:
2556     case 2:
2557       /* TDmode values are passed as TImode on the stack.  Moving them
2558          to stack may result in unaligned memory access.  */
2559       if (misaligned_operand (operands[0], TImode)
2560           || misaligned_operand (operands[1], TImode))
2561         {
2562           if (get_attr_mode (insn) == MODE_V4SF)
2563             return "%vmovups\t{%1, %0|%0, %1}";
2564          else
2565            return "%vmovdqu\t{%1, %0|%0, %1}";
2566         }
2567       else
2568         {
2569           if (get_attr_mode (insn) == MODE_V4SF)
2570             return "%vmovaps\t{%1, %0|%0, %1}";
2571          else
2572            return "%vmovdqa\t{%1, %0|%0, %1}";
2573         }
2574     default:
2575       gcc_unreachable ();
2576     }
2577 }
2578   [(set_attr "type" "sselog1,ssemov,ssemov")
2579    (set_attr "prefix" "maybe_vex")
2580    (set (attr "mode")
2581         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2582                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2583                  (const_string "V4SF")
2584                (and (eq_attr "alternative" "2")
2585                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2586                         (const_int 0)))
2587                  (const_string "V4SF")]
2588               (const_string "TI")))])
2589
2590 (define_insn "*movti_rex64"
2591   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2592         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2593   "TARGET_64BIT
2594    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2595 {
2596   switch (which_alternative)
2597     {
2598     case 0:
2599     case 1:
2600       return "#";
2601     case 2:
2602       if (get_attr_mode (insn) == MODE_V4SF)
2603         return "%vxorps\t%0, %d0";
2604       else
2605         return "%vpxor\t%0, %d0";
2606     case 3:
2607     case 4:
2608       /* TDmode values are passed as TImode on the stack.  Moving them
2609          to stack may result in unaligned memory access.  */
2610       if (misaligned_operand (operands[0], TImode)
2611           || misaligned_operand (operands[1], TImode))
2612         {
2613           if (get_attr_mode (insn) == MODE_V4SF)
2614             return "%vmovups\t{%1, %0|%0, %1}";
2615          else
2616            return "%vmovdqu\t{%1, %0|%0, %1}";
2617         }
2618       else
2619         {
2620           if (get_attr_mode (insn) == MODE_V4SF)
2621             return "%vmovaps\t{%1, %0|%0, %1}";
2622          else
2623            return "%vmovdqa\t{%1, %0|%0, %1}";
2624         }
2625     default:
2626       gcc_unreachable ();
2627     }
2628 }
2629   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2630    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2631    (set (attr "mode")
2632         (cond [(eq_attr "alternative" "2,3")
2633                  (if_then_else
2634                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2635                        (const_int 0))
2636                    (const_string "V4SF")
2637                    (const_string "TI"))
2638                (eq_attr "alternative" "4")
2639                  (if_then_else
2640                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2641                             (const_int 0))
2642                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2643                             (const_int 0)))
2644                    (const_string "V4SF")
2645                    (const_string "TI"))]
2646                (const_string "DI")))])
2647
2648 (define_split
2649   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2650         (match_operand:TI 1 "general_operand" ""))]
2651   "reload_completed && !SSE_REG_P (operands[0])
2652    && !SSE_REG_P (operands[1])"
2653   [(const_int 0)]
2654   "ix86_split_long_move (operands); DONE;")
2655
2656 ;; This expands to what emit_move_complex would generate if we didn't
2657 ;; have a movti pattern.  Having this avoids problems with reload on
2658 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2659 ;; to have around all the time.
2660 (define_expand "movcdi"
2661   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2662         (match_operand:CDI 1 "general_operand" ""))]
2663   ""
2664 {
2665   if (push_operand (operands[0], CDImode))
2666     emit_move_complex_push (CDImode, operands[0], operands[1]);
2667   else
2668     emit_move_complex_parts (operands[0], operands[1]);
2669   DONE;
2670 })
2671
2672 (define_expand "movsf"
2673   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2674         (match_operand:SF 1 "general_operand" ""))]
2675   ""
2676   "ix86_expand_move (SFmode, operands); DONE;")
2677
2678 (define_insn "*pushsf"
2679   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2680         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2681   "!TARGET_64BIT"
2682 {
2683   /* Anything else should be already split before reg-stack.  */
2684   gcc_assert (which_alternative == 1);
2685   return "push{l}\t%1";
2686 }
2687   [(set_attr "type" "multi,push,multi")
2688    (set_attr "unit" "i387,*,*")
2689    (set_attr "mode" "SF,SI,SF")])
2690
2691 (define_insn "*pushsf_rex64"
2692   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2693         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2694   "TARGET_64BIT"
2695 {
2696   /* Anything else should be already split before reg-stack.  */
2697   gcc_assert (which_alternative == 1);
2698   return "push{q}\t%q1";
2699 }
2700   [(set_attr "type" "multi,push,multi")
2701    (set_attr "unit" "i387,*,*")
2702    (set_attr "mode" "SF,DI,SF")])
2703
2704 (define_split
2705   [(set (match_operand:SF 0 "push_operand" "")
2706         (match_operand:SF 1 "memory_operand" ""))]
2707   "reload_completed
2708    && MEM_P (operands[1])
2709    && (operands[2] = find_constant_src (insn))"
2710   [(set (match_dup 0)
2711         (match_dup 2))])
2712
2713
2714 ;; %%% Kill this when call knows how to work this out.
2715 (define_split
2716   [(set (match_operand:SF 0 "push_operand" "")
2717         (match_operand:SF 1 "any_fp_register_operand" ""))]
2718   "!TARGET_64BIT"
2719   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2720    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2721
2722 (define_split
2723   [(set (match_operand:SF 0 "push_operand" "")
2724         (match_operand:SF 1 "any_fp_register_operand" ""))]
2725   "TARGET_64BIT"
2726   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2727    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2728
2729 (define_insn "*movsf_1"
2730   [(set (match_operand:SF 0 "nonimmediate_operand"
2731           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2732         (match_operand:SF 1 "general_operand"
2733           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2734   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2735    && (reload_in_progress || reload_completed
2736        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2737        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2738            && standard_80387_constant_p (operands[1]))
2739        || GET_CODE (operands[1]) != CONST_DOUBLE
2740        || memory_operand (operands[0], SFmode))"
2741 {
2742   switch (which_alternative)
2743     {
2744     case 0:
2745     case 1:
2746       return output_387_reg_move (insn, operands);
2747
2748     case 2:
2749       return standard_80387_constant_opcode (operands[1]);
2750
2751     case 3:
2752     case 4:
2753       return "mov{l}\t{%1, %0|%0, %1}";
2754     case 5:
2755       if (get_attr_mode (insn) == MODE_TI)
2756         return "%vpxor\t%0, %d0";
2757       else
2758         return "%vxorps\t%0, %d0";
2759     case 6:
2760       if (get_attr_mode (insn) == MODE_V4SF)
2761         return "%vmovaps\t{%1, %0|%0, %1}";
2762       else
2763         return "%vmovss\t{%1, %d0|%d0, %1}";
2764     case 7:
2765       if (TARGET_AVX)
2766         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2767                                    : "vmovss\t{%1, %0|%0, %1}";
2768       else
2769         return "movss\t{%1, %0|%0, %1}";
2770     case 8:
2771       return "%vmovss\t{%1, %0|%0, %1}";
2772
2773     case 9: case 10: case 14: case 15:
2774       return "movd\t{%1, %0|%0, %1}";
2775     case 12: case 13:
2776       return "%vmovd\t{%1, %0|%0, %1}";
2777
2778     case 11:
2779       return "movq\t{%1, %0|%0, %1}";
2780
2781     default:
2782       gcc_unreachable ();
2783     }
2784 }
2785   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2786    (set (attr "prefix")
2787      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2788        (const_string "maybe_vex")
2789        (const_string "orig")))
2790    (set (attr "mode")
2791         (cond [(eq_attr "alternative" "3,4,9,10")
2792                  (const_string "SI")
2793                (eq_attr "alternative" "5")
2794                  (if_then_else
2795                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2796                                  (const_int 0))
2797                              (ne (symbol_ref "TARGET_SSE2")
2798                                  (const_int 0)))
2799                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2800                             (const_int 0)))
2801                    (const_string "TI")
2802                    (const_string "V4SF"))
2803                /* For architectures resolving dependencies on
2804                   whole SSE registers use APS move to break dependency
2805                   chains, otherwise use short move to avoid extra work.
2806
2807                   Do the same for architectures resolving dependencies on
2808                   the parts.  While in DF mode it is better to always handle
2809                   just register parts, the SF mode is different due to lack
2810                   of instructions to load just part of the register.  It is
2811                   better to maintain the whole registers in single format
2812                   to avoid problems on using packed logical operations.  */
2813                (eq_attr "alternative" "6")
2814                  (if_then_else
2815                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2816                             (const_int 0))
2817                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2818                             (const_int 0)))
2819                    (const_string "V4SF")
2820                    (const_string "SF"))
2821                (eq_attr "alternative" "11")
2822                  (const_string "DI")]
2823                (const_string "SF")))])
2824
2825 (define_insn "*swapsf"
2826   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2827         (match_operand:SF 1 "fp_register_operand" "+f"))
2828    (set (match_dup 1)
2829         (match_dup 0))]
2830   "reload_completed || TARGET_80387"
2831 {
2832   if (STACK_TOP_P (operands[0]))
2833     return "fxch\t%1";
2834   else
2835     return "fxch\t%0";
2836 }
2837   [(set_attr "type" "fxch")
2838    (set_attr "mode" "SF")])
2839
2840 (define_expand "movdf"
2841   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2842         (match_operand:DF 1 "general_operand" ""))]
2843   ""
2844   "ix86_expand_move (DFmode, operands); DONE;")
2845
2846 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2847 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2848 ;; On the average, pushdf using integers can be still shorter.  Allow this
2849 ;; pattern for optimize_size too.
2850
2851 (define_insn "*pushdf_nointeger"
2852   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2853         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2854   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2855 {
2856   /* This insn should be already split before reg-stack.  */
2857   gcc_unreachable ();
2858 }
2859   [(set_attr "type" "multi")
2860    (set_attr "unit" "i387,*,*,*")
2861    (set_attr "mode" "DF,SI,SI,DF")])
2862
2863 (define_insn "*pushdf_integer"
2864   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2865         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2866   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2867 {
2868   /* This insn should be already split before reg-stack.  */
2869   gcc_unreachable ();
2870 }
2871   [(set_attr "type" "multi")
2872    (set_attr "unit" "i387,*,*")
2873    (set_attr "mode" "DF,SI,DF")])
2874
2875 ;; %%% Kill this when call knows how to work this out.
2876 (define_split
2877   [(set (match_operand:DF 0 "push_operand" "")
2878         (match_operand:DF 1 "any_fp_register_operand" ""))]
2879   "reload_completed"
2880   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2881    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2882   "")
2883
2884 (define_split
2885   [(set (match_operand:DF 0 "push_operand" "")
2886         (match_operand:DF 1 "general_operand" ""))]
2887   "reload_completed"
2888   [(const_int 0)]
2889   "ix86_split_long_move (operands); DONE;")
2890
2891 ;; Moving is usually shorter when only FP registers are used. This separate
2892 ;; movdf pattern avoids the use of integer registers for FP operations
2893 ;; when optimizing for size.
2894
2895 (define_insn "*movdf_nointeger"
2896   [(set (match_operand:DF 0 "nonimmediate_operand"
2897                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2898         (match_operand:DF 1 "general_operand"
2899                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2900   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2901    && ((optimize_function_for_size_p (cfun)
2902        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2903    && (reload_in_progress || reload_completed
2904        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2905        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2906            && optimize_function_for_size_p (cfun)
2907            && !memory_operand (operands[0], DFmode)
2908            && standard_80387_constant_p (operands[1]))
2909        || GET_CODE (operands[1]) != CONST_DOUBLE
2910        || ((optimize_function_for_size_p (cfun)
2911             || !TARGET_MEMORY_MISMATCH_STALL
2912             || reload_in_progress || reload_completed)
2913            && memory_operand (operands[0], DFmode)))"
2914 {
2915   switch (which_alternative)
2916     {
2917     case 0:
2918     case 1:
2919       return output_387_reg_move (insn, operands);
2920
2921     case 2:
2922       return standard_80387_constant_opcode (operands[1]);
2923
2924     case 3:
2925     case 4:
2926       return "#";
2927     case 5:
2928       switch (get_attr_mode (insn))
2929         {
2930         case MODE_V4SF:
2931           return "%vxorps\t%0, %d0";
2932         case MODE_V2DF:
2933           return "%vxorpd\t%0, %d0";
2934         case MODE_TI:
2935           return "%vpxor\t%0, %d0";
2936         default:
2937           gcc_unreachable ();
2938         }
2939     case 6:
2940     case 7:
2941     case 8:
2942       switch (get_attr_mode (insn))
2943         {
2944         case MODE_V4SF:
2945           return "%vmovaps\t{%1, %0|%0, %1}";
2946         case MODE_V2DF:
2947           return "%vmovapd\t{%1, %0|%0, %1}";
2948         case MODE_TI:
2949           return "%vmovdqa\t{%1, %0|%0, %1}";
2950         case MODE_DI:
2951           return "%vmovq\t{%1, %0|%0, %1}";
2952         case MODE_DF:
2953           if (TARGET_AVX)
2954             {
2955               if (REG_P (operands[0]) && REG_P (operands[1]))
2956                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2957               else
2958                 return "vmovsd\t{%1, %0|%0, %1}";
2959             }
2960           else
2961             return "movsd\t{%1, %0|%0, %1}";
2962         case MODE_V1DF:
2963           if (TARGET_AVX)
2964             {
2965               if (REG_P (operands[0]))
2966                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2967               else
2968                 return "vmovlpd\t{%1, %0|%0, %1}";
2969             }
2970           else
2971             return "movlpd\t{%1, %0|%0, %1}";
2972         case MODE_V2SF:
2973           if (TARGET_AVX)
2974             {
2975               if (REG_P (operands[0]))
2976                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2977               else
2978                 return "vmovlps\t{%1, %0|%0, %1}";
2979             }
2980           else
2981             return "movlps\t{%1, %0|%0, %1}";
2982         default:
2983           gcc_unreachable ();
2984         }
2985
2986     default:
2987       gcc_unreachable ();
2988     }
2989 }
2990   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2991    (set (attr "prefix")
2992      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2993        (const_string "orig")
2994        (const_string "maybe_vex")))
2995    (set (attr "mode")
2996         (cond [(eq_attr "alternative" "0,1,2")
2997                  (const_string "DF")
2998                (eq_attr "alternative" "3,4")
2999                  (const_string "SI")
3000
3001                /* For SSE1, we have many fewer alternatives.  */
3002                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3003                  (cond [(eq_attr "alternative" "5,6")
3004                           (const_string "V4SF")
3005                        ]
3006                    (const_string "V2SF"))
3007
3008                /* xorps is one byte shorter.  */
3009                (eq_attr "alternative" "5")
3010                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3011                             (const_int 0))
3012                           (const_string "V4SF")
3013                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3014                             (const_int 0))
3015                           (const_string "TI")
3016                        ]
3017                        (const_string "V2DF"))
3018
3019                /* For architectures resolving dependencies on
3020                   whole SSE registers use APD move to break dependency
3021                   chains, otherwise use short move to avoid extra work.
3022
3023                   movaps encodes one byte shorter.  */
3024                (eq_attr "alternative" "6")
3025                  (cond
3026                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3027                         (const_int 0))
3028                       (const_string "V4SF")
3029                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3030                         (const_int 0))
3031                       (const_string "V2DF")
3032                    ]
3033                    (const_string "DF"))
3034                /* For architectures resolving dependencies on register
3035                   parts we may avoid extra work to zero out upper part
3036                   of register.  */
3037                (eq_attr "alternative" "7")
3038                  (if_then_else
3039                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3040                        (const_int 0))
3041                    (const_string "V1DF")
3042                    (const_string "DF"))
3043               ]
3044               (const_string "DF")))])
3045
3046 (define_insn "*movdf_integer_rex64"
3047   [(set (match_operand:DF 0 "nonimmediate_operand"
3048                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3049         (match_operand:DF 1 "general_operand"
3050                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3051   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3052    && (reload_in_progress || reload_completed
3053        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3054        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3055            && optimize_function_for_size_p (cfun)
3056            && standard_80387_constant_p (operands[1]))
3057        || GET_CODE (operands[1]) != CONST_DOUBLE
3058        || memory_operand (operands[0], DFmode))"
3059 {
3060   switch (which_alternative)
3061     {
3062     case 0:
3063     case 1:
3064       return output_387_reg_move (insn, operands);
3065
3066     case 2:
3067       return standard_80387_constant_opcode (operands[1]);
3068
3069     case 3:
3070     case 4:
3071       return "#";
3072
3073     case 5:
3074       switch (get_attr_mode (insn))
3075         {
3076         case MODE_V4SF:
3077           return "%vxorps\t%0, %d0";
3078         case MODE_V2DF:
3079           return "%vxorpd\t%0, %d0";
3080         case MODE_TI:
3081           return "%vpxor\t%0, %d0";
3082         default:
3083           gcc_unreachable ();
3084         }
3085     case 6:
3086     case 7:
3087     case 8:
3088       switch (get_attr_mode (insn))
3089         {
3090         case MODE_V4SF:
3091           return "%vmovaps\t{%1, %0|%0, %1}";
3092         case MODE_V2DF:
3093           return "%vmovapd\t{%1, %0|%0, %1}";
3094         case MODE_TI:
3095           return "%vmovdqa\t{%1, %0|%0, %1}";
3096         case MODE_DI:
3097           return "%vmovq\t{%1, %0|%0, %1}";
3098         case MODE_DF:
3099           if (TARGET_AVX)
3100             {
3101               if (REG_P (operands[0]) && REG_P (operands[1]))
3102                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3103               else
3104                 return "vmovsd\t{%1, %0|%0, %1}";
3105             }
3106           else
3107             return "movsd\t{%1, %0|%0, %1}";
3108         case MODE_V1DF:
3109           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3110         case MODE_V2SF:
3111           return "%vmovlps\t{%1, %d0|%d0, %1}";
3112         default:
3113           gcc_unreachable ();
3114         }
3115
3116     case 9:
3117     case 10:
3118     return "%vmovd\t{%1, %0|%0, %1}";
3119
3120     default:
3121       gcc_unreachable();
3122     }
3123 }
3124   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3125    (set (attr "prefix")
3126      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3127        (const_string "orig")
3128        (const_string "maybe_vex")))
3129    (set (attr "mode")
3130         (cond [(eq_attr "alternative" "0,1,2")
3131                  (const_string "DF")
3132                (eq_attr "alternative" "3,4,9,10")
3133                  (const_string "DI")
3134
3135                /* For SSE1, we have many fewer alternatives.  */
3136                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3137                  (cond [(eq_attr "alternative" "5,6")
3138                           (const_string "V4SF")
3139                        ]
3140                    (const_string "V2SF"))
3141
3142                /* xorps is one byte shorter.  */
3143                (eq_attr "alternative" "5")
3144                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3145                             (const_int 0))
3146                           (const_string "V4SF")
3147                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3148                             (const_int 0))
3149                           (const_string "TI")
3150                        ]
3151                        (const_string "V2DF"))
3152
3153                /* For architectures resolving dependencies on
3154                   whole SSE registers use APD move to break dependency
3155                   chains, otherwise use short move to avoid extra work.
3156
3157                   movaps encodes one byte shorter.  */
3158                (eq_attr "alternative" "6")
3159                  (cond
3160                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3161                         (const_int 0))
3162                       (const_string "V4SF")
3163                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3164                         (const_int 0))
3165                       (const_string "V2DF")
3166                    ]
3167                    (const_string "DF"))
3168                /* For architectures resolving dependencies on register
3169                   parts we may avoid extra work to zero out upper part
3170                   of register.  */
3171                (eq_attr "alternative" "7")
3172                  (if_then_else
3173                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3174                        (const_int 0))
3175                    (const_string "V1DF")
3176                    (const_string "DF"))
3177               ]
3178               (const_string "DF")))])
3179
3180 (define_insn "*movdf_integer"
3181   [(set (match_operand:DF 0 "nonimmediate_operand"
3182                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3183         (match_operand:DF 1 "general_operand"
3184                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3185   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3186    && optimize_function_for_speed_p (cfun)
3187    && TARGET_INTEGER_DFMODE_MOVES
3188    && (reload_in_progress || reload_completed
3189        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3190        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3191            && optimize_function_for_size_p (cfun)
3192            && standard_80387_constant_p (operands[1]))
3193        || GET_CODE (operands[1]) != CONST_DOUBLE
3194        || memory_operand (operands[0], DFmode))"
3195 {
3196   switch (which_alternative)
3197     {
3198     case 0:
3199     case 1:
3200       return output_387_reg_move (insn, operands);
3201
3202     case 2:
3203       return standard_80387_constant_opcode (operands[1]);
3204
3205     case 3:
3206     case 4:
3207       return "#";
3208
3209     case 5:
3210       switch (get_attr_mode (insn))
3211         {
3212         case MODE_V4SF:
3213           return "xorps\t%0, %0";
3214         case MODE_V2DF:
3215           return "xorpd\t%0, %0";
3216         case MODE_TI:
3217           return "pxor\t%0, %0";
3218         default:
3219           gcc_unreachable ();
3220         }
3221     case 6:
3222     case 7:
3223     case 8:
3224       switch (get_attr_mode (insn))
3225         {
3226         case MODE_V4SF:
3227           return "movaps\t{%1, %0|%0, %1}";
3228         case MODE_V2DF:
3229           return "movapd\t{%1, %0|%0, %1}";
3230         case MODE_TI:
3231           return "movdqa\t{%1, %0|%0, %1}";
3232         case MODE_DI:
3233           return "movq\t{%1, %0|%0, %1}";
3234         case MODE_DF:
3235           return "movsd\t{%1, %0|%0, %1}";
3236         case MODE_V1DF:
3237           return "movlpd\t{%1, %0|%0, %1}";
3238         case MODE_V2SF:
3239           return "movlps\t{%1, %0|%0, %1}";
3240         default:
3241           gcc_unreachable ();
3242         }
3243
3244     default:
3245       gcc_unreachable();
3246     }
3247 }
3248   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3249    (set (attr "mode")
3250         (cond [(eq_attr "alternative" "0,1,2")
3251                  (const_string "DF")
3252                (eq_attr "alternative" "3,4")
3253                  (const_string "SI")
3254
3255                /* For SSE1, we have many fewer alternatives.  */
3256                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3257                  (cond [(eq_attr "alternative" "5,6")
3258                           (const_string "V4SF")
3259                        ]
3260                    (const_string "V2SF"))
3261
3262                /* xorps is one byte shorter.  */
3263                (eq_attr "alternative" "5")
3264                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3265                             (const_int 0))
3266                           (const_string "V4SF")
3267                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3268                             (const_int 0))
3269                           (const_string "TI")
3270                        ]
3271                        (const_string "V2DF"))
3272
3273                /* For architectures resolving dependencies on
3274                   whole SSE registers use APD move to break dependency
3275                   chains, otherwise use short move to avoid extra work.
3276
3277                   movaps encodes one byte shorter.  */
3278                (eq_attr "alternative" "6")
3279                  (cond
3280                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3281                         (const_int 0))
3282                       (const_string "V4SF")
3283                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3284                         (const_int 0))
3285                       (const_string "V2DF")
3286                    ]
3287                    (const_string "DF"))
3288                /* For architectures resolving dependencies on register
3289                   parts we may avoid extra work to zero out upper part
3290                   of register.  */
3291                (eq_attr "alternative" "7")
3292                  (if_then_else
3293                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3294                        (const_int 0))
3295                    (const_string "V1DF")
3296                    (const_string "DF"))
3297               ]
3298               (const_string "DF")))])
3299
3300 (define_split
3301   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3302         (match_operand:DF 1 "general_operand" ""))]
3303   "reload_completed
3304    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3305    && ! (ANY_FP_REG_P (operands[0]) ||
3306          (GET_CODE (operands[0]) == SUBREG
3307           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3308    && ! (ANY_FP_REG_P (operands[1]) ||
3309          (GET_CODE (operands[1]) == SUBREG
3310           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3311   [(const_int 0)]
3312   "ix86_split_long_move (operands); DONE;")
3313
3314 (define_insn "*swapdf"
3315   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3316         (match_operand:DF 1 "fp_register_operand" "+f"))
3317    (set (match_dup 1)
3318         (match_dup 0))]
3319   "reload_completed || TARGET_80387"
3320 {
3321   if (STACK_TOP_P (operands[0]))
3322     return "fxch\t%1";
3323   else
3324     return "fxch\t%0";
3325 }
3326   [(set_attr "type" "fxch")
3327    (set_attr "mode" "DF")])
3328
3329 (define_expand "movxf"
3330   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3331         (match_operand:XF 1 "general_operand" ""))]
3332   ""
3333   "ix86_expand_move (XFmode, operands); DONE;")
3334
3335 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3336 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3337 ;; Pushing using integer instructions is longer except for constants
3338 ;; and direct memory references.
3339 ;; (assuming that any given constant is pushed only once, but this ought to be
3340 ;;  handled elsewhere).
3341
3342 (define_insn "*pushxf_nointeger"
3343   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3344         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3345   "optimize_function_for_size_p (cfun)"
3346 {
3347   /* This insn should be already split before reg-stack.  */
3348   gcc_unreachable ();
3349 }
3350   [(set_attr "type" "multi")
3351    (set_attr "unit" "i387,*,*")
3352    (set_attr "mode" "XF,SI,SI")])
3353
3354 (define_insn "*pushxf_integer"
3355   [(set (match_operand:XF 0 "push_operand" "=<,<")
3356         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3357   "optimize_function_for_speed_p (cfun)"
3358 {
3359   /* This insn should be already split before reg-stack.  */
3360   gcc_unreachable ();
3361 }
3362   [(set_attr "type" "multi")
3363    (set_attr "unit" "i387,*")
3364    (set_attr "mode" "XF,SI")])
3365
3366 (define_split
3367   [(set (match_operand 0 "push_operand" "")
3368         (match_operand 1 "general_operand" ""))]
3369   "reload_completed
3370    && (GET_MODE (operands[0]) == XFmode
3371        || GET_MODE (operands[0]) == DFmode)
3372    && !ANY_FP_REG_P (operands[1])"
3373   [(const_int 0)]
3374   "ix86_split_long_move (operands); DONE;")
3375
3376 (define_split
3377   [(set (match_operand:XF 0 "push_operand" "")
3378         (match_operand:XF 1 "any_fp_register_operand" ""))]
3379   ""
3380   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3381    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3382   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3383
3384 ;; Do not use integer registers when optimizing for size
3385 (define_insn "*movxf_nointeger"
3386   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3387         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3388   "optimize_function_for_size_p (cfun)
3389    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3390    && (reload_in_progress || reload_completed
3391        || standard_80387_constant_p (operands[1])
3392        || GET_CODE (operands[1]) != CONST_DOUBLE
3393        || memory_operand (operands[0], XFmode))"
3394 {
3395   switch (which_alternative)
3396     {
3397     case 0:
3398     case 1:
3399       return output_387_reg_move (insn, operands);
3400
3401     case 2:
3402       return standard_80387_constant_opcode (operands[1]);
3403
3404     case 3: case 4:
3405       return "#";
3406     default:
3407       gcc_unreachable ();
3408     }
3409 }
3410   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3411    (set_attr "mode" "XF,XF,XF,SI,SI")])
3412
3413 (define_insn "*movxf_integer"
3414   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3415         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3416   "optimize_function_for_speed_p (cfun)
3417    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3418    && (reload_in_progress || reload_completed
3419        || GET_CODE (operands[1]) != CONST_DOUBLE
3420        || memory_operand (operands[0], XFmode))"
3421 {
3422   switch (which_alternative)
3423     {
3424     case 0:
3425     case 1:
3426       return output_387_reg_move (insn, operands);
3427
3428     case 2:
3429       return standard_80387_constant_opcode (operands[1]);
3430
3431     case 3: case 4:
3432       return "#";
3433
3434     default:
3435       gcc_unreachable ();
3436     }
3437 }
3438   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3439    (set_attr "mode" "XF,XF,XF,SI,SI")])
3440
3441 (define_expand "movtf"
3442   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3443         (match_operand:TF 1 "nonimmediate_operand" ""))]
3444   "TARGET_SSE2"
3445 {
3446   ix86_expand_move (TFmode, operands);
3447   DONE;
3448 })
3449
3450 (define_insn "*movtf_internal"
3451   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3452         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3453   "TARGET_SSE2
3454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3455 {
3456   switch (which_alternative)
3457     {
3458     case 0:
3459     case 1:
3460       if (get_attr_mode (insn) == MODE_V4SF)
3461         return "%vmovaps\t{%1, %0|%0, %1}";
3462       else
3463         return "%vmovdqa\t{%1, %0|%0, %1}";
3464     case 2:
3465       if (get_attr_mode (insn) == MODE_V4SF)
3466         return "%vxorps\t%0, %d0";
3467       else
3468         return "%vpxor\t%0, %d0";
3469     case 3:
3470     case 4:
3471         return "#";
3472     default:
3473       gcc_unreachable ();
3474     }
3475 }
3476   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3477    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3478    (set (attr "mode")
3479         (cond [(eq_attr "alternative" "0,2")
3480                  (if_then_else
3481                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3482                        (const_int 0))
3483                    (const_string "V4SF")
3484                    (const_string "TI"))
3485                (eq_attr "alternative" "1")
3486                  (if_then_else
3487                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3488                             (const_int 0))
3489                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3490                             (const_int 0)))
3491                    (const_string "V4SF")
3492                    (const_string "TI"))]
3493                (const_string "DI")))])
3494
3495 (define_insn "*pushtf_sse"
3496   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3497         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3498   "TARGET_SSE2"
3499 {
3500   /* This insn should be already split before reg-stack.  */
3501   gcc_unreachable ();
3502 }
3503   [(set_attr "type" "multi")
3504    (set_attr "unit" "sse,*,*")
3505    (set_attr "mode" "TF,SI,SI")])
3506
3507 (define_split
3508   [(set (match_operand:TF 0 "push_operand" "")
3509         (match_operand:TF 1 "general_operand" ""))]
3510   "TARGET_SSE2 && reload_completed
3511    && !SSE_REG_P (operands[1])"
3512   [(const_int 0)]
3513   "ix86_split_long_move (operands); DONE;")
3514
3515 (define_split
3516   [(set (match_operand:TF 0 "push_operand" "")
3517         (match_operand:TF 1 "any_fp_register_operand" ""))]
3518   "TARGET_SSE2"
3519   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3520    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3521   "")
3522
3523 (define_split
3524   [(set (match_operand 0 "nonimmediate_operand" "")
3525         (match_operand 1 "general_operand" ""))]
3526   "reload_completed
3527    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528    && GET_MODE (operands[0]) == XFmode
3529    && ! (ANY_FP_REG_P (operands[0]) ||
3530          (GET_CODE (operands[0]) == SUBREG
3531           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3532    && ! (ANY_FP_REG_P (operands[1]) ||
3533          (GET_CODE (operands[1]) == SUBREG
3534           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3535   [(const_int 0)]
3536   "ix86_split_long_move (operands); DONE;")
3537
3538 (define_split
3539   [(set (match_operand 0 "register_operand" "")
3540         (match_operand 1 "memory_operand" ""))]
3541   "reload_completed
3542    && MEM_P (operands[1])
3543    && (GET_MODE (operands[0]) == TFmode
3544        || GET_MODE (operands[0]) == XFmode
3545        || GET_MODE (operands[0]) == SFmode
3546        || GET_MODE (operands[0]) == DFmode)
3547    && (operands[2] = find_constant_src (insn))"
3548   [(set (match_dup 0) (match_dup 2))]
3549 {
3550   rtx c = operands[2];
3551   rtx r = operands[0];
3552
3553   if (GET_CODE (r) == SUBREG)
3554     r = SUBREG_REG (r);
3555
3556   if (SSE_REG_P (r))
3557     {
3558       if (!standard_sse_constant_p (c))
3559         FAIL;
3560     }
3561   else if (FP_REG_P (r))
3562     {
3563       if (!standard_80387_constant_p (c))
3564         FAIL;
3565     }
3566   else if (MMX_REG_P (r))
3567     FAIL;
3568 })
3569
3570 (define_split
3571   [(set (match_operand 0 "register_operand" "")
3572         (float_extend (match_operand 1 "memory_operand" "")))]
3573   "reload_completed
3574    && MEM_P (operands[1])
3575    && (GET_MODE (operands[0]) == TFmode
3576        || GET_MODE (operands[0]) == XFmode
3577        || GET_MODE (operands[0]) == SFmode
3578        || GET_MODE (operands[0]) == DFmode)
3579    && (operands[2] = find_constant_src (insn))"
3580   [(set (match_dup 0) (match_dup 2))]
3581 {
3582   rtx c = operands[2];
3583   rtx r = operands[0];
3584
3585   if (GET_CODE (r) == SUBREG)
3586     r = SUBREG_REG (r);
3587
3588   if (SSE_REG_P (r))
3589     {
3590       if (!standard_sse_constant_p (c))
3591         FAIL;
3592     }
3593   else if (FP_REG_P (r))
3594     {
3595       if (!standard_80387_constant_p (c))
3596         FAIL;
3597     }
3598   else if (MMX_REG_P (r))
3599     FAIL;
3600 })
3601
3602 (define_insn "swapxf"
3603   [(set (match_operand:XF 0 "register_operand" "+f")
3604         (match_operand:XF 1 "register_operand" "+f"))
3605    (set (match_dup 1)
3606         (match_dup 0))]
3607   "TARGET_80387"
3608 {
3609   if (STACK_TOP_P (operands[0]))
3610     return "fxch\t%1";
3611   else
3612     return "fxch\t%0";
3613 }
3614   [(set_attr "type" "fxch")
3615    (set_attr "mode" "XF")])
3616
3617 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3618 (define_split
3619   [(set (match_operand:X87MODEF 0 "register_operand" "")
3620         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3621   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3622    && (standard_80387_constant_p (operands[1]) == 8
3623        || standard_80387_constant_p (operands[1]) == 9)"
3624   [(set (match_dup 0)(match_dup 1))
3625    (set (match_dup 0)
3626         (neg:X87MODEF (match_dup 0)))]
3627 {
3628   REAL_VALUE_TYPE r;
3629
3630   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3631   if (real_isnegzero (&r))
3632     operands[1] = CONST0_RTX (<MODE>mode);
3633   else
3634     operands[1] = CONST1_RTX (<MODE>mode);
3635 })
3636
3637 (define_split
3638   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3639         (match_operand:TF 1 "general_operand" ""))]
3640   "reload_completed
3641    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3642   [(const_int 0)]
3643   "ix86_split_long_move (operands); DONE;")
3644 \f
3645 ;; Zero extension instructions
3646
3647 (define_expand "zero_extendhisi2"
3648   [(set (match_operand:SI 0 "register_operand" "")
3649      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3650   ""
3651 {
3652   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3653     {
3654       operands[1] = force_reg (HImode, operands[1]);
3655       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3656       DONE;
3657     }
3658 })
3659
3660 (define_insn "zero_extendhisi2_and"
3661   [(set (match_operand:SI 0 "register_operand" "=r")
3662      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3663    (clobber (reg:CC FLAGS_REG))]
3664   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3665   "#"
3666   [(set_attr "type" "alu1")
3667    (set_attr "mode" "SI")])
3668
3669 (define_split
3670   [(set (match_operand:SI 0 "register_operand" "")
3671         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3672    (clobber (reg:CC FLAGS_REG))]
3673   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3674    && optimize_function_for_speed_p (cfun)"
3675   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3676               (clobber (reg:CC FLAGS_REG))])]
3677   "")
3678
3679 (define_insn "*zero_extendhisi2_movzwl"
3680   [(set (match_operand:SI 0 "register_operand" "=r")
3681      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3682   "!TARGET_ZERO_EXTEND_WITH_AND
3683    || optimize_function_for_size_p (cfun)"
3684   "movz{wl|x}\t{%1, %0|%0, %1}"
3685   [(set_attr "type" "imovx")
3686    (set_attr "mode" "SI")])
3687
3688 (define_expand "zero_extendqihi2"
3689   [(parallel
3690     [(set (match_operand:HI 0 "register_operand" "")
3691        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3692      (clobber (reg:CC FLAGS_REG))])]
3693   ""
3694   "")
3695
3696 (define_insn "*zero_extendqihi2_and"
3697   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3698      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3699    (clobber (reg:CC FLAGS_REG))]
3700   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3701   "#"
3702   [(set_attr "type" "alu1")
3703    (set_attr "mode" "HI")])
3704
3705 (define_insn "*zero_extendqihi2_movzbw_and"
3706   [(set (match_operand:HI 0 "register_operand" "=r,r")
3707      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3708    (clobber (reg:CC FLAGS_REG))]
3709   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3710   "#"
3711   [(set_attr "type" "imovx,alu1")
3712    (set_attr "mode" "HI")])
3713
3714 ; zero extend to SImode here to avoid partial register stalls
3715 (define_insn "*zero_extendqihi2_movzbl"
3716   [(set (match_operand:HI 0 "register_operand" "=r")
3717      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3718   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3719    && reload_completed"
3720   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3721   [(set_attr "type" "imovx")
3722    (set_attr "mode" "SI")])
3723
3724 ;; For the movzbw case strip only the clobber
3725 (define_split
3726   [(set (match_operand:HI 0 "register_operand" "")
3727         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3728    (clobber (reg:CC FLAGS_REG))]
3729   "reload_completed
3730    && (!TARGET_ZERO_EXTEND_WITH_AND
3731        || optimize_function_for_size_p (cfun))
3732    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3733   [(set (match_operand:HI 0 "register_operand" "")
3734         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3735
3736 ;; When source and destination does not overlap, clear destination
3737 ;; first and then do the movb
3738 (define_split
3739   [(set (match_operand:HI 0 "register_operand" "")
3740         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3741    (clobber (reg:CC FLAGS_REG))]
3742   "reload_completed
3743    && ANY_QI_REG_P (operands[0])
3744    && (TARGET_ZERO_EXTEND_WITH_AND
3745        && optimize_function_for_speed_p (cfun))
3746    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3747   [(set (match_dup 0) (const_int 0))
3748    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3749   "operands[2] = gen_lowpart (QImode, operands[0]);")
3750
3751 ;; Rest is handled by single and.
3752 (define_split
3753   [(set (match_operand:HI 0 "register_operand" "")
3754         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3755    (clobber (reg:CC FLAGS_REG))]
3756   "reload_completed
3757    && true_regnum (operands[0]) == true_regnum (operands[1])"
3758   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3759               (clobber (reg:CC FLAGS_REG))])]
3760   "")
3761
3762 (define_expand "zero_extendqisi2"
3763   [(parallel
3764     [(set (match_operand:SI 0 "register_operand" "")
3765        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3766      (clobber (reg:CC FLAGS_REG))])]
3767   ""
3768   "")
3769
3770 (define_insn "*zero_extendqisi2_and"
3771   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3772      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3773    (clobber (reg:CC FLAGS_REG))]
3774   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3775   "#"
3776   [(set_attr "type" "alu1")
3777    (set_attr "mode" "SI")])
3778
3779 (define_insn "*zero_extendqisi2_movzbw_and"
3780   [(set (match_operand:SI 0 "register_operand" "=r,r")
3781      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3782    (clobber (reg:CC FLAGS_REG))]
3783   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3784   "#"
3785   [(set_attr "type" "imovx,alu1")
3786    (set_attr "mode" "SI")])
3787
3788 (define_insn "*zero_extendqisi2_movzbw"
3789   [(set (match_operand:SI 0 "register_operand" "=r")
3790      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3791   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3792    && reload_completed"
3793   "movz{bl|x}\t{%1, %0|%0, %1}"
3794   [(set_attr "type" "imovx")
3795    (set_attr "mode" "SI")])
3796
3797 ;; For the movzbl case strip only the clobber
3798 (define_split
3799   [(set (match_operand:SI 0 "register_operand" "")
3800         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3801    (clobber (reg:CC FLAGS_REG))]
3802   "reload_completed
3803    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3804    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3805   [(set (match_dup 0)
3806         (zero_extend:SI (match_dup 1)))])
3807
3808 ;; When source and destination does not overlap, clear destination
3809 ;; first and then do the movb
3810 (define_split
3811   [(set (match_operand:SI 0 "register_operand" "")
3812         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3813    (clobber (reg:CC FLAGS_REG))]
3814   "reload_completed
3815    && ANY_QI_REG_P (operands[0])
3816    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3817    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3818    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3819   [(set (match_dup 0) (const_int 0))
3820    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3821   "operands[2] = gen_lowpart (QImode, operands[0]);")
3822
3823 ;; Rest is handled by single and.
3824 (define_split
3825   [(set (match_operand:SI 0 "register_operand" "")
3826         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3827    (clobber (reg:CC FLAGS_REG))]
3828   "reload_completed
3829    && true_regnum (operands[0]) == true_regnum (operands[1])"
3830   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3831               (clobber (reg:CC FLAGS_REG))])]
3832   "")
3833
3834 ;; %%% Kill me once multi-word ops are sane.
3835 (define_expand "zero_extendsidi2"
3836   [(set (match_operand:DI 0 "register_operand" "")
3837      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3838   ""
3839 {
3840   if (!TARGET_64BIT)
3841     {
3842       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3843       DONE;
3844     }
3845 })
3846
3847 (define_insn "zero_extendsidi2_32"
3848   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3849         (zero_extend:DI
3850          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3851    (clobber (reg:CC FLAGS_REG))]
3852   "!TARGET_64BIT"
3853   "@
3854    #
3855    #
3856    #
3857    movd\t{%1, %0|%0, %1}
3858    movd\t{%1, %0|%0, %1}
3859    %vmovd\t{%1, %0|%0, %1}
3860    %vmovd\t{%1, %0|%0, %1}"
3861   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3862    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3863    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3864
3865 (define_insn "zero_extendsidi2_rex64"
3866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3867      (zero_extend:DI
3868        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3869   "TARGET_64BIT"
3870   "@
3871    mov\t{%k1, %k0|%k0, %k1}
3872    #
3873    movd\t{%1, %0|%0, %1}
3874    movd\t{%1, %0|%0, %1}
3875    %vmovd\t{%1, %0|%0, %1}
3876    %vmovd\t{%1, %0|%0, %1}"
3877   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3878    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3879    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3880
3881 (define_split
3882   [(set (match_operand:DI 0 "memory_operand" "")
3883      (zero_extend:DI (match_dup 0)))]
3884   "TARGET_64BIT"
3885   [(set (match_dup 4) (const_int 0))]
3886   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3887
3888 (define_split
3889   [(set (match_operand:DI 0 "register_operand" "")
3890         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3891    (clobber (reg:CC FLAGS_REG))]
3892   "!TARGET_64BIT && reload_completed
3893    && true_regnum (operands[0]) == true_regnum (operands[1])"
3894   [(set (match_dup 4) (const_int 0))]
3895   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3896
3897 (define_split
3898   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3899         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3900    (clobber (reg:CC FLAGS_REG))]
3901   "!TARGET_64BIT && reload_completed
3902    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3903   [(set (match_dup 3) (match_dup 1))
3904    (set (match_dup 4) (const_int 0))]
3905   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3906
3907 (define_insn "zero_extendhidi2"
3908   [(set (match_operand:DI 0 "register_operand" "=r")
3909      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3910   "TARGET_64BIT"
3911   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3912   [(set_attr "type" "imovx")
3913    (set_attr "mode" "DI")])
3914
3915 (define_insn "zero_extendqidi2"
3916   [(set (match_operand:DI 0 "register_operand" "=r")
3917      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3918   "TARGET_64BIT"
3919   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3920   [(set_attr "type" "imovx")
3921    (set_attr "mode" "DI")])
3922 \f
3923 ;; Sign extension instructions
3924
3925 (define_expand "extendsidi2"
3926   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3927                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3928               (clobber (reg:CC FLAGS_REG))
3929               (clobber (match_scratch:SI 2 ""))])]
3930   ""
3931 {
3932   if (TARGET_64BIT)
3933     {
3934       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3935       DONE;
3936     }
3937 })
3938
3939 (define_insn "*extendsidi2_1"
3940   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3941         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3942    (clobber (reg:CC FLAGS_REG))
3943    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3944   "!TARGET_64BIT"
3945   "#")
3946
3947 (define_insn "extendsidi2_rex64"
3948   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3949         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3950   "TARGET_64BIT"
3951   "@
3952    {cltq|cdqe}
3953    movs{lq|x}\t{%1,%0|%0, %1}"
3954   [(set_attr "type" "imovx")
3955    (set_attr "mode" "DI")
3956    (set_attr "prefix_0f" "0")
3957    (set_attr "modrm" "0,1")])
3958
3959 (define_insn "extendhidi2"
3960   [(set (match_operand:DI 0 "register_operand" "=r")
3961         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3962   "TARGET_64BIT"
3963   "movs{wq|x}\t{%1,%0|%0, %1}"
3964   [(set_attr "type" "imovx")
3965    (set_attr "mode" "DI")])
3966
3967 (define_insn "extendqidi2"
3968   [(set (match_operand:DI 0 "register_operand" "=r")
3969         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3970   "TARGET_64BIT"
3971   "movs{bq|x}\t{%1,%0|%0, %1}"
3972    [(set_attr "type" "imovx")
3973     (set_attr "mode" "DI")])
3974
3975 ;; Extend to memory case when source register does die.
3976 (define_split
3977   [(set (match_operand:DI 0 "memory_operand" "")
3978         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3979    (clobber (reg:CC FLAGS_REG))
3980    (clobber (match_operand:SI 2 "register_operand" ""))]
3981   "(reload_completed
3982     && dead_or_set_p (insn, operands[1])
3983     && !reg_mentioned_p (operands[1], operands[0]))"
3984   [(set (match_dup 3) (match_dup 1))
3985    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3986               (clobber (reg:CC FLAGS_REG))])
3987    (set (match_dup 4) (match_dup 1))]
3988   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3989
3990 ;; Extend to memory case when source register does not die.
3991 (define_split
3992   [(set (match_operand:DI 0 "memory_operand" "")
3993         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3994    (clobber (reg:CC FLAGS_REG))
3995    (clobber (match_operand:SI 2 "register_operand" ""))]
3996   "reload_completed"
3997   [(const_int 0)]
3998 {
3999   split_di (&operands[0], 1, &operands[3], &operands[4]);
4000
4001   emit_move_insn (operands[3], operands[1]);
4002
4003   /* Generate a cltd if possible and doing so it profitable.  */
4004   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4005       && true_regnum (operands[1]) == AX_REG
4006       && true_regnum (operands[2]) == DX_REG)
4007     {
4008       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4009     }
4010   else
4011     {
4012       emit_move_insn (operands[2], operands[1]);
4013       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4014     }
4015   emit_move_insn (operands[4], operands[2]);
4016   DONE;
4017 })
4018
4019 ;; Extend to register case.  Optimize case where source and destination
4020 ;; registers match and cases where we can use cltd.
4021 (define_split
4022   [(set (match_operand:DI 0 "register_operand" "")
4023         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4024    (clobber (reg:CC FLAGS_REG))
4025    (clobber (match_scratch:SI 2 ""))]
4026   "reload_completed"
4027   [(const_int 0)]
4028 {
4029   split_di (&operands[0], 1, &operands[3], &operands[4]);
4030
4031   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4032     emit_move_insn (operands[3], operands[1]);
4033
4034   /* Generate a cltd if possible and doing so it profitable.  */
4035   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4036       && true_regnum (operands[3]) == AX_REG)
4037     {
4038       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4039       DONE;
4040     }
4041
4042   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4043     emit_move_insn (operands[4], operands[1]);
4044
4045   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4046   DONE;
4047 })
4048
4049 (define_insn "extendhisi2"
4050   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4051         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4052   ""
4053 {
4054   switch (get_attr_prefix_0f (insn))
4055     {
4056     case 0:
4057       return "{cwtl|cwde}";
4058     default:
4059       return "movs{wl|x}\t{%1,%0|%0, %1}";
4060     }
4061 }
4062   [(set_attr "type" "imovx")
4063    (set_attr "mode" "SI")
4064    (set (attr "prefix_0f")
4065      ;; movsx is short decodable while cwtl is vector decoded.
4066      (if_then_else (and (eq_attr "cpu" "!k6")
4067                         (eq_attr "alternative" "0"))
4068         (const_string "0")
4069         (const_string "1")))
4070    (set (attr "modrm")
4071      (if_then_else (eq_attr "prefix_0f" "0")
4072         (const_string "0")
4073         (const_string "1")))])
4074
4075 (define_insn "*extendhisi2_zext"
4076   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4077         (zero_extend:DI
4078           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4079   "TARGET_64BIT"
4080 {
4081   switch (get_attr_prefix_0f (insn))
4082     {
4083     case 0:
4084       return "{cwtl|cwde}";
4085     default:
4086       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4087     }
4088 }
4089   [(set_attr "type" "imovx")
4090    (set_attr "mode" "SI")
4091    (set (attr "prefix_0f")
4092      ;; movsx is short decodable while cwtl is vector decoded.
4093      (if_then_else (and (eq_attr "cpu" "!k6")
4094                         (eq_attr "alternative" "0"))
4095         (const_string "0")
4096         (const_string "1")))
4097    (set (attr "modrm")
4098      (if_then_else (eq_attr "prefix_0f" "0")
4099         (const_string "0")
4100         (const_string "1")))])
4101
4102 (define_insn "extendqihi2"
4103   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4104         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4105   ""
4106 {
4107   switch (get_attr_prefix_0f (insn))
4108     {
4109     case 0:
4110       return "{cbtw|cbw}";
4111     default:
4112       return "movs{bw|x}\t{%1,%0|%0, %1}";
4113     }
4114 }
4115   [(set_attr "type" "imovx")
4116    (set_attr "mode" "HI")
4117    (set (attr "prefix_0f")
4118      ;; movsx is short decodable while cwtl is vector decoded.
4119      (if_then_else (and (eq_attr "cpu" "!k6")
4120                         (eq_attr "alternative" "0"))
4121         (const_string "0")
4122         (const_string "1")))
4123    (set (attr "modrm")
4124      (if_then_else (eq_attr "prefix_0f" "0")
4125         (const_string "0")
4126         (const_string "1")))])
4127
4128 (define_insn "extendqisi2"
4129   [(set (match_operand:SI 0 "register_operand" "=r")
4130         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4131   ""
4132   "movs{bl|x}\t{%1,%0|%0, %1}"
4133    [(set_attr "type" "imovx")
4134     (set_attr "mode" "SI")])
4135
4136 (define_insn "*extendqisi2_zext"
4137   [(set (match_operand:DI 0 "register_operand" "=r")
4138         (zero_extend:DI
4139           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4140   "TARGET_64BIT"
4141   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4142    [(set_attr "type" "imovx")
4143     (set_attr "mode" "SI")])
4144 \f
4145 ;; Conversions between float and double.
4146
4147 ;; These are all no-ops in the model used for the 80387.  So just
4148 ;; emit moves.
4149
4150 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4151 (define_insn "*dummy_extendsfdf2"
4152   [(set (match_operand:DF 0 "push_operand" "=<")
4153         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4154   "0"
4155   "#")
4156
4157 (define_split
4158   [(set (match_operand:DF 0 "push_operand" "")
4159         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4160   ""
4161   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4162    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4163
4164 (define_insn "*dummy_extendsfxf2"
4165   [(set (match_operand:XF 0 "push_operand" "=<")
4166         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4167   "0"
4168   "#")
4169
4170 (define_split
4171   [(set (match_operand:XF 0 "push_operand" "")
4172         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4173   ""
4174   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4175    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4176   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4177
4178 (define_split
4179   [(set (match_operand:XF 0 "push_operand" "")
4180         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4181   ""
4182   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4183    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4184   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4185
4186 (define_expand "extendsfdf2"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4188         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4189   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4190 {
4191   /* ??? Needed for compress_float_constant since all fp constants
4192      are LEGITIMATE_CONSTANT_P.  */
4193   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4194     {
4195       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4196           && standard_80387_constant_p (operands[1]) > 0)
4197         {
4198           operands[1] = simplify_const_unary_operation
4199             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4200           emit_move_insn_1 (operands[0], operands[1]);
4201           DONE;
4202         }
4203       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4204     }
4205 })
4206
4207 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4208    cvtss2sd:
4209       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4210       cvtps2pd xmm2,xmm1
4211    We do the conversion post reload to avoid producing of 128bit spills
4212    that might lead to ICE on 32bit target.  The sequence unlikely combine
4213    anyway.  */
4214 (define_split
4215   [(set (match_operand:DF 0 "register_operand" "")
4216         (float_extend:DF
4217           (match_operand:SF 1 "nonimmediate_operand" "")))]
4218   "TARGET_USE_VECTOR_FP_CONVERTS
4219    && optimize_insn_for_speed_p ()
4220    && reload_completed && SSE_REG_P (operands[0])"
4221    [(set (match_dup 2)
4222          (float_extend:V2DF
4223            (vec_select:V2SF
4224              (match_dup 3)
4225              (parallel [(const_int 0) (const_int 1)]))))]
4226 {
4227   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4228   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4229   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4230      Try to avoid move when unpacking can be done in source.  */
4231   if (REG_P (operands[1]))
4232     {
4233       /* If it is unsafe to overwrite upper half of source, we need
4234          to move to destination and unpack there.  */
4235       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4236            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4237           && true_regnum (operands[0]) != true_regnum (operands[1]))
4238         {
4239           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4240           emit_move_insn (tmp, operands[1]);
4241         }
4242       else
4243         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4244       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4245     }
4246   else
4247     emit_insn (gen_vec_setv4sf_0 (operands[3],
4248                                   CONST0_RTX (V4SFmode), operands[1]));
4249 })
4250
4251 (define_insn "*extendsfdf2_mixed"
4252   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4253         (float_extend:DF
4254           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4255   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4256 {
4257   switch (which_alternative)
4258     {
4259     case 0:
4260     case 1:
4261       return output_387_reg_move (insn, operands);
4262
4263     case 2:
4264       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4265
4266     default:
4267       gcc_unreachable ();
4268     }
4269 }
4270   [(set_attr "type" "fmov,fmov,ssecvt")
4271    (set_attr "prefix" "orig,orig,maybe_vex")
4272    (set_attr "mode" "SF,XF,DF")])
4273
4274 (define_insn "*extendsfdf2_sse"
4275   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4276         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4277   "TARGET_SSE2 && TARGET_SSE_MATH"
4278   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4279   [(set_attr "type" "ssecvt")
4280    (set_attr "prefix" "maybe_vex")
4281    (set_attr "mode" "DF")])
4282
4283 (define_insn "*extendsfdf2_i387"
4284   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4285         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4286   "TARGET_80387"
4287   "* return output_387_reg_move (insn, operands);"
4288   [(set_attr "type" "fmov")
4289    (set_attr "mode" "SF,XF")])
4290
4291 (define_expand "extend<mode>xf2"
4292   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4293         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4294   "TARGET_80387"
4295 {
4296   /* ??? Needed for compress_float_constant since all fp constants
4297      are LEGITIMATE_CONSTANT_P.  */
4298   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4299     {
4300       if (standard_80387_constant_p (operands[1]) > 0)
4301         {
4302           operands[1] = simplify_const_unary_operation
4303             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4304           emit_move_insn_1 (operands[0], operands[1]);
4305           DONE;
4306         }
4307       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4308     }
4309 })
4310
4311 (define_insn "*extend<mode>xf2_i387"
4312   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4313         (float_extend:XF
4314           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4315   "TARGET_80387"
4316   "* return output_387_reg_move (insn, operands);"
4317   [(set_attr "type" "fmov")
4318    (set_attr "mode" "<MODE>,XF")])
4319
4320 ;; %%% This seems bad bad news.
4321 ;; This cannot output into an f-reg because there is no way to be sure
4322 ;; of truncating in that case.  Otherwise this is just like a simple move
4323 ;; insn.  So we pretend we can output to a reg in order to get better
4324 ;; register preferencing, but we really use a stack slot.
4325
4326 ;; Conversion from DFmode to SFmode.
4327
4328 (define_expand "truncdfsf2"
4329   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4330         (float_truncate:SF
4331           (match_operand:DF 1 "nonimmediate_operand" "")))]
4332   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4333 {
4334   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4335     ;
4336   else if (flag_unsafe_math_optimizations)
4337     ;
4338   else
4339     {
4340       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4341       rtx temp = assign_386_stack_local (SFmode, slot);
4342       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4343       DONE;
4344     }
4345 })
4346
4347 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4348    cvtsd2ss:
4349       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4350       cvtpd2ps xmm2,xmm1
4351    We do the conversion post reload to avoid producing of 128bit spills
4352    that might lead to ICE on 32bit target.  The sequence unlikely combine
4353    anyway.  */
4354 (define_split
4355   [(set (match_operand:SF 0 "register_operand" "")
4356         (float_truncate:SF
4357           (match_operand:DF 1 "nonimmediate_operand" "")))]
4358   "TARGET_USE_VECTOR_FP_CONVERTS
4359    && optimize_insn_for_speed_p ()
4360    && reload_completed && SSE_REG_P (operands[0])"
4361    [(set (match_dup 2)
4362          (vec_concat:V4SF
4363            (float_truncate:V2SF
4364              (match_dup 4))
4365            (match_dup 3)))]
4366 {
4367   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4368   operands[3] = CONST0_RTX (V2SFmode);
4369   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4370   /* Use movsd for loading from memory, unpcklpd for registers.
4371      Try to avoid move when unpacking can be done in source, or SSE3
4372      movddup is available.  */
4373   if (REG_P (operands[1]))
4374     {
4375       if (!TARGET_SSE3
4376           && true_regnum (operands[0]) != true_regnum (operands[1])
4377           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4378               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4379         {
4380           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4381           emit_move_insn (tmp, operands[1]);
4382           operands[1] = tmp;
4383         }
4384       else if (!TARGET_SSE3)
4385         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4386       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4387     }
4388   else
4389     emit_insn (gen_sse2_loadlpd (operands[4],
4390                                  CONST0_RTX (V2DFmode), operands[1]));
4391 })
4392
4393 (define_expand "truncdfsf2_with_temp"
4394   [(parallel [(set (match_operand:SF 0 "" "")
4395                    (float_truncate:SF (match_operand:DF 1 "" "")))
4396               (clobber (match_operand:SF 2 "" ""))])]
4397   "")
4398
4399 (define_insn "*truncdfsf_fast_mixed"
4400   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4401         (float_truncate:SF
4402           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4403   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4404 {
4405   switch (which_alternative)
4406     {
4407     case 0:
4408       return output_387_reg_move (insn, operands);
4409     case 1:
4410       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4411     default:
4412       gcc_unreachable ();
4413     }
4414 }
4415   [(set_attr "type" "fmov,ssecvt")
4416    (set_attr "prefix" "orig,maybe_vex")
4417    (set_attr "mode" "SF")])
4418
4419 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4420 ;; because nothing we do here is unsafe.
4421 (define_insn "*truncdfsf_fast_sse"
4422   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4423         (float_truncate:SF
4424           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4425   "TARGET_SSE2 && TARGET_SSE_MATH"
4426   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4427   [(set_attr "type" "ssecvt")
4428    (set_attr "prefix" "maybe_vex")
4429    (set_attr "mode" "SF")])
4430
4431 (define_insn "*truncdfsf_fast_i387"
4432   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4433         (float_truncate:SF
4434           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4435   "TARGET_80387 && flag_unsafe_math_optimizations"
4436   "* return output_387_reg_move (insn, operands);"
4437   [(set_attr "type" "fmov")
4438    (set_attr "mode" "SF")])
4439
4440 (define_insn "*truncdfsf_mixed"
4441   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4442         (float_truncate:SF
4443           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4444    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4445   "TARGET_MIX_SSE_I387"
4446 {
4447   switch (which_alternative)
4448     {
4449     case 0:
4450       return output_387_reg_move (insn, operands);
4451
4452     case 1:
4453       return "#";
4454     case 2:
4455       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4456     default:
4457       gcc_unreachable ();
4458     }
4459 }
4460   [(set_attr "type" "fmov,multi,ssecvt")
4461    (set_attr "unit" "*,i387,*")
4462    (set_attr "prefix" "orig,orig,maybe_vex")
4463    (set_attr "mode" "SF")])
4464
4465 (define_insn "*truncdfsf_i387"
4466   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4467         (float_truncate:SF
4468           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4469    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4470   "TARGET_80387"
4471 {
4472   switch (which_alternative)
4473     {
4474     case 0:
4475       return output_387_reg_move (insn, operands);
4476
4477     case 1:
4478       return "#";
4479     default:
4480       gcc_unreachable ();
4481     }
4482 }
4483   [(set_attr "type" "fmov,multi")
4484    (set_attr "unit" "*,i387")
4485    (set_attr "mode" "SF")])
4486
4487 (define_insn "*truncdfsf2_i387_1"
4488   [(set (match_operand:SF 0 "memory_operand" "=m")
4489         (float_truncate:SF
4490           (match_operand:DF 1 "register_operand" "f")))]
4491   "TARGET_80387
4492    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4493    && !TARGET_MIX_SSE_I387"
4494   "* return output_387_reg_move (insn, operands);"
4495   [(set_attr "type" "fmov")
4496    (set_attr "mode" "SF")])
4497
4498 (define_split
4499   [(set (match_operand:SF 0 "register_operand" "")
4500         (float_truncate:SF
4501          (match_operand:DF 1 "fp_register_operand" "")))
4502    (clobber (match_operand 2 "" ""))]
4503   "reload_completed"
4504   [(set (match_dup 2) (match_dup 1))
4505    (set (match_dup 0) (match_dup 2))]
4506 {
4507   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4508 })
4509
4510 ;; Conversion from XFmode to {SF,DF}mode
4511
4512 (define_expand "truncxf<mode>2"
4513   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4514                    (float_truncate:MODEF
4515                      (match_operand:XF 1 "register_operand" "")))
4516               (clobber (match_dup 2))])]
4517   "TARGET_80387"
4518 {
4519   if (flag_unsafe_math_optimizations)
4520     {
4521       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4522       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4523       if (reg != operands[0])
4524         emit_move_insn (operands[0], reg);
4525       DONE;
4526     }
4527   else
4528     {
4529       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4530       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4531     }
4532 })
4533
4534 (define_insn "*truncxfsf2_mixed"
4535   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4536         (float_truncate:SF
4537           (match_operand:XF 1 "register_operand" "f,f")))
4538    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4539   "TARGET_80387"
4540 {
4541   gcc_assert (!which_alternative);
4542   return output_387_reg_move (insn, operands);
4543 }
4544   [(set_attr "type" "fmov,multi")
4545    (set_attr "unit" "*,i387")
4546    (set_attr "mode" "SF")])
4547
4548 (define_insn "*truncxfdf2_mixed"
4549   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4550         (float_truncate:DF
4551           (match_operand:XF 1 "register_operand" "f,f")))
4552    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4553   "TARGET_80387"
4554 {
4555   gcc_assert (!which_alternative);
4556   return output_387_reg_move (insn, operands);
4557 }
4558   [(set_attr "type" "fmov,multi")
4559    (set_attr "unit" "*,i387")
4560    (set_attr "mode" "DF")])
4561
4562 (define_insn "truncxf<mode>2_i387_noop"
4563   [(set (match_operand:MODEF 0 "register_operand" "=f")
4564         (float_truncate:MODEF
4565           (match_operand:XF 1 "register_operand" "f")))]
4566   "TARGET_80387 && flag_unsafe_math_optimizations"
4567   "* return output_387_reg_move (insn, operands);"
4568   [(set_attr "type" "fmov")
4569    (set_attr "mode" "<MODE>")])
4570
4571 (define_insn "*truncxf<mode>2_i387"
4572   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4573         (float_truncate:MODEF
4574           (match_operand:XF 1 "register_operand" "f")))]
4575   "TARGET_80387"
4576   "* return output_387_reg_move (insn, operands);"
4577   [(set_attr "type" "fmov")
4578    (set_attr "mode" "<MODE>")])
4579
4580 (define_split
4581   [(set (match_operand:MODEF 0 "register_operand" "")
4582         (float_truncate:MODEF
4583           (match_operand:XF 1 "register_operand" "")))
4584    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4585   "TARGET_80387 && reload_completed"
4586   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4587    (set (match_dup 0) (match_dup 2))]
4588   "")
4589
4590 (define_split
4591   [(set (match_operand:MODEF 0 "memory_operand" "")
4592         (float_truncate:MODEF
4593           (match_operand:XF 1 "register_operand" "")))
4594    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4595   "TARGET_80387"
4596   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4597   "")
4598 \f
4599 ;; Signed conversion to DImode.
4600
4601 (define_expand "fix_truncxfdi2"
4602   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4603                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4604               (clobber (reg:CC FLAGS_REG))])]
4605   "TARGET_80387"
4606 {
4607   if (TARGET_FISTTP)
4608    {
4609      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4610      DONE;
4611    }
4612 })
4613
4614 (define_expand "fix_trunc<mode>di2"
4615   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4616                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4617               (clobber (reg:CC FLAGS_REG))])]
4618   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4619 {
4620   if (TARGET_FISTTP
4621       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4622    {
4623      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4624      DONE;
4625    }
4626   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4627    {
4628      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4629      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4630      if (out != operands[0])
4631         emit_move_insn (operands[0], out);
4632      DONE;
4633    }
4634 })
4635
4636 ;; Signed conversion to SImode.
4637
4638 (define_expand "fix_truncxfsi2"
4639   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4640                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4641               (clobber (reg:CC FLAGS_REG))])]
4642   "TARGET_80387"
4643 {
4644   if (TARGET_FISTTP)
4645    {
4646      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4647      DONE;
4648    }
4649 })
4650
4651 (define_expand "fix_trunc<mode>si2"
4652   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4653                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4654               (clobber (reg:CC FLAGS_REG))])]
4655   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4656 {
4657   if (TARGET_FISTTP
4658       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4659    {
4660      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4661      DONE;
4662    }
4663   if (SSE_FLOAT_MODE_P (<MODE>mode))
4664    {
4665      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4666      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4667      if (out != operands[0])
4668         emit_move_insn (operands[0], out);
4669      DONE;
4670    }
4671 })
4672
4673 ;; Signed conversion to HImode.
4674
4675 (define_expand "fix_trunc<mode>hi2"
4676   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4677                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4678               (clobber (reg:CC FLAGS_REG))])]
4679   "TARGET_80387
4680    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4681 {
4682   if (TARGET_FISTTP)
4683    {
4684      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4685      DONE;
4686    }
4687 })
4688
4689 ;; Unsigned conversion to SImode.
4690
4691 (define_expand "fixuns_trunc<mode>si2"
4692   [(parallel
4693     [(set (match_operand:SI 0 "register_operand" "")
4694           (unsigned_fix:SI
4695             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4696      (use (match_dup 2))
4697      (clobber (match_scratch:<ssevecmode> 3 ""))
4698      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4699   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4700 {
4701   enum machine_mode mode = <MODE>mode;
4702   enum machine_mode vecmode = <ssevecmode>mode;
4703   REAL_VALUE_TYPE TWO31r;
4704   rtx two31;
4705
4706   if (optimize_insn_for_size_p ())
4707     FAIL;
4708
4709   real_ldexp (&TWO31r, &dconst1, 31);
4710   two31 = const_double_from_real_value (TWO31r, mode);
4711   two31 = ix86_build_const_vector (mode, true, two31);
4712   operands[2] = force_reg (vecmode, two31);
4713 })
4714
4715 (define_insn_and_split "*fixuns_trunc<mode>_1"
4716   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4717         (unsigned_fix:SI
4718           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4719    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4720    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4721    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4722   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4723    && optimize_function_for_speed_p (cfun)"
4724   "#"
4725   "&& reload_completed"
4726   [(const_int 0)]
4727 {
4728   ix86_split_convert_uns_si_sse (operands);
4729   DONE;
4730 })
4731
4732 ;; Unsigned conversion to HImode.
4733 ;; Without these patterns, we'll try the unsigned SI conversion which
4734 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4735
4736 (define_expand "fixuns_trunc<mode>hi2"
4737   [(set (match_dup 2)
4738         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4739    (set (match_operand:HI 0 "nonimmediate_operand" "")
4740         (subreg:HI (match_dup 2) 0))]
4741   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4742   "operands[2] = gen_reg_rtx (SImode);")
4743
4744 ;; When SSE is available, it is always faster to use it!
4745 (define_insn "fix_trunc<mode>di_sse"
4746   [(set (match_operand:DI 0 "register_operand" "=r,r")
4747         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4748   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4749    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4750   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4751   [(set_attr "type" "sseicvt")
4752    (set_attr "prefix" "maybe_vex")
4753    (set_attr "mode" "<MODE>")
4754    (set_attr "athlon_decode" "double,vector")
4755    (set_attr "amdfam10_decode" "double,double")])
4756
4757 (define_insn "fix_trunc<mode>si_sse"
4758   [(set (match_operand:SI 0 "register_operand" "=r,r")
4759         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4760   "SSE_FLOAT_MODE_P (<MODE>mode)
4761    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4762   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4763   [(set_attr "type" "sseicvt")
4764    (set_attr "prefix" "maybe_vex")
4765    (set_attr "mode" "<MODE>")
4766    (set_attr "athlon_decode" "double,vector")
4767    (set_attr "amdfam10_decode" "double,double")])
4768
4769 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4770 (define_peephole2
4771   [(set (match_operand:MODEF 0 "register_operand" "")
4772         (match_operand:MODEF 1 "memory_operand" ""))
4773    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4774         (fix:SSEMODEI24 (match_dup 0)))]
4775   "TARGET_SHORTEN_X87_SSE
4776    && peep2_reg_dead_p (2, operands[0])"
4777   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4778   "")
4779
4780 ;; Avoid vector decoded forms of the instruction.
4781 (define_peephole2
4782   [(match_scratch:DF 2 "Y2")
4783    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4784         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4785   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4786   [(set (match_dup 2) (match_dup 1))
4787    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4788   "")
4789
4790 (define_peephole2
4791   [(match_scratch:SF 2 "x")
4792    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4793         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4794   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4795   [(set (match_dup 2) (match_dup 1))
4796    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4797   "")
4798
4799 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4800   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4801         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4802   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4803    && TARGET_FISTTP
4804    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4805          && (TARGET_64BIT || <MODE>mode != DImode))
4806         && TARGET_SSE_MATH)
4807    && !(reload_completed || reload_in_progress)"
4808   "#"
4809   "&& 1"
4810   [(const_int 0)]
4811 {
4812   if (memory_operand (operands[0], VOIDmode))
4813     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4814   else
4815     {
4816       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4817       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4818                                                             operands[1],
4819                                                             operands[2]));
4820     }
4821   DONE;
4822 }
4823   [(set_attr "type" "fisttp")
4824    (set_attr "mode" "<MODE>")])
4825
4826 (define_insn "fix_trunc<mode>_i387_fisttp"
4827   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4828         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4829    (clobber (match_scratch:XF 2 "=&1f"))]
4830   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4831    && TARGET_FISTTP
4832    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4833          && (TARGET_64BIT || <MODE>mode != DImode))
4834         && TARGET_SSE_MATH)"
4835   "* return output_fix_trunc (insn, operands, 1);"
4836   [(set_attr "type" "fisttp")
4837    (set_attr "mode" "<MODE>")])
4838
4839 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4840   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4841         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4842    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4843    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4844   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4845    && TARGET_FISTTP
4846    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4847         && (TARGET_64BIT || <MODE>mode != DImode))
4848         && TARGET_SSE_MATH)"
4849   "#"
4850   [(set_attr "type" "fisttp")
4851    (set_attr "mode" "<MODE>")])
4852
4853 (define_split
4854   [(set (match_operand:X87MODEI 0 "register_operand" "")
4855         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4856    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4857    (clobber (match_scratch 3 ""))]
4858   "reload_completed"
4859   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4860               (clobber (match_dup 3))])
4861    (set (match_dup 0) (match_dup 2))]
4862   "")
4863
4864 (define_split
4865   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4866         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4867    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4868    (clobber (match_scratch 3 ""))]
4869   "reload_completed"
4870   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4871               (clobber (match_dup 3))])]
4872   "")
4873
4874 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4875 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4876 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4877 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4878 ;; function in i386.c.
4879 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4880   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4881         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4882    (clobber (reg:CC FLAGS_REG))]
4883   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4884    && !TARGET_FISTTP
4885    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4886          && (TARGET_64BIT || <MODE>mode != DImode))
4887    && !(reload_completed || reload_in_progress)"
4888   "#"
4889   "&& 1"
4890   [(const_int 0)]
4891 {
4892   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4893
4894   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4895   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4896   if (memory_operand (operands[0], VOIDmode))
4897     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4898                                          operands[2], operands[3]));
4899   else
4900     {
4901       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4902       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4903                                                      operands[2], operands[3],
4904                                                      operands[4]));
4905     }
4906   DONE;
4907 }
4908   [(set_attr "type" "fistp")
4909    (set_attr "i387_cw" "trunc")
4910    (set_attr "mode" "<MODE>")])
4911
4912 (define_insn "fix_truncdi_i387"
4913   [(set (match_operand:DI 0 "memory_operand" "=m")
4914         (fix:DI (match_operand 1 "register_operand" "f")))
4915    (use (match_operand:HI 2 "memory_operand" "m"))
4916    (use (match_operand:HI 3 "memory_operand" "m"))
4917    (clobber (match_scratch:XF 4 "=&1f"))]
4918   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4919    && !TARGET_FISTTP
4920    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4921   "* return output_fix_trunc (insn, operands, 0);"
4922   [(set_attr "type" "fistp")
4923    (set_attr "i387_cw" "trunc")
4924    (set_attr "mode" "DI")])
4925
4926 (define_insn "fix_truncdi_i387_with_temp"
4927   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4928         (fix:DI (match_operand 1 "register_operand" "f,f")))
4929    (use (match_operand:HI 2 "memory_operand" "m,m"))
4930    (use (match_operand:HI 3 "memory_operand" "m,m"))
4931    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4932    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4933   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4934    && !TARGET_FISTTP
4935    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4936   "#"
4937   [(set_attr "type" "fistp")
4938    (set_attr "i387_cw" "trunc")
4939    (set_attr "mode" "DI")])
4940
4941 (define_split
4942   [(set (match_operand:DI 0 "register_operand" "")
4943         (fix:DI (match_operand 1 "register_operand" "")))
4944    (use (match_operand:HI 2 "memory_operand" ""))
4945    (use (match_operand:HI 3 "memory_operand" ""))
4946    (clobber (match_operand:DI 4 "memory_operand" ""))
4947    (clobber (match_scratch 5 ""))]
4948   "reload_completed"
4949   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4950               (use (match_dup 2))
4951               (use (match_dup 3))
4952               (clobber (match_dup 5))])
4953    (set (match_dup 0) (match_dup 4))]
4954   "")
4955
4956 (define_split
4957   [(set (match_operand:DI 0 "memory_operand" "")
4958         (fix:DI (match_operand 1 "register_operand" "")))
4959    (use (match_operand:HI 2 "memory_operand" ""))
4960    (use (match_operand:HI 3 "memory_operand" ""))
4961    (clobber (match_operand:DI 4 "memory_operand" ""))
4962    (clobber (match_scratch 5 ""))]
4963   "reload_completed"
4964   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4965               (use (match_dup 2))
4966               (use (match_dup 3))
4967               (clobber (match_dup 5))])]
4968   "")
4969
4970 (define_insn "fix_trunc<mode>_i387"
4971   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4972         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4973    (use (match_operand:HI 2 "memory_operand" "m"))
4974    (use (match_operand:HI 3 "memory_operand" "m"))]
4975   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976    && !TARGET_FISTTP
4977    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4978   "* return output_fix_trunc (insn, operands, 0);"
4979   [(set_attr "type" "fistp")
4980    (set_attr "i387_cw" "trunc")
4981    (set_attr "mode" "<MODE>")])
4982
4983 (define_insn "fix_trunc<mode>_i387_with_temp"
4984   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4985         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4986    (use (match_operand:HI 2 "memory_operand" "m,m"))
4987    (use (match_operand:HI 3 "memory_operand" "m,m"))
4988    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4989   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990    && !TARGET_FISTTP
4991    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4992   "#"
4993   [(set_attr "type" "fistp")
4994    (set_attr "i387_cw" "trunc")
4995    (set_attr "mode" "<MODE>")])
4996
4997 (define_split
4998   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4999         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5000    (use (match_operand:HI 2 "memory_operand" ""))
5001    (use (match_operand:HI 3 "memory_operand" ""))
5002    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5003   "reload_completed"
5004   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5005               (use (match_dup 2))
5006               (use (match_dup 3))])
5007    (set (match_dup 0) (match_dup 4))]
5008   "")
5009
5010 (define_split
5011   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5012         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5013    (use (match_operand:HI 2 "memory_operand" ""))
5014    (use (match_operand:HI 3 "memory_operand" ""))
5015    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5016   "reload_completed"
5017   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5018               (use (match_dup 2))
5019               (use (match_dup 3))])]
5020   "")
5021
5022 (define_insn "x86_fnstcw_1"
5023   [(set (match_operand:HI 0 "memory_operand" "=m")
5024         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5025   "TARGET_80387"
5026   "fnstcw\t%0"
5027   [(set_attr "length" "2")
5028    (set_attr "mode" "HI")
5029    (set_attr "unit" "i387")])
5030
5031 (define_insn "x86_fldcw_1"
5032   [(set (reg:HI FPCR_REG)
5033         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5034   "TARGET_80387"
5035   "fldcw\t%0"
5036   [(set_attr "length" "2")
5037    (set_attr "mode" "HI")
5038    (set_attr "unit" "i387")
5039    (set_attr "athlon_decode" "vector")
5040    (set_attr "amdfam10_decode" "vector")])
5041 \f
5042 ;; Conversion between fixed point and floating point.
5043
5044 ;; Even though we only accept memory inputs, the backend _really_
5045 ;; wants to be able to do this between registers.
5046
5047 (define_expand "floathi<mode>2"
5048   [(set (match_operand:X87MODEF 0 "register_operand" "")
5049         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5050   "TARGET_80387
5051    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5052        || TARGET_MIX_SSE_I387)"
5053   "")
5054
5055 ;; Pre-reload splitter to add memory clobber to the pattern.
5056 (define_insn_and_split "*floathi<mode>2_1"
5057   [(set (match_operand:X87MODEF 0 "register_operand" "")
5058         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5059   "TARGET_80387
5060    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5061        || TARGET_MIX_SSE_I387)
5062    && !(reload_completed || reload_in_progress)"
5063   "#"
5064   "&& 1"
5065   [(parallel [(set (match_dup 0)
5066               (float:X87MODEF (match_dup 1)))
5067    (clobber (match_dup 2))])]
5068   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5069
5070 (define_insn "*floathi<mode>2_i387_with_temp"
5071   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5072         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5073   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5074   "TARGET_80387
5075    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5076        || TARGET_MIX_SSE_I387)"
5077   "#"
5078   [(set_attr "type" "fmov,multi")
5079    (set_attr "mode" "<MODE>")
5080    (set_attr "unit" "*,i387")
5081    (set_attr "fp_int_src" "true")])
5082
5083 (define_insn "*floathi<mode>2_i387"
5084   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5085         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5086   "TARGET_80387
5087    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5088        || TARGET_MIX_SSE_I387)"
5089   "fild%z1\t%1"
5090   [(set_attr "type" "fmov")
5091    (set_attr "mode" "<MODE>")
5092    (set_attr "fp_int_src" "true")])
5093
5094 (define_split
5095   [(set (match_operand:X87MODEF 0 "register_operand" "")
5096         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5097    (clobber (match_operand:HI 2 "memory_operand" ""))]
5098   "TARGET_80387
5099    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5100        || TARGET_MIX_SSE_I387)
5101    && reload_completed"
5102   [(set (match_dup 2) (match_dup 1))
5103    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5104   "")
5105
5106 (define_split
5107   [(set (match_operand:X87MODEF 0 "register_operand" "")
5108         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5109    (clobber (match_operand:HI 2 "memory_operand" ""))]
5110    "TARGET_80387
5111     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5112         || TARGET_MIX_SSE_I387)
5113     && reload_completed"
5114   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5115   "")
5116
5117 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5118   [(set (match_operand:X87MODEF 0 "register_operand" "")
5119         (float:X87MODEF
5120           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5121   "TARGET_80387
5122    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5123        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5124   "")
5125
5126 ;; Pre-reload splitter to add memory clobber to the pattern.
5127 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5128   [(set (match_operand:X87MODEF 0 "register_operand" "")
5129         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5130   "((TARGET_80387
5131      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5132            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5133          || TARGET_MIX_SSE_I387))
5134     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5135         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5136         && ((<SSEMODEI24:MODE>mode == SImode
5137              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5138              && optimize_function_for_speed_p (cfun)
5139              && flag_trapping_math)
5140             || !(TARGET_INTER_UNIT_CONVERSIONS
5141                  || optimize_function_for_size_p (cfun)))))
5142    && !(reload_completed || reload_in_progress)"
5143   "#"
5144   "&& 1"
5145   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5146               (clobber (match_dup 2))])]
5147 {
5148   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5149
5150   /* Avoid store forwarding (partial memory) stall penalty
5151      by passing DImode value through XMM registers.  */
5152   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5153       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5154       && optimize_function_for_speed_p (cfun))
5155     {
5156       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5157                                                             operands[1],
5158                                                             operands[2]));
5159       DONE;
5160     }
5161 })
5162
5163 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5164   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5165         (float:MODEF
5166           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5167    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5168   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5169    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5170   "#"
5171   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5172    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5173    (set_attr "unit" "*,i387,*,*,*")
5174    (set_attr "athlon_decode" "*,*,double,direct,double")
5175    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5176    (set_attr "fp_int_src" "true")])
5177
5178 (define_insn "*floatsi<mode>2_vector_mixed"
5179   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5180         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5181   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5182    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5183   "@
5184    fild%z1\t%1
5185    #"
5186   [(set_attr "type" "fmov,sseicvt")
5187    (set_attr "mode" "<MODE>,<ssevecmode>")
5188    (set_attr "unit" "i387,*")
5189    (set_attr "athlon_decode" "*,direct")
5190    (set_attr "amdfam10_decode" "*,double")
5191    (set_attr "fp_int_src" "true")])
5192
5193 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5194   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5195         (float:MODEF
5196           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5197   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5198   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5199    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5200   "#"
5201   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5202    (set_attr "mode" "<MODEF:MODE>")
5203    (set_attr "unit" "*,i387,*,*")
5204    (set_attr "athlon_decode" "*,*,double,direct")
5205    (set_attr "amdfam10_decode" "*,*,vector,double")
5206    (set_attr "fp_int_src" "true")])
5207
5208 (define_split
5209   [(set (match_operand:MODEF 0 "register_operand" "")
5210         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5211    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5212   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5214    && TARGET_INTER_UNIT_CONVERSIONS
5215    && reload_completed
5216    && (SSE_REG_P (operands[0])
5217        || (GET_CODE (operands[0]) == SUBREG
5218            && SSE_REG_P (operands[0])))"
5219   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5220   "")
5221
5222 (define_split
5223   [(set (match_operand:MODEF 0 "register_operand" "")
5224         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5225    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5226   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5227    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5228    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5229    && reload_completed
5230    && (SSE_REG_P (operands[0])
5231        || (GET_CODE (operands[0]) == SUBREG
5232            && SSE_REG_P (operands[0])))"
5233   [(set (match_dup 2) (match_dup 1))
5234    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5235   "")
5236
5237 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5238   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5239         (float:MODEF
5240           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5241   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5243    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5244   "@
5245    fild%z1\t%1
5246    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5247    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5248   [(set_attr "type" "fmov,sseicvt,sseicvt")
5249    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5250    (set_attr "mode" "<MODEF:MODE>")
5251    (set_attr "unit" "i387,*,*")
5252    (set_attr "athlon_decode" "*,double,direct")
5253    (set_attr "amdfam10_decode" "*,vector,double")
5254    (set_attr "fp_int_src" "true")])
5255
5256 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5257   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5258         (float:MODEF
5259           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5260   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5261    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5262    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5263   "@
5264    fild%z1\t%1
5265    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5266   [(set_attr "type" "fmov,sseicvt")
5267    (set_attr "prefix" "orig,maybe_vex")
5268    (set_attr "mode" "<MODEF:MODE>")
5269    (set_attr "athlon_decode" "*,direct")
5270    (set_attr "amdfam10_decode" "*,double")
5271    (set_attr "fp_int_src" "true")])
5272
5273 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5274   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5275         (float:MODEF
5276           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5277    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5278   "TARGET_SSE2 && TARGET_SSE_MATH
5279    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5280   "#"
5281   [(set_attr "type" "sseicvt")
5282    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5283    (set_attr "athlon_decode" "double,direct,double")
5284    (set_attr "amdfam10_decode" "vector,double,double")
5285    (set_attr "fp_int_src" "true")])
5286
5287 (define_insn "*floatsi<mode>2_vector_sse"
5288   [(set (match_operand:MODEF 0 "register_operand" "=x")
5289         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5290   "TARGET_SSE2 && TARGET_SSE_MATH
5291    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5292   "#"
5293   [(set_attr "type" "sseicvt")
5294    (set_attr "mode" "<MODE>")
5295    (set_attr "athlon_decode" "direct")
5296    (set_attr "amdfam10_decode" "double")
5297    (set_attr "fp_int_src" "true")])
5298
5299 (define_split
5300   [(set (match_operand:MODEF 0 "register_operand" "")
5301         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5302    (clobber (match_operand:SI 2 "memory_operand" ""))]
5303   "TARGET_SSE2 && TARGET_SSE_MATH
5304    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5305    && reload_completed
5306    && (SSE_REG_P (operands[0])
5307        || (GET_CODE (operands[0]) == SUBREG
5308            && SSE_REG_P (operands[0])))"
5309   [(const_int 0)]
5310 {
5311   rtx op1 = operands[1];
5312
5313   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5314                                      <MODE>mode, 0);
5315   if (GET_CODE (op1) == SUBREG)
5316     op1 = SUBREG_REG (op1);
5317
5318   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5319     {
5320       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5321       emit_insn (gen_sse2_loadld (operands[4],
5322                                   CONST0_RTX (V4SImode), operands[1]));
5323     }
5324   /* We can ignore possible trapping value in the
5325      high part of SSE register for non-trapping math. */
5326   else if (SSE_REG_P (op1) && !flag_trapping_math)
5327     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5328   else
5329     {
5330       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5331       emit_move_insn (operands[2], operands[1]);
5332       emit_insn (gen_sse2_loadld (operands[4],
5333                                   CONST0_RTX (V4SImode), operands[2]));
5334     }
5335   emit_insn
5336     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5337   DONE;
5338 })
5339
5340 (define_split
5341   [(set (match_operand:MODEF 0 "register_operand" "")
5342         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5343    (clobber (match_operand:SI 2 "memory_operand" ""))]
5344   "TARGET_SSE2 && TARGET_SSE_MATH
5345    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5346    && reload_completed
5347    && (SSE_REG_P (operands[0])
5348        || (GET_CODE (operands[0]) == SUBREG
5349            && SSE_REG_P (operands[0])))"
5350   [(const_int 0)]
5351 {
5352   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5353                                      <MODE>mode, 0);
5354   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5355
5356   emit_insn (gen_sse2_loadld (operands[4],
5357                               CONST0_RTX (V4SImode), operands[1]));
5358   emit_insn
5359     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5360   DONE;
5361 })
5362
5363 (define_split
5364   [(set (match_operand:MODEF 0 "register_operand" "")
5365         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5366   "TARGET_SSE2 && TARGET_SSE_MATH
5367    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5368    && reload_completed
5369    && (SSE_REG_P (operands[0])
5370        || (GET_CODE (operands[0]) == SUBREG
5371            && SSE_REG_P (operands[0])))"
5372   [(const_int 0)]
5373 {
5374   rtx op1 = operands[1];
5375
5376   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5377                                      <MODE>mode, 0);
5378   if (GET_CODE (op1) == SUBREG)
5379     op1 = SUBREG_REG (op1);
5380
5381   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5382     {
5383       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5384       emit_insn (gen_sse2_loadld (operands[4],
5385                                   CONST0_RTX (V4SImode), operands[1]));
5386     }
5387   /* We can ignore possible trapping value in the
5388      high part of SSE register for non-trapping math. */
5389   else if (SSE_REG_P (op1) && !flag_trapping_math)
5390     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5391   else
5392     gcc_unreachable ();
5393   emit_insn
5394     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5395   DONE;
5396 })
5397
5398 (define_split
5399   [(set (match_operand:MODEF 0 "register_operand" "")
5400         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5401   "TARGET_SSE2 && TARGET_SSE_MATH
5402    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5403    && reload_completed
5404    && (SSE_REG_P (operands[0])
5405        || (GET_CODE (operands[0]) == SUBREG
5406            && SSE_REG_P (operands[0])))"
5407   [(const_int 0)]
5408 {
5409   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5410                                      <MODE>mode, 0);
5411   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5412
5413   emit_insn (gen_sse2_loadld (operands[4],
5414                               CONST0_RTX (V4SImode), operands[1]));
5415   emit_insn
5416     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5417   DONE;
5418 })
5419
5420 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5421   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5422         (float:MODEF
5423           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5424   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5425   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5426    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5427   "#"
5428   [(set_attr "type" "sseicvt")
5429    (set_attr "mode" "<MODEF:MODE>")
5430    (set_attr "athlon_decode" "double,direct")
5431    (set_attr "amdfam10_decode" "vector,double")
5432    (set_attr "fp_int_src" "true")])
5433
5434 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5435   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5436         (float:MODEF
5437           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5438   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5439    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5440    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5441   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5442   [(set_attr "type" "sseicvt")
5443    (set_attr "prefix" "maybe_vex")
5444    (set_attr "mode" "<MODEF:MODE>")
5445    (set_attr "athlon_decode" "double,direct")
5446    (set_attr "amdfam10_decode" "vector,double")
5447    (set_attr "fp_int_src" "true")])
5448
5449 (define_split
5450   [(set (match_operand:MODEF 0 "register_operand" "")
5451         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5452    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5453   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5454    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5455    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5456    && reload_completed
5457    && (SSE_REG_P (operands[0])
5458        || (GET_CODE (operands[0]) == SUBREG
5459            && SSE_REG_P (operands[0])))"
5460   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5461   "")
5462
5463 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5464   [(set (match_operand:MODEF 0 "register_operand" "=x")
5465         (float:MODEF
5466           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5467   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5468    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5469    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5470   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5471   [(set_attr "type" "sseicvt")
5472    (set_attr "prefix" "maybe_vex")
5473    (set_attr "mode" "<MODEF:MODE>")
5474    (set_attr "athlon_decode" "direct")
5475    (set_attr "amdfam10_decode" "double")
5476    (set_attr "fp_int_src" "true")])
5477
5478 (define_split
5479   [(set (match_operand:MODEF 0 "register_operand" "")
5480         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5481    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5482   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5483    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5484    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5485    && reload_completed
5486    && (SSE_REG_P (operands[0])
5487        || (GET_CODE (operands[0]) == SUBREG
5488            && SSE_REG_P (operands[0])))"
5489   [(set (match_dup 2) (match_dup 1))
5490    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5491   "")
5492
5493 (define_split
5494   [(set (match_operand:MODEF 0 "register_operand" "")
5495         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5496    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5497   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5498    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5499    && reload_completed
5500    && (SSE_REG_P (operands[0])
5501        || (GET_CODE (operands[0]) == SUBREG
5502            && SSE_REG_P (operands[0])))"
5503   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5504   "")
5505
5506 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5507   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5508         (float:X87MODEF
5509           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5510   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5511   "TARGET_80387"
5512   "@
5513    fild%z1\t%1
5514    #"
5515   [(set_attr "type" "fmov,multi")
5516    (set_attr "mode" "<X87MODEF:MODE>")
5517    (set_attr "unit" "*,i387")
5518    (set_attr "fp_int_src" "true")])
5519
5520 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5521   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5522         (float:X87MODEF
5523           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5524   "TARGET_80387"
5525   "fild%z1\t%1"
5526   [(set_attr "type" "fmov")
5527    (set_attr "mode" "<X87MODEF:MODE>")
5528    (set_attr "fp_int_src" "true")])
5529
5530 (define_split
5531   [(set (match_operand:X87MODEF 0 "register_operand" "")
5532         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5533    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5534   "TARGET_80387
5535    && reload_completed
5536    && FP_REG_P (operands[0])"
5537   [(set (match_dup 2) (match_dup 1))
5538    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5539   "")
5540
5541 (define_split
5542   [(set (match_operand:X87MODEF 0 "register_operand" "")
5543         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5544    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5545   "TARGET_80387
5546    && reload_completed
5547    && FP_REG_P (operands[0])"
5548   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5549   "")
5550
5551 ;; Avoid store forwarding (partial memory) stall penalty
5552 ;; by passing DImode value through XMM registers.  */
5553
5554 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5555   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5556         (float:X87MODEF
5557           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5558    (clobber (match_scratch:V4SI 3 "=X,x"))
5559    (clobber (match_scratch:V4SI 4 "=X,x"))
5560    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5561   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5562    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5563   "#"
5564   [(set_attr "type" "multi")
5565    (set_attr "mode" "<X87MODEF:MODE>")
5566    (set_attr "unit" "i387")
5567    (set_attr "fp_int_src" "true")])
5568
5569 (define_split
5570   [(set (match_operand:X87MODEF 0 "register_operand" "")
5571         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5572    (clobber (match_scratch:V4SI 3 ""))
5573    (clobber (match_scratch:V4SI 4 ""))
5574    (clobber (match_operand:DI 2 "memory_operand" ""))]
5575   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5576    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5577    && reload_completed
5578    && FP_REG_P (operands[0])"
5579   [(set (match_dup 2) (match_dup 3))
5580    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5581 {
5582   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5583      Assemble the 64-bit DImode value in an xmm register.  */
5584   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5585                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5586   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5587                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5588   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5589
5590   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5591 })
5592
5593 (define_split
5594   [(set (match_operand:X87MODEF 0 "register_operand" "")
5595         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5596    (clobber (match_scratch:V4SI 3 ""))
5597    (clobber (match_scratch:V4SI 4 ""))
5598    (clobber (match_operand:DI 2 "memory_operand" ""))]
5599   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5600    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5601    && reload_completed
5602    && FP_REG_P (operands[0])"
5603   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5604   "")
5605
5606 ;; Avoid store forwarding (partial memory) stall penalty by extending
5607 ;; SImode value to DImode through XMM register instead of pushing two
5608 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5609 ;; targets benefit from this optimization. Also note that fild
5610 ;; loads from memory only.
5611
5612 (define_insn "*floatunssi<mode>2_1"
5613   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5614         (unsigned_float:X87MODEF
5615           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5616    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5617    (clobber (match_scratch:SI 3 "=X,x"))]
5618   "!TARGET_64BIT
5619    && TARGET_80387 && TARGET_SSE"
5620   "#"
5621   [(set_attr "type" "multi")
5622    (set_attr "mode" "<MODE>")])
5623
5624 (define_split
5625   [(set (match_operand:X87MODEF 0 "register_operand" "")
5626         (unsigned_float:X87MODEF
5627           (match_operand:SI 1 "register_operand" "")))
5628    (clobber (match_operand:DI 2 "memory_operand" ""))
5629    (clobber (match_scratch:SI 3 ""))]
5630   "!TARGET_64BIT
5631    && TARGET_80387 && TARGET_SSE
5632    && reload_completed"
5633   [(set (match_dup 2) (match_dup 1))
5634    (set (match_dup 0)
5635         (float:X87MODEF (match_dup 2)))]
5636   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5637
5638 (define_split
5639   [(set (match_operand:X87MODEF 0 "register_operand" "")
5640         (unsigned_float:X87MODEF
5641           (match_operand:SI 1 "memory_operand" "")))
5642    (clobber (match_operand:DI 2 "memory_operand" ""))
5643    (clobber (match_scratch:SI 3 ""))]
5644   "!TARGET_64BIT
5645    && TARGET_80387 && TARGET_SSE
5646    && reload_completed"
5647   [(set (match_dup 2) (match_dup 3))
5648    (set (match_dup 0)
5649         (float:X87MODEF (match_dup 2)))]
5650 {
5651   emit_move_insn (operands[3], operands[1]);
5652   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5653 })
5654
5655 (define_expand "floatunssi<mode>2"
5656   [(parallel
5657      [(set (match_operand:X87MODEF 0 "register_operand" "")
5658            (unsigned_float:X87MODEF
5659              (match_operand:SI 1 "nonimmediate_operand" "")))
5660       (clobber (match_dup 2))
5661       (clobber (match_scratch:SI 3 ""))])]
5662   "!TARGET_64BIT
5663    && ((TARGET_80387 && TARGET_SSE)
5664        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5665 {
5666   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5667     {
5668       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5669       DONE;
5670     }
5671   else
5672     {
5673       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5674       operands[2] = assign_386_stack_local (DImode, slot);
5675     }
5676 })
5677
5678 (define_expand "floatunsdisf2"
5679   [(use (match_operand:SF 0 "register_operand" ""))
5680    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5681   "TARGET_64BIT && TARGET_SSE_MATH"
5682   "x86_emit_floatuns (operands); DONE;")
5683
5684 (define_expand "floatunsdidf2"
5685   [(use (match_operand:DF 0 "register_operand" ""))
5686    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5687   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5688    && TARGET_SSE2 && TARGET_SSE_MATH"
5689 {
5690   if (TARGET_64BIT)
5691     x86_emit_floatuns (operands);
5692   else
5693     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5694   DONE;
5695 })
5696 \f
5697 ;; Add instructions
5698
5699 ;; %%% splits for addditi3
5700
5701 (define_expand "addti3"
5702   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5703         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5704                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5705   "TARGET_64BIT"
5706   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5707
5708 (define_insn "*addti3_1"
5709   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5710         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5711                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5712    (clobber (reg:CC FLAGS_REG))]
5713   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5714   "#")
5715
5716 (define_split
5717   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5718         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5719                  (match_operand:TI 2 "x86_64_general_operand" "")))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "TARGET_64BIT && reload_completed"
5722   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5723                                           UNSPEC_ADD_CARRY))
5724               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5725    (parallel [(set (match_dup 3)
5726                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5727                                      (match_dup 4))
5728                             (match_dup 5)))
5729               (clobber (reg:CC FLAGS_REG))])]
5730   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5731
5732 ;; %%% splits for addsidi3
5733 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5734 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5735 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5736
5737 (define_expand "adddi3"
5738   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5739         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5740                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5741   ""
5742   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5743
5744 (define_insn "*adddi3_1"
5745   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5746         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5747                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5748    (clobber (reg:CC FLAGS_REG))]
5749   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5750   "#")
5751
5752 (define_split
5753   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5754         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5755                  (match_operand:DI 2 "general_operand" "")))
5756    (clobber (reg:CC FLAGS_REG))]
5757   "!TARGET_64BIT && reload_completed"
5758   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5759                                           UNSPEC_ADD_CARRY))
5760               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5761    (parallel [(set (match_dup 3)
5762                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5763                                      (match_dup 4))
5764                             (match_dup 5)))
5765               (clobber (reg:CC FLAGS_REG))])]
5766   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5767
5768 (define_insn "adddi3_carry_rex64"
5769   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5770           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5771                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5772                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5773    (clobber (reg:CC FLAGS_REG))]
5774   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5775   "adc{q}\t{%2, %0|%0, %2}"
5776   [(set_attr "type" "alu")
5777    (set_attr "pent_pair" "pu")
5778    (set_attr "mode" "DI")])
5779
5780 (define_insn "*adddi3_cc_rex64"
5781   [(set (reg:CC FLAGS_REG)
5782         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5783                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5784                    UNSPEC_ADD_CARRY))
5785    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5786         (plus:DI (match_dup 1) (match_dup 2)))]
5787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5788   "add{q}\t{%2, %0|%0, %2}"
5789   [(set_attr "type" "alu")
5790    (set_attr "mode" "DI")])
5791
5792 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5793   [(set (reg:CCC FLAGS_REG)
5794         (compare:CCC
5795             (plusminus:SWI
5796                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5797                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5798             (match_dup 1)))
5799    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5800         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5801   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5802   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5803   [(set_attr "type" "alu")
5804    (set_attr "mode" "<MODE>")])
5805
5806 (define_insn "*add<mode>3_cconly_overflow"
5807   [(set (reg:CCC FLAGS_REG)
5808         (compare:CCC
5809                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5810                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5811                 (match_dup 1)))
5812    (clobber (match_scratch:SWI 0 "=<r>"))]
5813   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5814   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5815   [(set_attr "type" "alu")
5816    (set_attr "mode" "<MODE>")])
5817
5818 (define_insn "*sub<mode>3_cconly_overflow"
5819   [(set (reg:CCC FLAGS_REG)
5820         (compare:CCC
5821              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5822                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5823              (match_dup 0)))]
5824   ""
5825   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5826   [(set_attr "type" "icmp")
5827    (set_attr "mode" "<MODE>")])
5828
5829 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5830   [(set (reg:CCC FLAGS_REG)
5831         (compare:CCC
5832             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5833                           (match_operand:SI 2 "general_operand" "g"))
5834             (match_dup 1)))
5835    (set (match_operand:DI 0 "register_operand" "=r")
5836         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5837   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5838   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5839   [(set_attr "type" "alu")
5840    (set_attr "mode" "SI")])
5841
5842 (define_insn "addqi3_carry"
5843   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5844           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5845                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5846                    (match_operand:QI 2 "general_operand" "qn,qm")))
5847    (clobber (reg:CC FLAGS_REG))]
5848   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5849   "adc{b}\t{%2, %0|%0, %2}"
5850   [(set_attr "type" "alu")
5851    (set_attr "pent_pair" "pu")
5852    (set_attr "mode" "QI")])
5853
5854 (define_insn "addhi3_carry"
5855   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5856           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5857                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5858                    (match_operand:HI 2 "general_operand" "rn,rm")))
5859    (clobber (reg:CC FLAGS_REG))]
5860   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5861   "adc{w}\t{%2, %0|%0, %2}"
5862   [(set_attr "type" "alu")
5863    (set_attr "pent_pair" "pu")
5864    (set_attr "mode" "HI")])
5865
5866 (define_insn "addsi3_carry"
5867   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5868           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5869                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5870                    (match_operand:SI 2 "general_operand" "ri,rm")))
5871    (clobber (reg:CC FLAGS_REG))]
5872   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5873   "adc{l}\t{%2, %0|%0, %2}"
5874   [(set_attr "type" "alu")
5875    (set_attr "pent_pair" "pu")
5876    (set_attr "mode" "SI")])
5877
5878 (define_insn "*addsi3_carry_zext"
5879   [(set (match_operand:DI 0 "register_operand" "=r")
5880           (zero_extend:DI
5881             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5882                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5883                      (match_operand:SI 2 "general_operand" "g"))))
5884    (clobber (reg:CC FLAGS_REG))]
5885   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5886   "adc{l}\t{%2, %k0|%k0, %2}"
5887   [(set_attr "type" "alu")
5888    (set_attr "pent_pair" "pu")
5889    (set_attr "mode" "SI")])
5890
5891 (define_insn "*addsi3_cc"
5892   [(set (reg:CC FLAGS_REG)
5893         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5894                     (match_operand:SI 2 "general_operand" "ri,rm")]
5895                    UNSPEC_ADD_CARRY))
5896    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5897         (plus:SI (match_dup 1) (match_dup 2)))]
5898   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5899   "add{l}\t{%2, %0|%0, %2}"
5900   [(set_attr "type" "alu")
5901    (set_attr "mode" "SI")])
5902
5903 (define_insn "addqi3_cc"
5904   [(set (reg:CC FLAGS_REG)
5905         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5906                     (match_operand:QI 2 "general_operand" "qn,qm")]
5907                    UNSPEC_ADD_CARRY))
5908    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5909         (plus:QI (match_dup 1) (match_dup 2)))]
5910   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5911   "add{b}\t{%2, %0|%0, %2}"
5912   [(set_attr "type" "alu")
5913    (set_attr "mode" "QI")])
5914
5915 (define_expand "addsi3"
5916   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5917         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5918                  (match_operand:SI 2 "general_operand" "")))]
5919   ""
5920   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5921
5922 (define_insn "*lea_1"
5923   [(set (match_operand:SI 0 "register_operand" "=r")
5924         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5925   "!TARGET_64BIT"
5926   "lea{l}\t{%a1, %0|%0, %a1}"
5927   [(set_attr "type" "lea")
5928    (set_attr "mode" "SI")])
5929
5930 (define_insn "*lea_1_rex64"
5931   [(set (match_operand:SI 0 "register_operand" "=r")
5932         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5933   "TARGET_64BIT"
5934   "lea{l}\t{%a1, %0|%0, %a1}"
5935   [(set_attr "type" "lea")
5936    (set_attr "mode" "SI")])
5937
5938 (define_insn "*lea_1_zext"
5939   [(set (match_operand:DI 0 "register_operand" "=r")
5940         (zero_extend:DI
5941          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5942   "TARGET_64BIT"
5943   "lea{l}\t{%a1, %k0|%k0, %a1}"
5944   [(set_attr "type" "lea")
5945    (set_attr "mode" "SI")])
5946
5947 (define_insn "*lea_2_rex64"
5948   [(set (match_operand:DI 0 "register_operand" "=r")
5949         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5950   "TARGET_64BIT"
5951   "lea{q}\t{%a1, %0|%0, %a1}"
5952   [(set_attr "type" "lea")
5953    (set_attr "mode" "DI")])
5954
5955 ;; The lea patterns for non-Pmodes needs to be matched by several
5956 ;; insns converted to real lea by splitters.
5957
5958 (define_insn_and_split "*lea_general_1"
5959   [(set (match_operand 0 "register_operand" "=r")
5960         (plus (plus (match_operand 1 "index_register_operand" "l")
5961                     (match_operand 2 "register_operand" "r"))
5962               (match_operand 3 "immediate_operand" "i")))]
5963   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5964     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5965    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5966    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5967    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5968    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5969        || GET_MODE (operands[3]) == VOIDmode)"
5970   "#"
5971   "&& reload_completed"
5972   [(const_int 0)]
5973 {
5974   rtx pat;
5975   operands[0] = gen_lowpart (SImode, operands[0]);
5976   operands[1] = gen_lowpart (Pmode, operands[1]);
5977   operands[2] = gen_lowpart (Pmode, operands[2]);
5978   operands[3] = gen_lowpart (Pmode, operands[3]);
5979   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5980                       operands[3]);
5981   if (Pmode != SImode)
5982     pat = gen_rtx_SUBREG (SImode, pat, 0);
5983   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5984   DONE;
5985 }
5986   [(set_attr "type" "lea")
5987    (set_attr "mode" "SI")])
5988
5989 (define_insn_and_split "*lea_general_1_zext"
5990   [(set (match_operand:DI 0 "register_operand" "=r")
5991         (zero_extend:DI
5992           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5993                             (match_operand:SI 2 "register_operand" "r"))
5994                    (match_operand:SI 3 "immediate_operand" "i"))))]
5995   "TARGET_64BIT"
5996   "#"
5997   "&& reload_completed"
5998   [(set (match_dup 0)
5999         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6000                                                      (match_dup 2))
6001                                             (match_dup 3)) 0)))]
6002 {
6003   operands[1] = gen_lowpart (Pmode, operands[1]);
6004   operands[2] = gen_lowpart (Pmode, operands[2]);
6005   operands[3] = gen_lowpart (Pmode, operands[3]);
6006 }
6007   [(set_attr "type" "lea")
6008    (set_attr "mode" "SI")])
6009
6010 (define_insn_and_split "*lea_general_2"
6011   [(set (match_operand 0 "register_operand" "=r")
6012         (plus (mult (match_operand 1 "index_register_operand" "l")
6013                     (match_operand 2 "const248_operand" "i"))
6014               (match_operand 3 "nonmemory_operand" "ri")))]
6015   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6016     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6017    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6018    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6019    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6020        || GET_MODE (operands[3]) == VOIDmode)"
6021   "#"
6022   "&& reload_completed"
6023   [(const_int 0)]
6024 {
6025   rtx pat;
6026   operands[0] = gen_lowpart (SImode, operands[0]);
6027   operands[1] = gen_lowpart (Pmode, operands[1]);
6028   operands[3] = gen_lowpart (Pmode, operands[3]);
6029   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6030                       operands[3]);
6031   if (Pmode != SImode)
6032     pat = gen_rtx_SUBREG (SImode, pat, 0);
6033   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6034   DONE;
6035 }
6036   [(set_attr "type" "lea")
6037    (set_attr "mode" "SI")])
6038
6039 (define_insn_and_split "*lea_general_2_zext"
6040   [(set (match_operand:DI 0 "register_operand" "=r")
6041         (zero_extend:DI
6042           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6043                             (match_operand:SI 2 "const248_operand" "n"))
6044                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6045   "TARGET_64BIT"
6046   "#"
6047   "&& reload_completed"
6048   [(set (match_dup 0)
6049         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6050                                                      (match_dup 2))
6051                                             (match_dup 3)) 0)))]
6052 {
6053   operands[1] = gen_lowpart (Pmode, operands[1]);
6054   operands[3] = gen_lowpart (Pmode, operands[3]);
6055 }
6056   [(set_attr "type" "lea")
6057    (set_attr "mode" "SI")])
6058
6059 (define_insn_and_split "*lea_general_3"
6060   [(set (match_operand 0 "register_operand" "=r")
6061         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6062                           (match_operand 2 "const248_operand" "i"))
6063                     (match_operand 3 "register_operand" "r"))
6064               (match_operand 4 "immediate_operand" "i")))]
6065   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6066     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6067    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6068    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6069    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6070   "#"
6071   "&& reload_completed"
6072   [(const_int 0)]
6073 {
6074   rtx pat;
6075   operands[0] = gen_lowpart (SImode, operands[0]);
6076   operands[1] = gen_lowpart (Pmode, operands[1]);
6077   operands[3] = gen_lowpart (Pmode, operands[3]);
6078   operands[4] = gen_lowpart (Pmode, operands[4]);
6079   pat = gen_rtx_PLUS (Pmode,
6080                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6081                                                          operands[2]),
6082                                     operands[3]),
6083                       operands[4]);
6084   if (Pmode != SImode)
6085     pat = gen_rtx_SUBREG (SImode, pat, 0);
6086   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6087   DONE;
6088 }
6089   [(set_attr "type" "lea")
6090    (set_attr "mode" "SI")])
6091
6092 (define_insn_and_split "*lea_general_3_zext"
6093   [(set (match_operand:DI 0 "register_operand" "=r")
6094         (zero_extend:DI
6095           (plus:SI (plus:SI (mult:SI
6096                               (match_operand:SI 1 "index_register_operand" "l")
6097                               (match_operand:SI 2 "const248_operand" "n"))
6098                             (match_operand:SI 3 "register_operand" "r"))
6099                    (match_operand:SI 4 "immediate_operand" "i"))))]
6100   "TARGET_64BIT"
6101   "#"
6102   "&& reload_completed"
6103   [(set (match_dup 0)
6104         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6105                                                               (match_dup 2))
6106                                                      (match_dup 3))
6107                                             (match_dup 4)) 0)))]
6108 {
6109   operands[1] = gen_lowpart (Pmode, operands[1]);
6110   operands[3] = gen_lowpart (Pmode, operands[3]);
6111   operands[4] = gen_lowpart (Pmode, operands[4]);
6112 }
6113   [(set_attr "type" "lea")
6114    (set_attr "mode" "SI")])
6115
6116 (define_insn "*adddi_1_rex64"
6117   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6118         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6119                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6120    (clobber (reg:CC FLAGS_REG))]
6121   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6122 {
6123   switch (get_attr_type (insn))
6124     {
6125     case TYPE_LEA:
6126       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6127       return "lea{q}\t{%a2, %0|%0, %a2}";
6128
6129     case TYPE_INCDEC:
6130       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6131       if (operands[2] == const1_rtx)
6132         return "inc{q}\t%0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return "dec{q}\t%0";
6137         }
6138
6139     default:
6140       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6141
6142       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6143          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6144       if (CONST_INT_P (operands[2])
6145           /* Avoid overflows.  */
6146           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6147           && (INTVAL (operands[2]) == 128
6148               || (INTVAL (operands[2]) < 0
6149                   && INTVAL (operands[2]) != -128)))
6150         {
6151           operands[2] = GEN_INT (-INTVAL (operands[2]));
6152           return "sub{q}\t{%2, %0|%0, %2}";
6153         }
6154       return "add{q}\t{%2, %0|%0, %2}";
6155     }
6156 }
6157   [(set (attr "type")
6158      (cond [(eq_attr "alternative" "2")
6159               (const_string "lea")
6160             ; Current assemblers are broken and do not allow @GOTOFF in
6161             ; ought but a memory context.
6162             (match_operand:DI 2 "pic_symbolic_operand" "")
6163               (const_string "lea")
6164             (match_operand:DI 2 "incdec_operand" "")
6165               (const_string "incdec")
6166            ]
6167            (const_string "alu")))
6168    (set_attr "mode" "DI")])
6169
6170 ;; Convert lea to the lea pattern to avoid flags dependency.
6171 (define_split
6172   [(set (match_operand:DI 0 "register_operand" "")
6173         (plus:DI (match_operand:DI 1 "register_operand" "")
6174                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6175    (clobber (reg:CC FLAGS_REG))]
6176   "TARGET_64BIT && reload_completed
6177    && true_regnum (operands[0]) != true_regnum (operands[1])"
6178   [(set (match_dup 0)
6179         (plus:DI (match_dup 1)
6180                  (match_dup 2)))]
6181   "")
6182
6183 (define_insn "*adddi_2_rex64"
6184   [(set (reg FLAGS_REG)
6185         (compare
6186           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6187                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6188           (const_int 0)))
6189    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6190         (plus:DI (match_dup 1) (match_dup 2)))]
6191   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6192    && ix86_binary_operator_ok (PLUS, DImode, operands)
6193    /* Current assemblers are broken and do not allow @GOTOFF in
6194       ought but a memory context.  */
6195    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6196 {
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_INCDEC:
6200       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6201       if (operands[2] == const1_rtx)
6202         return "inc{q}\t%0";
6203       else
6204         {
6205           gcc_assert (operands[2] == constm1_rtx);
6206           return "dec{q}\t%0";
6207         }
6208
6209     default:
6210       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211       /* ???? We ought to handle there the 32bit case too
6212          - do we need new constraint?  */
6213       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6214          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6215       if (CONST_INT_P (operands[2])
6216           /* Avoid overflows.  */
6217           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6218           && (INTVAL (operands[2]) == 128
6219               || (INTVAL (operands[2]) < 0
6220                   && INTVAL (operands[2]) != -128)))
6221         {
6222           operands[2] = GEN_INT (-INTVAL (operands[2]));
6223           return "sub{q}\t{%2, %0|%0, %2}";
6224         }
6225       return "add{q}\t{%2, %0|%0, %2}";
6226     }
6227 }
6228   [(set (attr "type")
6229      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6230         (const_string "incdec")
6231         (const_string "alu")))
6232    (set_attr "mode" "DI")])
6233
6234 (define_insn "*adddi_3_rex64"
6235   [(set (reg FLAGS_REG)
6236         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6237                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6238    (clobber (match_scratch:DI 0 "=r"))]
6239   "TARGET_64BIT
6240    && ix86_match_ccmode (insn, CCZmode)
6241    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6242    /* Current assemblers are broken and do not allow @GOTOFF in
6243       ought but a memory context.  */
6244    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6245 {
6246   switch (get_attr_type (insn))
6247     {
6248     case TYPE_INCDEC:
6249       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6250       if (operands[2] == const1_rtx)
6251         return "inc{q}\t%0";
6252       else
6253         {
6254           gcc_assert (operands[2] == constm1_rtx);
6255           return "dec{q}\t%0";
6256         }
6257
6258     default:
6259       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6260       /* ???? We ought to handle there the 32bit case too
6261          - do we need new constraint?  */
6262       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6263          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6264       if (CONST_INT_P (operands[2])
6265           /* Avoid overflows.  */
6266           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6267           && (INTVAL (operands[2]) == 128
6268               || (INTVAL (operands[2]) < 0
6269                   && INTVAL (operands[2]) != -128)))
6270         {
6271           operands[2] = GEN_INT (-INTVAL (operands[2]));
6272           return "sub{q}\t{%2, %0|%0, %2}";
6273         }
6274       return "add{q}\t{%2, %0|%0, %2}";
6275     }
6276 }
6277   [(set (attr "type")
6278      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6279         (const_string "incdec")
6280         (const_string "alu")))
6281    (set_attr "mode" "DI")])
6282
6283 ; For comparisons against 1, -1 and 128, we may generate better code
6284 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6285 ; is matched then.  We can't accept general immediate, because for
6286 ; case of overflows,  the result is messed up.
6287 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6288 ; when negated.
6289 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6290 ; only for comparisons not depending on it.
6291 (define_insn "*adddi_4_rex64"
6292   [(set (reg FLAGS_REG)
6293         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6294                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6295    (clobber (match_scratch:DI 0 "=rm"))]
6296   "TARGET_64BIT
6297    &&  ix86_match_ccmode (insn, CCGCmode)"
6298 {
6299   switch (get_attr_type (insn))
6300     {
6301     case TYPE_INCDEC:
6302       if (operands[2] == constm1_rtx)
6303         return "inc{q}\t%0";
6304       else
6305         {
6306           gcc_assert (operands[2] == const1_rtx);
6307           return "dec{q}\t%0";
6308         }
6309
6310     default:
6311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6312       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6313          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6314       if ((INTVAL (operands[2]) == -128
6315            || (INTVAL (operands[2]) > 0
6316                && INTVAL (operands[2]) != 128))
6317           /* Avoid overflows.  */
6318           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6319         return "sub{q}\t{%2, %0|%0, %2}";
6320       operands[2] = GEN_INT (-INTVAL (operands[2]));
6321       return "add{q}\t{%2, %0|%0, %2}";
6322     }
6323 }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "DI")])
6329
6330 (define_insn "*adddi_5_rex64"
6331   [(set (reg FLAGS_REG)
6332         (compare
6333           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6334                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6335           (const_int 0)))
6336    (clobber (match_scratch:DI 0 "=r"))]
6337   "TARGET_64BIT
6338    && ix86_match_ccmode (insn, CCGOCmode)
6339    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6340    /* Current assemblers are broken and do not allow @GOTOFF in
6341       ought but a memory context.  */
6342    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6343 {
6344   switch (get_attr_type (insn))
6345     {
6346     case TYPE_INCDEC:
6347       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6348       if (operands[2] == const1_rtx)
6349         return "inc{q}\t%0";
6350       else
6351         {
6352           gcc_assert (operands[2] == constm1_rtx);
6353           return "dec{q}\t%0";
6354         }
6355
6356     default:
6357       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6358       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6359          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6360       if (CONST_INT_P (operands[2])
6361           /* Avoid overflows.  */
6362           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6363           && (INTVAL (operands[2]) == 128
6364               || (INTVAL (operands[2]) < 0
6365                   && INTVAL (operands[2]) != -128)))
6366         {
6367           operands[2] = GEN_INT (-INTVAL (operands[2]));
6368           return "sub{q}\t{%2, %0|%0, %2}";
6369         }
6370       return "add{q}\t{%2, %0|%0, %2}";
6371     }
6372 }
6373   [(set (attr "type")
6374      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6375         (const_string "incdec")
6376         (const_string "alu")))
6377    (set_attr "mode" "DI")])
6378
6379
6380 (define_insn "*addsi_1"
6381   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6382         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6383                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6384    (clobber (reg:CC FLAGS_REG))]
6385   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6386 {
6387   switch (get_attr_type (insn))
6388     {
6389     case TYPE_LEA:
6390       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6391       return "lea{l}\t{%a2, %0|%0, %a2}";
6392
6393     case TYPE_INCDEC:
6394       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6395       if (operands[2] == const1_rtx)
6396         return "inc{l}\t%0";
6397       else
6398         {
6399           gcc_assert (operands[2] == constm1_rtx);
6400           return "dec{l}\t%0";
6401         }
6402
6403     default:
6404       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6405
6406       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6407          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6408       if (CONST_INT_P (operands[2])
6409           && (INTVAL (operands[2]) == 128
6410               || (INTVAL (operands[2]) < 0
6411                   && INTVAL (operands[2]) != -128)))
6412         {
6413           operands[2] = GEN_INT (-INTVAL (operands[2]));
6414           return "sub{l}\t{%2, %0|%0, %2}";
6415         }
6416       return "add{l}\t{%2, %0|%0, %2}";
6417     }
6418 }
6419   [(set (attr "type")
6420      (cond [(eq_attr "alternative" "2")
6421               (const_string "lea")
6422             ; Current assemblers are broken and do not allow @GOTOFF in
6423             ; ought but a memory context.
6424             (match_operand:SI 2 "pic_symbolic_operand" "")
6425               (const_string "lea")
6426             (match_operand:SI 2 "incdec_operand" "")
6427               (const_string "incdec")
6428            ]
6429            (const_string "alu")))
6430    (set_attr "mode" "SI")])
6431
6432 ;; Convert lea to the lea pattern to avoid flags dependency.
6433 (define_split
6434   [(set (match_operand 0 "register_operand" "")
6435         (plus (match_operand 1 "register_operand" "")
6436               (match_operand 2 "nonmemory_operand" "")))
6437    (clobber (reg:CC FLAGS_REG))]
6438   "reload_completed
6439    && true_regnum (operands[0]) != true_regnum (operands[1])"
6440   [(const_int 0)]
6441 {
6442   rtx pat;
6443   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6444      may confuse gen_lowpart.  */
6445   if (GET_MODE (operands[0]) != Pmode)
6446     {
6447       operands[1] = gen_lowpart (Pmode, operands[1]);
6448       operands[2] = gen_lowpart (Pmode, operands[2]);
6449     }
6450   operands[0] = gen_lowpart (SImode, operands[0]);
6451   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6452   if (Pmode != SImode)
6453     pat = gen_rtx_SUBREG (SImode, pat, 0);
6454   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6455   DONE;
6456 })
6457
6458 ;; It may seem that nonimmediate operand is proper one for operand 1.
6459 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6460 ;; we take care in ix86_binary_operator_ok to not allow two memory
6461 ;; operands so proper swapping will be done in reload.  This allow
6462 ;; patterns constructed from addsi_1 to match.
6463 (define_insn "addsi_1_zext"
6464   [(set (match_operand:DI 0 "register_operand" "=r,r")
6465         (zero_extend:DI
6466           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6467                    (match_operand:SI 2 "general_operand" "g,li"))))
6468    (clobber (reg:CC FLAGS_REG))]
6469   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6470 {
6471   switch (get_attr_type (insn))
6472     {
6473     case TYPE_LEA:
6474       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6475       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6476
6477     case TYPE_INCDEC:
6478       if (operands[2] == const1_rtx)
6479         return "inc{l}\t%k0";
6480       else
6481         {
6482           gcc_assert (operands[2] == constm1_rtx);
6483           return "dec{l}\t%k0";
6484         }
6485
6486     default:
6487       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6488          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6489       if (CONST_INT_P (operands[2])
6490           && (INTVAL (operands[2]) == 128
6491               || (INTVAL (operands[2]) < 0
6492                   && INTVAL (operands[2]) != -128)))
6493         {
6494           operands[2] = GEN_INT (-INTVAL (operands[2]));
6495           return "sub{l}\t{%2, %k0|%k0, %2}";
6496         }
6497       return "add{l}\t{%2, %k0|%k0, %2}";
6498     }
6499 }
6500   [(set (attr "type")
6501      (cond [(eq_attr "alternative" "1")
6502               (const_string "lea")
6503             ; Current assemblers are broken and do not allow @GOTOFF in
6504             ; ought but a memory context.
6505             (match_operand:SI 2 "pic_symbolic_operand" "")
6506               (const_string "lea")
6507             (match_operand:SI 2 "incdec_operand" "")
6508               (const_string "incdec")
6509            ]
6510            (const_string "alu")))
6511    (set_attr "mode" "SI")])
6512
6513 ;; Convert lea to the lea pattern to avoid flags dependency.
6514 (define_split
6515   [(set (match_operand:DI 0 "register_operand" "")
6516         (zero_extend:DI
6517           (plus:SI (match_operand:SI 1 "register_operand" "")
6518                    (match_operand:SI 2 "nonmemory_operand" ""))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "TARGET_64BIT && reload_completed
6521    && true_regnum (operands[0]) != true_regnum (operands[1])"
6522   [(set (match_dup 0)
6523         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6524 {
6525   operands[1] = gen_lowpart (Pmode, operands[1]);
6526   operands[2] = gen_lowpart (Pmode, operands[2]);
6527 })
6528
6529 (define_insn "*addsi_2"
6530   [(set (reg FLAGS_REG)
6531         (compare
6532           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6533                    (match_operand:SI 2 "general_operand" "g,ri"))
6534           (const_int 0)))
6535    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6536         (plus:SI (match_dup 1) (match_dup 2)))]
6537   "ix86_match_ccmode (insn, CCGOCmode)
6538    && ix86_binary_operator_ok (PLUS, SImode, operands)
6539    /* Current assemblers are broken and do not allow @GOTOFF in
6540       ought but a memory context.  */
6541    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6542 {
6543   switch (get_attr_type (insn))
6544     {
6545     case TYPE_INCDEC:
6546       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6547       if (operands[2] == const1_rtx)
6548         return "inc{l}\t%0";
6549       else
6550         {
6551           gcc_assert (operands[2] == constm1_rtx);
6552           return "dec{l}\t%0";
6553         }
6554
6555     default:
6556       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6557       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6558          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6559       if (CONST_INT_P (operands[2])
6560           && (INTVAL (operands[2]) == 128
6561               || (INTVAL (operands[2]) < 0
6562                   && INTVAL (operands[2]) != -128)))
6563         {
6564           operands[2] = GEN_INT (-INTVAL (operands[2]));
6565           return "sub{l}\t{%2, %0|%0, %2}";
6566         }
6567       return "add{l}\t{%2, %0|%0, %2}";
6568     }
6569 }
6570   [(set (attr "type")
6571      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6572         (const_string "incdec")
6573         (const_string "alu")))
6574    (set_attr "mode" "SI")])
6575
6576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6577 (define_insn "*addsi_2_zext"
6578   [(set (reg FLAGS_REG)
6579         (compare
6580           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6581                    (match_operand:SI 2 "general_operand" "g"))
6582           (const_int 0)))
6583    (set (match_operand:DI 0 "register_operand" "=r")
6584         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6585   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6586    && ix86_binary_operator_ok (PLUS, SImode, operands)
6587    /* Current assemblers are broken and do not allow @GOTOFF in
6588       ought but a memory context.  */
6589    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6590 {
6591   switch (get_attr_type (insn))
6592     {
6593     case TYPE_INCDEC:
6594       if (operands[2] == const1_rtx)
6595         return "inc{l}\t%k0";
6596       else
6597         {
6598           gcc_assert (operands[2] == constm1_rtx);
6599           return "dec{l}\t%k0";
6600         }
6601
6602     default:
6603       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6604          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6605       if (CONST_INT_P (operands[2])
6606           && (INTVAL (operands[2]) == 128
6607               || (INTVAL (operands[2]) < 0
6608                   && INTVAL (operands[2]) != -128)))
6609         {
6610           operands[2] = GEN_INT (-INTVAL (operands[2]));
6611           return "sub{l}\t{%2, %k0|%k0, %2}";
6612         }
6613       return "add{l}\t{%2, %k0|%k0, %2}";
6614     }
6615 }
6616   [(set (attr "type")
6617      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6618         (const_string "incdec")
6619         (const_string "alu")))
6620    (set_attr "mode" "SI")])
6621
6622 (define_insn "*addsi_3"
6623   [(set (reg FLAGS_REG)
6624         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6625                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6626    (clobber (match_scratch:SI 0 "=r"))]
6627   "ix86_match_ccmode (insn, CCZmode)
6628    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6629    /* Current assemblers are broken and do not allow @GOTOFF in
6630       ought but a memory context.  */
6631    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6632 {
6633   switch (get_attr_type (insn))
6634     {
6635     case TYPE_INCDEC:
6636       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637       if (operands[2] == const1_rtx)
6638         return "inc{l}\t%0";
6639       else
6640         {
6641           gcc_assert (operands[2] == constm1_rtx);
6642           return "dec{l}\t%0";
6643         }
6644
6645     default:
6646       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6647       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6648          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6649       if (CONST_INT_P (operands[2])
6650           && (INTVAL (operands[2]) == 128
6651               || (INTVAL (operands[2]) < 0
6652                   && INTVAL (operands[2]) != -128)))
6653         {
6654           operands[2] = GEN_INT (-INTVAL (operands[2]));
6655           return "sub{l}\t{%2, %0|%0, %2}";
6656         }
6657       return "add{l}\t{%2, %0|%0, %2}";
6658     }
6659 }
6660   [(set (attr "type")
6661      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6662         (const_string "incdec")
6663         (const_string "alu")))
6664    (set_attr "mode" "SI")])
6665
6666 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6667 (define_insn "*addsi_3_zext"
6668   [(set (reg FLAGS_REG)
6669         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6670                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6671    (set (match_operand:DI 0 "register_operand" "=r")
6672         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6673   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6674    && ix86_binary_operator_ok (PLUS, SImode, operands)
6675    /* Current assemblers are broken and do not allow @GOTOFF in
6676       ought but a memory context.  */
6677    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6678 {
6679   switch (get_attr_type (insn))
6680     {
6681     case TYPE_INCDEC:
6682       if (operands[2] == const1_rtx)
6683         return "inc{l}\t%k0";
6684       else
6685         {
6686           gcc_assert (operands[2] == constm1_rtx);
6687           return "dec{l}\t%k0";
6688         }
6689
6690     default:
6691       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6692          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6693       if (CONST_INT_P (operands[2])
6694           && (INTVAL (operands[2]) == 128
6695               || (INTVAL (operands[2]) < 0
6696                   && INTVAL (operands[2]) != -128)))
6697         {
6698           operands[2] = GEN_INT (-INTVAL (operands[2]));
6699           return "sub{l}\t{%2, %k0|%k0, %2}";
6700         }
6701       return "add{l}\t{%2, %k0|%k0, %2}";
6702     }
6703 }
6704   [(set (attr "type")
6705      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6706         (const_string "incdec")
6707         (const_string "alu")))
6708    (set_attr "mode" "SI")])
6709
6710 ; For comparisons against 1, -1 and 128, we may generate better code
6711 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6712 ; is matched then.  We can't accept general immediate, because for
6713 ; case of overflows,  the result is messed up.
6714 ; This pattern also don't hold of 0x80000000, since the value overflows
6715 ; when negated.
6716 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6717 ; only for comparisons not depending on it.
6718 (define_insn "*addsi_4"
6719   [(set (reg FLAGS_REG)
6720         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6721                  (match_operand:SI 2 "const_int_operand" "n")))
6722    (clobber (match_scratch:SI 0 "=rm"))]
6723   "ix86_match_ccmode (insn, CCGCmode)
6724    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6725 {
6726   switch (get_attr_type (insn))
6727     {
6728     case TYPE_INCDEC:
6729       if (operands[2] == constm1_rtx)
6730         return "inc{l}\t%0";
6731       else
6732         {
6733           gcc_assert (operands[2] == const1_rtx);
6734           return "dec{l}\t%0";
6735         }
6736
6737     default:
6738       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6739       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6740          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6741       if ((INTVAL (operands[2]) == -128
6742            || (INTVAL (operands[2]) > 0
6743                && INTVAL (operands[2]) != 128)))
6744         return "sub{l}\t{%2, %0|%0, %2}";
6745       operands[2] = GEN_INT (-INTVAL (operands[2]));
6746       return "add{l}\t{%2, %0|%0, %2}";
6747     }
6748 }
6749   [(set (attr "type")
6750      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6751         (const_string "incdec")
6752         (const_string "alu")))
6753    (set_attr "mode" "SI")])
6754
6755 (define_insn "*addsi_5"
6756   [(set (reg FLAGS_REG)
6757         (compare
6758           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6759                    (match_operand:SI 2 "general_operand" "g"))
6760           (const_int 0)))
6761    (clobber (match_scratch:SI 0 "=r"))]
6762   "ix86_match_ccmode (insn, CCGOCmode)
6763    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6764    /* Current assemblers are broken and do not allow @GOTOFF in
6765       ought but a memory context.  */
6766    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6767 {
6768   switch (get_attr_type (insn))
6769     {
6770     case TYPE_INCDEC:
6771       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772       if (operands[2] == const1_rtx)
6773         return "inc{l}\t%0";
6774       else
6775         {
6776           gcc_assert (operands[2] == constm1_rtx);
6777           return "dec{l}\t%0";
6778         }
6779
6780     default:
6781       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6782       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6783          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6784       if (CONST_INT_P (operands[2])
6785           && (INTVAL (operands[2]) == 128
6786               || (INTVAL (operands[2]) < 0
6787                   && INTVAL (operands[2]) != -128)))
6788         {
6789           operands[2] = GEN_INT (-INTVAL (operands[2]));
6790           return "sub{l}\t{%2, %0|%0, %2}";
6791         }
6792       return "add{l}\t{%2, %0|%0, %2}";
6793     }
6794 }
6795   [(set (attr "type")
6796      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6797         (const_string "incdec")
6798         (const_string "alu")))
6799    (set_attr "mode" "SI")])
6800
6801 (define_expand "addhi3"
6802   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6803         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6804                  (match_operand:HI 2 "general_operand" "")))]
6805   "TARGET_HIMODE_MATH"
6806   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6807
6808 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6809 ;; type optimizations enabled by define-splits.  This is not important
6810 ;; for PII, and in fact harmful because of partial register stalls.
6811
6812 (define_insn "*addhi_1_lea"
6813   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6814         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6815                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6816    (clobber (reg:CC FLAGS_REG))]
6817   "!TARGET_PARTIAL_REG_STALL
6818    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6819 {
6820   switch (get_attr_type (insn))
6821     {
6822     case TYPE_LEA:
6823       return "#";
6824     case TYPE_INCDEC:
6825       if (operands[2] == const1_rtx)
6826         return "inc{w}\t%0";
6827       else
6828         {
6829           gcc_assert (operands[2] == constm1_rtx);
6830           return "dec{w}\t%0";
6831         }
6832
6833     default:
6834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6835          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6836       if (CONST_INT_P (operands[2])
6837           && (INTVAL (operands[2]) == 128
6838               || (INTVAL (operands[2]) < 0
6839                   && INTVAL (operands[2]) != -128)))
6840         {
6841           operands[2] = GEN_INT (-INTVAL (operands[2]));
6842           return "sub{w}\t{%2, %0|%0, %2}";
6843         }
6844       return "add{w}\t{%2, %0|%0, %2}";
6845     }
6846 }
6847   [(set (attr "type")
6848      (if_then_else (eq_attr "alternative" "2")
6849         (const_string "lea")
6850         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6851            (const_string "incdec")
6852            (const_string "alu"))))
6853    (set_attr "mode" "HI,HI,SI")])
6854
6855 (define_insn "*addhi_1"
6856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6857         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6858                  (match_operand:HI 2 "general_operand" "rn,rm")))
6859    (clobber (reg:CC FLAGS_REG))]
6860   "TARGET_PARTIAL_REG_STALL
6861    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6862 {
6863   switch (get_attr_type (insn))
6864     {
6865     case TYPE_INCDEC:
6866       if (operands[2] == const1_rtx)
6867         return "inc{w}\t%0";
6868       else
6869         {
6870           gcc_assert (operands[2] == constm1_rtx);
6871           return "dec{w}\t%0";
6872         }
6873
6874     default:
6875       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6876          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6877       if (CONST_INT_P (operands[2])
6878           && (INTVAL (operands[2]) == 128
6879               || (INTVAL (operands[2]) < 0
6880                   && INTVAL (operands[2]) != -128)))
6881         {
6882           operands[2] = GEN_INT (-INTVAL (operands[2]));
6883           return "sub{w}\t{%2, %0|%0, %2}";
6884         }
6885       return "add{w}\t{%2, %0|%0, %2}";
6886     }
6887 }
6888   [(set (attr "type")
6889      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6890         (const_string "incdec")
6891         (const_string "alu")))
6892    (set_attr "mode" "HI")])
6893
6894 (define_insn "*addhi_2"
6895   [(set (reg FLAGS_REG)
6896         (compare
6897           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6898                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6899           (const_int 0)))
6900    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6901         (plus:HI (match_dup 1) (match_dup 2)))]
6902   "ix86_match_ccmode (insn, CCGOCmode)
6903    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6904 {
6905   switch (get_attr_type (insn))
6906     {
6907     case TYPE_INCDEC:
6908       if (operands[2] == const1_rtx)
6909         return "inc{w}\t%0";
6910       else
6911         {
6912           gcc_assert (operands[2] == constm1_rtx);
6913           return "dec{w}\t%0";
6914         }
6915
6916     default:
6917       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6918          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6919       if (CONST_INT_P (operands[2])
6920           && (INTVAL (operands[2]) == 128
6921               || (INTVAL (operands[2]) < 0
6922                   && INTVAL (operands[2]) != -128)))
6923         {
6924           operands[2] = GEN_INT (-INTVAL (operands[2]));
6925           return "sub{w}\t{%2, %0|%0, %2}";
6926         }
6927       return "add{w}\t{%2, %0|%0, %2}";
6928     }
6929 }
6930   [(set (attr "type")
6931      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6932         (const_string "incdec")
6933         (const_string "alu")))
6934    (set_attr "mode" "HI")])
6935
6936 (define_insn "*addhi_3"
6937   [(set (reg FLAGS_REG)
6938         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6939                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6940    (clobber (match_scratch:HI 0 "=r"))]
6941   "ix86_match_ccmode (insn, CCZmode)
6942    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6943 {
6944   switch (get_attr_type (insn))
6945     {
6946     case TYPE_INCDEC:
6947       if (operands[2] == const1_rtx)
6948         return "inc{w}\t%0";
6949       else
6950         {
6951           gcc_assert (operands[2] == constm1_rtx);
6952           return "dec{w}\t%0";
6953         }
6954
6955     default:
6956       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6957          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6958       if (CONST_INT_P (operands[2])
6959           && (INTVAL (operands[2]) == 128
6960               || (INTVAL (operands[2]) < 0
6961                   && INTVAL (operands[2]) != -128)))
6962         {
6963           operands[2] = GEN_INT (-INTVAL (operands[2]));
6964           return "sub{w}\t{%2, %0|%0, %2}";
6965         }
6966       return "add{w}\t{%2, %0|%0, %2}";
6967     }
6968 }
6969   [(set (attr "type")
6970      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6971         (const_string "incdec")
6972         (const_string "alu")))
6973    (set_attr "mode" "HI")])
6974
6975 ; See comments above addsi_4 for details.
6976 (define_insn "*addhi_4"
6977   [(set (reg FLAGS_REG)
6978         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6979                  (match_operand:HI 2 "const_int_operand" "n")))
6980    (clobber (match_scratch:HI 0 "=rm"))]
6981   "ix86_match_ccmode (insn, CCGCmode)
6982    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6983 {
6984   switch (get_attr_type (insn))
6985     {
6986     case TYPE_INCDEC:
6987       if (operands[2] == constm1_rtx)
6988         return "inc{w}\t%0";
6989       else
6990         {
6991           gcc_assert (operands[2] == const1_rtx);
6992           return "dec{w}\t%0";
6993         }
6994
6995     default:
6996       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6997       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6998          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6999       if ((INTVAL (operands[2]) == -128
7000            || (INTVAL (operands[2]) > 0
7001                && INTVAL (operands[2]) != 128)))
7002         return "sub{w}\t{%2, %0|%0, %2}";
7003       operands[2] = GEN_INT (-INTVAL (operands[2]));
7004       return "add{w}\t{%2, %0|%0, %2}";
7005     }
7006 }
7007   [(set (attr "type")
7008      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7009         (const_string "incdec")
7010         (const_string "alu")))
7011    (set_attr "mode" "SI")])
7012
7013
7014 (define_insn "*addhi_5"
7015   [(set (reg FLAGS_REG)
7016         (compare
7017           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7018                    (match_operand:HI 2 "general_operand" "rmn"))
7019           (const_int 0)))
7020    (clobber (match_scratch:HI 0 "=r"))]
7021   "ix86_match_ccmode (insn, CCGOCmode)
7022    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7023 {
7024   switch (get_attr_type (insn))
7025     {
7026     case TYPE_INCDEC:
7027       if (operands[2] == const1_rtx)
7028         return "inc{w}\t%0";
7029       else
7030         {
7031           gcc_assert (operands[2] == constm1_rtx);
7032           return "dec{w}\t%0";
7033         }
7034
7035     default:
7036       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7037          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7038       if (CONST_INT_P (operands[2])
7039           && (INTVAL (operands[2]) == 128
7040               || (INTVAL (operands[2]) < 0
7041                   && INTVAL (operands[2]) != -128)))
7042         {
7043           operands[2] = GEN_INT (-INTVAL (operands[2]));
7044           return "sub{w}\t{%2, %0|%0, %2}";
7045         }
7046       return "add{w}\t{%2, %0|%0, %2}";
7047     }
7048 }
7049   [(set (attr "type")
7050      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7051         (const_string "incdec")
7052         (const_string "alu")))
7053    (set_attr "mode" "HI")])
7054
7055 (define_expand "addqi3"
7056   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058                  (match_operand:QI 2 "general_operand" "")))]
7059   "TARGET_QIMODE_MATH"
7060   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7061
7062 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7063 (define_insn "*addqi_1_lea"
7064   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7065         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7066                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7067    (clobber (reg:CC FLAGS_REG))]
7068   "!TARGET_PARTIAL_REG_STALL
7069    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7070 {
7071   int widen = (which_alternative == 2);
7072   switch (get_attr_type (insn))
7073     {
7074     case TYPE_LEA:
7075       return "#";
7076     case TYPE_INCDEC:
7077       if (operands[2] == const1_rtx)
7078         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7079       else
7080         {
7081           gcc_assert (operands[2] == constm1_rtx);
7082           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7083         }
7084
7085     default:
7086       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7087          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7088       if (CONST_INT_P (operands[2])
7089           && (INTVAL (operands[2]) == 128
7090               || (INTVAL (operands[2]) < 0
7091                   && INTVAL (operands[2]) != -128)))
7092         {
7093           operands[2] = GEN_INT (-INTVAL (operands[2]));
7094           if (widen)
7095             return "sub{l}\t{%2, %k0|%k0, %2}";
7096           else
7097             return "sub{b}\t{%2, %0|%0, %2}";
7098         }
7099       if (widen)
7100         return "add{l}\t{%k2, %k0|%k0, %k2}";
7101       else
7102         return "add{b}\t{%2, %0|%0, %2}";
7103     }
7104 }
7105   [(set (attr "type")
7106      (if_then_else (eq_attr "alternative" "3")
7107         (const_string "lea")
7108         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7109            (const_string "incdec")
7110            (const_string "alu"))))
7111    (set_attr "mode" "QI,QI,SI,SI")])
7112
7113 (define_insn "*addqi_1"
7114   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7115         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7116                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7117    (clobber (reg:CC FLAGS_REG))]
7118   "TARGET_PARTIAL_REG_STALL
7119    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7120 {
7121   int widen = (which_alternative == 2);
7122   switch (get_attr_type (insn))
7123     {
7124     case TYPE_INCDEC:
7125       if (operands[2] == const1_rtx)
7126         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7127       else
7128         {
7129           gcc_assert (operands[2] == constm1_rtx);
7130           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7131         }
7132
7133     default:
7134       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7135          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7136       if (CONST_INT_P (operands[2])
7137           && (INTVAL (operands[2]) == 128
7138               || (INTVAL (operands[2]) < 0
7139                   && INTVAL (operands[2]) != -128)))
7140         {
7141           operands[2] = GEN_INT (-INTVAL (operands[2]));
7142           if (widen)
7143             return "sub{l}\t{%2, %k0|%k0, %2}";
7144           else
7145             return "sub{b}\t{%2, %0|%0, %2}";
7146         }
7147       if (widen)
7148         return "add{l}\t{%k2, %k0|%k0, %k2}";
7149       else
7150         return "add{b}\t{%2, %0|%0, %2}";
7151     }
7152 }
7153   [(set (attr "type")
7154      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7155         (const_string "incdec")
7156         (const_string "alu")))
7157    (set_attr "mode" "QI,QI,SI")])
7158
7159 (define_insn "*addqi_1_slp"
7160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7161         (plus:QI (match_dup 0)
7162                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7163    (clobber (reg:CC FLAGS_REG))]
7164   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7165    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7166 {
7167   switch (get_attr_type (insn))
7168     {
7169     case TYPE_INCDEC:
7170       if (operands[1] == const1_rtx)
7171         return "inc{b}\t%0";
7172       else
7173         {
7174           gcc_assert (operands[1] == constm1_rtx);
7175           return "dec{b}\t%0";
7176         }
7177
7178     default:
7179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7180       if (CONST_INT_P (operands[1])
7181           && INTVAL (operands[1]) < 0)
7182         {
7183           operands[1] = GEN_INT (-INTVAL (operands[1]));
7184           return "sub{b}\t{%1, %0|%0, %1}";
7185         }
7186       return "add{b}\t{%1, %0|%0, %1}";
7187     }
7188 }
7189   [(set (attr "type")
7190      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7191         (const_string "incdec")
7192         (const_string "alu1")))
7193    (set (attr "memory")
7194      (if_then_else (match_operand 1 "memory_operand" "")
7195         (const_string "load")
7196         (const_string "none")))
7197    (set_attr "mode" "QI")])
7198
7199 (define_insn "*addqi_2"
7200   [(set (reg FLAGS_REG)
7201         (compare
7202           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7203                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7204           (const_int 0)))
7205    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7206         (plus:QI (match_dup 1) (match_dup 2)))]
7207   "ix86_match_ccmode (insn, CCGOCmode)
7208    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7209 {
7210   switch (get_attr_type (insn))
7211     {
7212     case TYPE_INCDEC:
7213       if (operands[2] == const1_rtx)
7214         return "inc{b}\t%0";
7215       else
7216         {
7217           gcc_assert (operands[2] == constm1_rtx
7218                       || (CONST_INT_P (operands[2])
7219                           && INTVAL (operands[2]) == 255));
7220           return "dec{b}\t%0";
7221         }
7222
7223     default:
7224       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7225       if (CONST_INT_P (operands[2])
7226           && INTVAL (operands[2]) < 0)
7227         {
7228           operands[2] = GEN_INT (-INTVAL (operands[2]));
7229           return "sub{b}\t{%2, %0|%0, %2}";
7230         }
7231       return "add{b}\t{%2, %0|%0, %2}";
7232     }
7233 }
7234   [(set (attr "type")
7235      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7236         (const_string "incdec")
7237         (const_string "alu")))
7238    (set_attr "mode" "QI")])
7239
7240 (define_insn "*addqi_3"
7241   [(set (reg FLAGS_REG)
7242         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7243                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7244    (clobber (match_scratch:QI 0 "=q"))]
7245   "ix86_match_ccmode (insn, CCZmode)
7246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7247 {
7248   switch (get_attr_type (insn))
7249     {
7250     case TYPE_INCDEC:
7251       if (operands[2] == const1_rtx)
7252         return "inc{b}\t%0";
7253       else
7254         {
7255           gcc_assert (operands[2] == constm1_rtx
7256                       || (CONST_INT_P (operands[2])
7257                           && INTVAL (operands[2]) == 255));
7258           return "dec{b}\t%0";
7259         }
7260
7261     default:
7262       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7263       if (CONST_INT_P (operands[2])
7264           && INTVAL (operands[2]) < 0)
7265         {
7266           operands[2] = GEN_INT (-INTVAL (operands[2]));
7267           return "sub{b}\t{%2, %0|%0, %2}";
7268         }
7269       return "add{b}\t{%2, %0|%0, %2}";
7270     }
7271 }
7272   [(set (attr "type")
7273      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7274         (const_string "incdec")
7275         (const_string "alu")))
7276    (set_attr "mode" "QI")])
7277
7278 ; See comments above addsi_4 for details.
7279 (define_insn "*addqi_4"
7280   [(set (reg FLAGS_REG)
7281         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7282                  (match_operand:QI 2 "const_int_operand" "n")))
7283    (clobber (match_scratch:QI 0 "=qm"))]
7284   "ix86_match_ccmode (insn, CCGCmode)
7285    && (INTVAL (operands[2]) & 0xff) != 0x80"
7286 {
7287   switch (get_attr_type (insn))
7288     {
7289     case TYPE_INCDEC:
7290       if (operands[2] == constm1_rtx
7291           || (CONST_INT_P (operands[2])
7292               && INTVAL (operands[2]) == 255))
7293         return "inc{b}\t%0";
7294       else
7295         {
7296           gcc_assert (operands[2] == const1_rtx);
7297           return "dec{b}\t%0";
7298         }
7299
7300     default:
7301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7302       if (INTVAL (operands[2]) < 0)
7303         {
7304           operands[2] = GEN_INT (-INTVAL (operands[2]));
7305           return "add{b}\t{%2, %0|%0, %2}";
7306         }
7307       return "sub{b}\t{%2, %0|%0, %2}";
7308     }
7309 }
7310   [(set (attr "type")
7311      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7312         (const_string "incdec")
7313         (const_string "alu")))
7314    (set_attr "mode" "QI")])
7315
7316
7317 (define_insn "*addqi_5"
7318   [(set (reg FLAGS_REG)
7319         (compare
7320           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7321                    (match_operand:QI 2 "general_operand" "qmn"))
7322           (const_int 0)))
7323    (clobber (match_scratch:QI 0 "=q"))]
7324   "ix86_match_ccmode (insn, CCGOCmode)
7325    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7326 {
7327   switch (get_attr_type (insn))
7328     {
7329     case TYPE_INCDEC:
7330       if (operands[2] == const1_rtx)
7331         return "inc{b}\t%0";
7332       else
7333         {
7334           gcc_assert (operands[2] == constm1_rtx
7335                       || (CONST_INT_P (operands[2])
7336                           && INTVAL (operands[2]) == 255));
7337           return "dec{b}\t%0";
7338         }
7339
7340     default:
7341       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7342       if (CONST_INT_P (operands[2])
7343           && INTVAL (operands[2]) < 0)
7344         {
7345           operands[2] = GEN_INT (-INTVAL (operands[2]));
7346           return "sub{b}\t{%2, %0|%0, %2}";
7347         }
7348       return "add{b}\t{%2, %0|%0, %2}";
7349     }
7350 }
7351   [(set (attr "type")
7352      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7353         (const_string "incdec")
7354         (const_string "alu")))
7355    (set_attr "mode" "QI")])
7356
7357
7358 (define_insn "addqi_ext_1"
7359   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7360                          (const_int 8)
7361                          (const_int 8))
7362         (plus:SI
7363           (zero_extract:SI
7364             (match_operand 1 "ext_register_operand" "0")
7365             (const_int 8)
7366             (const_int 8))
7367           (match_operand:QI 2 "general_operand" "Qmn")))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "!TARGET_64BIT"
7370 {
7371   switch (get_attr_type (insn))
7372     {
7373     case TYPE_INCDEC:
7374       if (operands[2] == const1_rtx)
7375         return "inc{b}\t%h0";
7376       else
7377         {
7378           gcc_assert (operands[2] == constm1_rtx
7379                       || (CONST_INT_P (operands[2])
7380                           && INTVAL (operands[2]) == 255));
7381           return "dec{b}\t%h0";
7382         }
7383
7384     default:
7385       return "add{b}\t{%2, %h0|%h0, %2}";
7386     }
7387 }
7388   [(set (attr "type")
7389      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7390         (const_string "incdec")
7391         (const_string "alu")))
7392    (set_attr "mode" "QI")])
7393
7394 (define_insn "*addqi_ext_1_rex64"
7395   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7396                          (const_int 8)
7397                          (const_int 8))
7398         (plus:SI
7399           (zero_extract:SI
7400             (match_operand 1 "ext_register_operand" "0")
7401             (const_int 8)
7402             (const_int 8))
7403           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7404    (clobber (reg:CC FLAGS_REG))]
7405   "TARGET_64BIT"
7406 {
7407   switch (get_attr_type (insn))
7408     {
7409     case TYPE_INCDEC:
7410       if (operands[2] == const1_rtx)
7411         return "inc{b}\t%h0";
7412       else
7413         {
7414           gcc_assert (operands[2] == constm1_rtx
7415                       || (CONST_INT_P (operands[2])
7416                           && INTVAL (operands[2]) == 255));
7417           return "dec{b}\t%h0";
7418         }
7419
7420     default:
7421       return "add{b}\t{%2, %h0|%h0, %2}";
7422     }
7423 }
7424   [(set (attr "type")
7425      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7426         (const_string "incdec")
7427         (const_string "alu")))
7428    (set_attr "mode" "QI")])
7429
7430 (define_insn "*addqi_ext_2"
7431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7432                          (const_int 8)
7433                          (const_int 8))
7434         (plus:SI
7435           (zero_extract:SI
7436             (match_operand 1 "ext_register_operand" "%0")
7437             (const_int 8)
7438             (const_int 8))
7439           (zero_extract:SI
7440             (match_operand 2 "ext_register_operand" "Q")
7441             (const_int 8)
7442             (const_int 8))))
7443    (clobber (reg:CC FLAGS_REG))]
7444   ""
7445   "add{b}\t{%h2, %h0|%h0, %h2}"
7446   [(set_attr "type" "alu")
7447    (set_attr "mode" "QI")])
7448
7449 ;; The patterns that match these are at the end of this file.
7450
7451 (define_expand "addxf3"
7452   [(set (match_operand:XF 0 "register_operand" "")
7453         (plus:XF (match_operand:XF 1 "register_operand" "")
7454                  (match_operand:XF 2 "register_operand" "")))]
7455   "TARGET_80387"
7456   "")
7457
7458 (define_expand "add<mode>3"
7459   [(set (match_operand:MODEF 0 "register_operand" "")
7460         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7461                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7462   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7463   "")
7464 \f
7465 ;; Subtract instructions
7466
7467 ;; %%% splits for subditi3
7468
7469 (define_expand "subti3"
7470   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7471         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7472                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7473   "TARGET_64BIT"
7474   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7475
7476 (define_insn "*subti3_1"
7477   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7478         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7479                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7480    (clobber (reg:CC FLAGS_REG))]
7481   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7482   "#")
7483
7484 (define_split
7485   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7486         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7487                   (match_operand:TI 2 "x86_64_general_operand" "")))
7488    (clobber (reg:CC FLAGS_REG))]
7489   "TARGET_64BIT && reload_completed"
7490   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7491               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7492    (parallel [(set (match_dup 3)
7493                    (minus:DI (match_dup 4)
7494                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7495                                       (match_dup 5))))
7496               (clobber (reg:CC FLAGS_REG))])]
7497   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7498
7499 ;; %%% splits for subsidi3
7500
7501 (define_expand "subdi3"
7502   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7503         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7504                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7505   ""
7506   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7507
7508 (define_insn "*subdi3_1"
7509   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7510         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7511                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7512    (clobber (reg:CC FLAGS_REG))]
7513   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7514   "#")
7515
7516 (define_split
7517   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7518         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7519                   (match_operand:DI 2 "general_operand" "")))
7520    (clobber (reg:CC FLAGS_REG))]
7521   "!TARGET_64BIT && reload_completed"
7522   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7523               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7524    (parallel [(set (match_dup 3)
7525                    (minus:SI (match_dup 4)
7526                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7527                                       (match_dup 5))))
7528               (clobber (reg:CC FLAGS_REG))])]
7529   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7530
7531 (define_insn "subdi3_carry_rex64"
7532   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7533           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7534             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7535                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7538   "sbb{q}\t{%2, %0|%0, %2}"
7539   [(set_attr "type" "alu")
7540    (set_attr "pent_pair" "pu")
7541    (set_attr "mode" "DI")])
7542
7543 (define_insn "*subdi_1_rex64"
7544   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7545         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7546                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7547    (clobber (reg:CC FLAGS_REG))]
7548   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7549   "sub{q}\t{%2, %0|%0, %2}"
7550   [(set_attr "type" "alu")
7551    (set_attr "mode" "DI")])
7552
7553 (define_insn "*subdi_2_rex64"
7554   [(set (reg FLAGS_REG)
7555         (compare
7556           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7557                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7558           (const_int 0)))
7559    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7560         (minus:DI (match_dup 1) (match_dup 2)))]
7561   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7562    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7563   "sub{q}\t{%2, %0|%0, %2}"
7564   [(set_attr "type" "alu")
7565    (set_attr "mode" "DI")])
7566
7567 (define_insn "*subdi_3_rex63"
7568   [(set (reg FLAGS_REG)
7569         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7570                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7571    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7572         (minus:DI (match_dup 1) (match_dup 2)))]
7573   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7574    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7575   "sub{q}\t{%2, %0|%0, %2}"
7576   [(set_attr "type" "alu")
7577    (set_attr "mode" "DI")])
7578
7579 (define_insn "subqi3_carry"
7580   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7581           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7582             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7583                (match_operand:QI 2 "general_operand" "qn,qm"))))
7584    (clobber (reg:CC FLAGS_REG))]
7585   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7586   "sbb{b}\t{%2, %0|%0, %2}"
7587   [(set_attr "type" "alu")
7588    (set_attr "pent_pair" "pu")
7589    (set_attr "mode" "QI")])
7590
7591 (define_insn "subhi3_carry"
7592   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7593           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7594             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7595                (match_operand:HI 2 "general_operand" "rn,rm"))))
7596    (clobber (reg:CC FLAGS_REG))]
7597   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7598   "sbb{w}\t{%2, %0|%0, %2}"
7599   [(set_attr "type" "alu")
7600    (set_attr "pent_pair" "pu")
7601    (set_attr "mode" "HI")])
7602
7603 (define_insn "subsi3_carry"
7604   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7605           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7606             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7607                (match_operand:SI 2 "general_operand" "ri,rm"))))
7608    (clobber (reg:CC FLAGS_REG))]
7609   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7610   "sbb{l}\t{%2, %0|%0, %2}"
7611   [(set_attr "type" "alu")
7612    (set_attr "pent_pair" "pu")
7613    (set_attr "mode" "SI")])
7614
7615 (define_insn "subsi3_carry_zext"
7616   [(set (match_operand:DI 0 "register_operand" "=r")
7617           (zero_extend:DI
7618             (minus:SI (match_operand:SI 1 "register_operand" "0")
7619               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7620                  (match_operand:SI 2 "general_operand" "g")))))
7621    (clobber (reg:CC FLAGS_REG))]
7622   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7623   "sbb{l}\t{%2, %k0|%k0, %2}"
7624   [(set_attr "type" "alu")
7625    (set_attr "pent_pair" "pu")
7626    (set_attr "mode" "SI")])
7627
7628 (define_expand "subsi3"
7629   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7630         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7631                   (match_operand:SI 2 "general_operand" "")))]
7632   ""
7633   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7634
7635 (define_insn "*subsi_1"
7636   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7637         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7638                   (match_operand:SI 2 "general_operand" "ri,rm")))
7639    (clobber (reg:CC FLAGS_REG))]
7640   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7641   "sub{l}\t{%2, %0|%0, %2}"
7642   [(set_attr "type" "alu")
7643    (set_attr "mode" "SI")])
7644
7645 (define_insn "*subsi_1_zext"
7646   [(set (match_operand:DI 0 "register_operand" "=r")
7647         (zero_extend:DI
7648           (minus:SI (match_operand:SI 1 "register_operand" "0")
7649                     (match_operand:SI 2 "general_operand" "g"))))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7652   "sub{l}\t{%2, %k0|%k0, %2}"
7653   [(set_attr "type" "alu")
7654    (set_attr "mode" "SI")])
7655
7656 (define_insn "*subsi_2"
7657   [(set (reg FLAGS_REG)
7658         (compare
7659           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7660                     (match_operand:SI 2 "general_operand" "ri,rm"))
7661           (const_int 0)))
7662    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7663         (minus:SI (match_dup 1) (match_dup 2)))]
7664   "ix86_match_ccmode (insn, CCGOCmode)
7665    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7666   "sub{l}\t{%2, %0|%0, %2}"
7667   [(set_attr "type" "alu")
7668    (set_attr "mode" "SI")])
7669
7670 (define_insn "*subsi_2_zext"
7671   [(set (reg FLAGS_REG)
7672         (compare
7673           (minus:SI (match_operand:SI 1 "register_operand" "0")
7674                     (match_operand:SI 2 "general_operand" "g"))
7675           (const_int 0)))
7676    (set (match_operand:DI 0 "register_operand" "=r")
7677         (zero_extend:DI
7678           (minus:SI (match_dup 1)
7679                     (match_dup 2))))]
7680   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7681    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682   "sub{l}\t{%2, %k0|%k0, %2}"
7683   [(set_attr "type" "alu")
7684    (set_attr "mode" "SI")])
7685
7686 (define_insn "*subsi_3"
7687   [(set (reg FLAGS_REG)
7688         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7689                  (match_operand:SI 2 "general_operand" "ri,rm")))
7690    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7691         (minus:SI (match_dup 1) (match_dup 2)))]
7692   "ix86_match_ccmode (insn, CCmode)
7693    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7694   "sub{l}\t{%2, %0|%0, %2}"
7695   [(set_attr "type" "alu")
7696    (set_attr "mode" "SI")])
7697
7698 (define_insn "*subsi_3_zext"
7699   [(set (reg FLAGS_REG)
7700         (compare (match_operand:SI 1 "register_operand" "0")
7701                  (match_operand:SI 2 "general_operand" "g")))
7702    (set (match_operand:DI 0 "register_operand" "=r")
7703         (zero_extend:DI
7704           (minus:SI (match_dup 1)
7705                     (match_dup 2))))]
7706   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7707    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7708   "sub{l}\t{%2, %1|%1, %2}"
7709   [(set_attr "type" "alu")
7710    (set_attr "mode" "DI")])
7711
7712 (define_expand "subhi3"
7713   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7714         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7715                   (match_operand:HI 2 "general_operand" "")))]
7716   "TARGET_HIMODE_MATH"
7717   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7718
7719 (define_insn "*subhi_1"
7720   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7721         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7722                   (match_operand:HI 2 "general_operand" "rn,rm")))
7723    (clobber (reg:CC FLAGS_REG))]
7724   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7725   "sub{w}\t{%2, %0|%0, %2}"
7726   [(set_attr "type" "alu")
7727    (set_attr "mode" "HI")])
7728
7729 (define_insn "*subhi_2"
7730   [(set (reg FLAGS_REG)
7731         (compare
7732           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7733                     (match_operand:HI 2 "general_operand" "rn,rm"))
7734           (const_int 0)))
7735    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7736         (minus:HI (match_dup 1) (match_dup 2)))]
7737   "ix86_match_ccmode (insn, CCGOCmode)
7738    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7739   "sub{w}\t{%2, %0|%0, %2}"
7740   [(set_attr "type" "alu")
7741    (set_attr "mode" "HI")])
7742
7743 (define_insn "*subhi_3"
7744   [(set (reg FLAGS_REG)
7745         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7746                  (match_operand:HI 2 "general_operand" "rn,rm")))
7747    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7748         (minus:HI (match_dup 1) (match_dup 2)))]
7749   "ix86_match_ccmode (insn, CCmode)
7750    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7751   "sub{w}\t{%2, %0|%0, %2}"
7752   [(set_attr "type" "alu")
7753    (set_attr "mode" "HI")])
7754
7755 (define_expand "subqi3"
7756   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7757         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7758                   (match_operand:QI 2 "general_operand" "")))]
7759   "TARGET_QIMODE_MATH"
7760   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7761
7762 (define_insn "*subqi_1"
7763   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7764         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7765                   (match_operand:QI 2 "general_operand" "qn,qm")))
7766    (clobber (reg:CC FLAGS_REG))]
7767   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7768   "sub{b}\t{%2, %0|%0, %2}"
7769   [(set_attr "type" "alu")
7770    (set_attr "mode" "QI")])
7771
7772 (define_insn "*subqi_1_slp"
7773   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7774         (minus:QI (match_dup 0)
7775                   (match_operand:QI 1 "general_operand" "qn,qm")))
7776    (clobber (reg:CC FLAGS_REG))]
7777   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7778    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7779   "sub{b}\t{%1, %0|%0, %1}"
7780   [(set_attr "type" "alu1")
7781    (set_attr "mode" "QI")])
7782
7783 (define_insn "*subqi_2"
7784   [(set (reg FLAGS_REG)
7785         (compare
7786           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7787                     (match_operand:QI 2 "general_operand" "qn,qm"))
7788           (const_int 0)))
7789    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7790         (minus:QI (match_dup 1) (match_dup 2)))]
7791   "ix86_match_ccmode (insn, CCGOCmode)
7792    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7793   "sub{b}\t{%2, %0|%0, %2}"
7794   [(set_attr "type" "alu")
7795    (set_attr "mode" "QI")])
7796
7797 (define_insn "*subqi_3"
7798   [(set (reg FLAGS_REG)
7799         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7800                  (match_operand:QI 2 "general_operand" "qn,qm")))
7801    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7802         (minus:QI (match_dup 1) (match_dup 2)))]
7803   "ix86_match_ccmode (insn, CCmode)
7804    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7805   "sub{b}\t{%2, %0|%0, %2}"
7806   [(set_attr "type" "alu")
7807    (set_attr "mode" "QI")])
7808
7809 ;; The patterns that match these are at the end of this file.
7810
7811 (define_expand "subxf3"
7812   [(set (match_operand:XF 0 "register_operand" "")
7813         (minus:XF (match_operand:XF 1 "register_operand" "")
7814                   (match_operand:XF 2 "register_operand" "")))]
7815   "TARGET_80387"
7816   "")
7817
7818 (define_expand "sub<mode>3"
7819   [(set (match_operand:MODEF 0 "register_operand" "")
7820         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7821                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7822   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7823   "")
7824 \f
7825 ;; Multiply instructions
7826
7827 (define_expand "muldi3"
7828   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7829                    (mult:DI (match_operand:DI 1 "register_operand" "")
7830                             (match_operand:DI 2 "x86_64_general_operand" "")))
7831               (clobber (reg:CC FLAGS_REG))])]
7832   "TARGET_64BIT"
7833   "")
7834
7835 ;; On AMDFAM10
7836 ;; IMUL reg64, reg64, imm8      Direct
7837 ;; IMUL reg64, mem64, imm8      VectorPath
7838 ;; IMUL reg64, reg64, imm32     Direct
7839 ;; IMUL reg64, mem64, imm32     VectorPath
7840 ;; IMUL reg64, reg64            Direct
7841 ;; IMUL reg64, mem64            Direct
7842
7843 (define_insn "*muldi3_1_rex64"
7844   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7845         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7846                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7847    (clobber (reg:CC FLAGS_REG))]
7848   "TARGET_64BIT
7849    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7850   "@
7851    imul{q}\t{%2, %1, %0|%0, %1, %2}
7852    imul{q}\t{%2, %1, %0|%0, %1, %2}
7853    imul{q}\t{%2, %0|%0, %2}"
7854   [(set_attr "type" "imul")
7855    (set_attr "prefix_0f" "0,0,1")
7856    (set (attr "athlon_decode")
7857         (cond [(eq_attr "cpu" "athlon")
7858                   (const_string "vector")
7859                (eq_attr "alternative" "1")
7860                   (const_string "vector")
7861                (and (eq_attr "alternative" "2")
7862                     (match_operand 1 "memory_operand" ""))
7863                   (const_string "vector")]
7864               (const_string "direct")))
7865    (set (attr "amdfam10_decode")
7866         (cond [(and (eq_attr "alternative" "0,1")
7867                     (match_operand 1 "memory_operand" ""))
7868                   (const_string "vector")]
7869               (const_string "direct")))
7870    (set_attr "mode" "DI")])
7871
7872 (define_expand "mulsi3"
7873   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7874                    (mult:SI (match_operand:SI 1 "register_operand" "")
7875                             (match_operand:SI 2 "general_operand" "")))
7876               (clobber (reg:CC FLAGS_REG))])]
7877   ""
7878   "")
7879
7880 ;; On AMDFAM10
7881 ;; IMUL reg32, reg32, imm8      Direct
7882 ;; IMUL reg32, mem32, imm8      VectorPath
7883 ;; IMUL reg32, reg32, imm32     Direct
7884 ;; IMUL reg32, mem32, imm32     VectorPath
7885 ;; IMUL reg32, reg32            Direct
7886 ;; IMUL reg32, mem32            Direct
7887
7888 (define_insn "*mulsi3_1"
7889   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7890         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7891                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7892    (clobber (reg:CC FLAGS_REG))]
7893   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7894   "@
7895    imul{l}\t{%2, %1, %0|%0, %1, %2}
7896    imul{l}\t{%2, %1, %0|%0, %1, %2}
7897    imul{l}\t{%2, %0|%0, %2}"
7898   [(set_attr "type" "imul")
7899    (set_attr "prefix_0f" "0,0,1")
7900    (set (attr "athlon_decode")
7901         (cond [(eq_attr "cpu" "athlon")
7902                   (const_string "vector")
7903                (eq_attr "alternative" "1")
7904                   (const_string "vector")
7905                (and (eq_attr "alternative" "2")
7906                     (match_operand 1 "memory_operand" ""))
7907                   (const_string "vector")]
7908               (const_string "direct")))
7909    (set (attr "amdfam10_decode")
7910         (cond [(and (eq_attr "alternative" "0,1")
7911                     (match_operand 1 "memory_operand" ""))
7912                   (const_string "vector")]
7913               (const_string "direct")))
7914    (set_attr "mode" "SI")])
7915
7916 (define_insn "*mulsi3_1_zext"
7917   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7918         (zero_extend:DI
7919           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7920                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7921    (clobber (reg:CC FLAGS_REG))]
7922   "TARGET_64BIT
7923    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7924   "@
7925    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7926    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927    imul{l}\t{%2, %k0|%k0, %2}"
7928   [(set_attr "type" "imul")
7929    (set_attr "prefix_0f" "0,0,1")
7930    (set (attr "athlon_decode")
7931         (cond [(eq_attr "cpu" "athlon")
7932                   (const_string "vector")
7933                (eq_attr "alternative" "1")
7934                   (const_string "vector")
7935                (and (eq_attr "alternative" "2")
7936                     (match_operand 1 "memory_operand" ""))
7937                   (const_string "vector")]
7938               (const_string "direct")))
7939    (set (attr "amdfam10_decode")
7940         (cond [(and (eq_attr "alternative" "0,1")
7941                     (match_operand 1 "memory_operand" ""))
7942                   (const_string "vector")]
7943               (const_string "direct")))
7944    (set_attr "mode" "SI")])
7945
7946 (define_expand "mulhi3"
7947   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7948                    (mult:HI (match_operand:HI 1 "register_operand" "")
7949                             (match_operand:HI 2 "general_operand" "")))
7950               (clobber (reg:CC FLAGS_REG))])]
7951   "TARGET_HIMODE_MATH"
7952   "")
7953
7954 ;; On AMDFAM10
7955 ;; IMUL reg16, reg16, imm8      VectorPath
7956 ;; IMUL reg16, mem16, imm8      VectorPath
7957 ;; IMUL reg16, reg16, imm16     VectorPath
7958 ;; IMUL reg16, mem16, imm16     VectorPath
7959 ;; IMUL reg16, reg16            Direct
7960 ;; IMUL reg16, mem16            Direct
7961 (define_insn "*mulhi3_1"
7962   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7963         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7964                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7965    (clobber (reg:CC FLAGS_REG))]
7966   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7967   "@
7968    imul{w}\t{%2, %1, %0|%0, %1, %2}
7969    imul{w}\t{%2, %1, %0|%0, %1, %2}
7970    imul{w}\t{%2, %0|%0, %2}"
7971   [(set_attr "type" "imul")
7972    (set_attr "prefix_0f" "0,0,1")
7973    (set (attr "athlon_decode")
7974         (cond [(eq_attr "cpu" "athlon")
7975                   (const_string "vector")
7976                (eq_attr "alternative" "1,2")
7977                   (const_string "vector")]
7978               (const_string "direct")))
7979    (set (attr "amdfam10_decode")
7980         (cond [(eq_attr "alternative" "0,1")
7981                   (const_string "vector")]
7982               (const_string "direct")))
7983    (set_attr "mode" "HI")])
7984
7985 (define_expand "mulqi3"
7986   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7987                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7988                             (match_operand:QI 2 "register_operand" "")))
7989               (clobber (reg:CC FLAGS_REG))])]
7990   "TARGET_QIMODE_MATH"
7991   "")
7992
7993 ;;On AMDFAM10
7994 ;; MUL reg8     Direct
7995 ;; MUL mem8     Direct
7996
7997 (define_insn "*mulqi3_1"
7998   [(set (match_operand:QI 0 "register_operand" "=a")
7999         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8000                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8001    (clobber (reg:CC FLAGS_REG))]
8002   "TARGET_QIMODE_MATH
8003    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8004   "mul{b}\t%2"
8005   [(set_attr "type" "imul")
8006    (set_attr "length_immediate" "0")
8007    (set (attr "athlon_decode")
8008      (if_then_else (eq_attr "cpu" "athlon")
8009         (const_string "vector")
8010         (const_string "direct")))
8011    (set_attr "amdfam10_decode" "direct")
8012    (set_attr "mode" "QI")])
8013
8014 (define_expand "umulqihi3"
8015   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8016                    (mult:HI (zero_extend:HI
8017                               (match_operand:QI 1 "nonimmediate_operand" ""))
8018                             (zero_extend:HI
8019                               (match_operand:QI 2 "register_operand" ""))))
8020               (clobber (reg:CC FLAGS_REG))])]
8021   "TARGET_QIMODE_MATH"
8022   "")
8023
8024 (define_insn "*umulqihi3_1"
8025   [(set (match_operand:HI 0 "register_operand" "=a")
8026         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8027                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8028    (clobber (reg:CC FLAGS_REG))]
8029   "TARGET_QIMODE_MATH
8030    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8031   "mul{b}\t%2"
8032   [(set_attr "type" "imul")
8033    (set_attr "length_immediate" "0")
8034    (set (attr "athlon_decode")
8035      (if_then_else (eq_attr "cpu" "athlon")
8036         (const_string "vector")
8037         (const_string "direct")))
8038    (set_attr "amdfam10_decode" "direct")
8039    (set_attr "mode" "QI")])
8040
8041 (define_expand "mulqihi3"
8042   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8043                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8044                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8045               (clobber (reg:CC FLAGS_REG))])]
8046   "TARGET_QIMODE_MATH"
8047   "")
8048
8049 (define_insn "*mulqihi3_insn"
8050   [(set (match_operand:HI 0 "register_operand" "=a")
8051         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8052                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8053    (clobber (reg:CC FLAGS_REG))]
8054   "TARGET_QIMODE_MATH
8055    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8056   "imul{b}\t%2"
8057   [(set_attr "type" "imul")
8058    (set_attr "length_immediate" "0")
8059    (set (attr "athlon_decode")
8060      (if_then_else (eq_attr "cpu" "athlon")
8061         (const_string "vector")
8062         (const_string "direct")))
8063    (set_attr "amdfam10_decode" "direct")
8064    (set_attr "mode" "QI")])
8065
8066 (define_expand "umulditi3"
8067   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8068                    (mult:TI (zero_extend:TI
8069                               (match_operand:DI 1 "nonimmediate_operand" ""))
8070                             (zero_extend:TI
8071                               (match_operand:DI 2 "register_operand" ""))))
8072               (clobber (reg:CC FLAGS_REG))])]
8073   "TARGET_64BIT"
8074   "")
8075
8076 (define_insn "*umulditi3_insn"
8077   [(set (match_operand:TI 0 "register_operand" "=A")
8078         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8079                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8080    (clobber (reg:CC FLAGS_REG))]
8081   "TARGET_64BIT
8082    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8083   "mul{q}\t%2"
8084   [(set_attr "type" "imul")
8085    (set_attr "length_immediate" "0")
8086    (set (attr "athlon_decode")
8087      (if_then_else (eq_attr "cpu" "athlon")
8088         (const_string "vector")
8089         (const_string "double")))
8090    (set_attr "amdfam10_decode" "double")
8091    (set_attr "mode" "DI")])
8092
8093 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8094 (define_expand "umulsidi3"
8095   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8096                    (mult:DI (zero_extend:DI
8097                               (match_operand:SI 1 "nonimmediate_operand" ""))
8098                             (zero_extend:DI
8099                               (match_operand:SI 2 "register_operand" ""))))
8100               (clobber (reg:CC FLAGS_REG))])]
8101   "!TARGET_64BIT"
8102   "")
8103
8104 (define_insn "*umulsidi3_insn"
8105   [(set (match_operand:DI 0 "register_operand" "=A")
8106         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8107                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8108    (clobber (reg:CC FLAGS_REG))]
8109   "!TARGET_64BIT
8110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8111   "mul{l}\t%2"
8112   [(set_attr "type" "imul")
8113    (set_attr "length_immediate" "0")
8114    (set (attr "athlon_decode")
8115      (if_then_else (eq_attr "cpu" "athlon")
8116         (const_string "vector")
8117         (const_string "double")))
8118    (set_attr "amdfam10_decode" "double")
8119    (set_attr "mode" "SI")])
8120
8121 (define_expand "mulditi3"
8122   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8123                    (mult:TI (sign_extend:TI
8124                               (match_operand:DI 1 "nonimmediate_operand" ""))
8125                             (sign_extend:TI
8126                               (match_operand:DI 2 "register_operand" ""))))
8127               (clobber (reg:CC FLAGS_REG))])]
8128   "TARGET_64BIT"
8129   "")
8130
8131 (define_insn "*mulditi3_insn"
8132   [(set (match_operand:TI 0 "register_operand" "=A")
8133         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8134                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8135    (clobber (reg:CC FLAGS_REG))]
8136   "TARGET_64BIT
8137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8138   "imul{q}\t%2"
8139   [(set_attr "type" "imul")
8140    (set_attr "length_immediate" "0")
8141    (set (attr "athlon_decode")
8142      (if_then_else (eq_attr "cpu" "athlon")
8143         (const_string "vector")
8144         (const_string "double")))
8145    (set_attr "amdfam10_decode" "double")
8146    (set_attr "mode" "DI")])
8147
8148 (define_expand "mulsidi3"
8149   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8150                    (mult:DI (sign_extend:DI
8151                               (match_operand:SI 1 "nonimmediate_operand" ""))
8152                             (sign_extend:DI
8153                               (match_operand:SI 2 "register_operand" ""))))
8154               (clobber (reg:CC FLAGS_REG))])]
8155   "!TARGET_64BIT"
8156   "")
8157
8158 (define_insn "*mulsidi3_insn"
8159   [(set (match_operand:DI 0 "register_operand" "=A")
8160         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8161                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8162    (clobber (reg:CC FLAGS_REG))]
8163   "!TARGET_64BIT
8164    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8165   "imul{l}\t%2"
8166   [(set_attr "type" "imul")
8167    (set_attr "length_immediate" "0")
8168    (set (attr "athlon_decode")
8169      (if_then_else (eq_attr "cpu" "athlon")
8170         (const_string "vector")
8171         (const_string "double")))
8172    (set_attr "amdfam10_decode" "double")
8173    (set_attr "mode" "SI")])
8174
8175 (define_expand "umuldi3_highpart"
8176   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8177                    (truncate:DI
8178                      (lshiftrt:TI
8179                        (mult:TI (zero_extend:TI
8180                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8181                                 (zero_extend:TI
8182                                   (match_operand:DI 2 "register_operand" "")))
8183                        (const_int 64))))
8184               (clobber (match_scratch:DI 3 ""))
8185               (clobber (reg:CC FLAGS_REG))])]
8186   "TARGET_64BIT"
8187   "")
8188
8189 (define_insn "*umuldi3_highpart_rex64"
8190   [(set (match_operand:DI 0 "register_operand" "=d")
8191         (truncate:DI
8192           (lshiftrt:TI
8193             (mult:TI (zero_extend:TI
8194                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8195                      (zero_extend:TI
8196                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8197             (const_int 64))))
8198    (clobber (match_scratch:DI 3 "=1"))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "TARGET_64BIT
8201    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8202   "mul{q}\t%2"
8203   [(set_attr "type" "imul")
8204    (set_attr "length_immediate" "0")
8205    (set (attr "athlon_decode")
8206      (if_then_else (eq_attr "cpu" "athlon")
8207         (const_string "vector")
8208         (const_string "double")))
8209    (set_attr "amdfam10_decode" "double")
8210    (set_attr "mode" "DI")])
8211
8212 (define_expand "umulsi3_highpart"
8213   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8214                    (truncate:SI
8215                      (lshiftrt:DI
8216                        (mult:DI (zero_extend:DI
8217                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8218                                 (zero_extend:DI
8219                                   (match_operand:SI 2 "register_operand" "")))
8220                        (const_int 32))))
8221               (clobber (match_scratch:SI 3 ""))
8222               (clobber (reg:CC FLAGS_REG))])]
8223   ""
8224   "")
8225
8226 (define_insn "*umulsi3_highpart_insn"
8227   [(set (match_operand:SI 0 "register_operand" "=d")
8228         (truncate:SI
8229           (lshiftrt:DI
8230             (mult:DI (zero_extend:DI
8231                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8232                      (zero_extend:DI
8233                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8234             (const_int 32))))
8235    (clobber (match_scratch:SI 3 "=1"))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8238   "mul{l}\t%2"
8239   [(set_attr "type" "imul")
8240    (set_attr "length_immediate" "0")
8241    (set (attr "athlon_decode")
8242      (if_then_else (eq_attr "cpu" "athlon")
8243         (const_string "vector")
8244         (const_string "double")))
8245    (set_attr "amdfam10_decode" "double")
8246    (set_attr "mode" "SI")])
8247
8248 (define_insn "*umulsi3_highpart_zext"
8249   [(set (match_operand:DI 0 "register_operand" "=d")
8250         (zero_extend:DI (truncate:SI
8251           (lshiftrt:DI
8252             (mult:DI (zero_extend:DI
8253                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8254                      (zero_extend:DI
8255                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8256             (const_int 32)))))
8257    (clobber (match_scratch:SI 3 "=1"))
8258    (clobber (reg:CC FLAGS_REG))]
8259   "TARGET_64BIT
8260    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8261   "mul{l}\t%2"
8262   [(set_attr "type" "imul")
8263    (set_attr "length_immediate" "0")
8264    (set (attr "athlon_decode")
8265      (if_then_else (eq_attr "cpu" "athlon")
8266         (const_string "vector")
8267         (const_string "double")))
8268    (set_attr "amdfam10_decode" "double")
8269    (set_attr "mode" "SI")])
8270
8271 (define_expand "smuldi3_highpart"
8272   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8273                    (truncate:DI
8274                      (lshiftrt:TI
8275                        (mult:TI (sign_extend:TI
8276                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8277                                 (sign_extend:TI
8278                                   (match_operand:DI 2 "register_operand" "")))
8279                        (const_int 64))))
8280               (clobber (match_scratch:DI 3 ""))
8281               (clobber (reg:CC FLAGS_REG))])]
8282   "TARGET_64BIT"
8283   "")
8284
8285 (define_insn "*smuldi3_highpart_rex64"
8286   [(set (match_operand:DI 0 "register_operand" "=d")
8287         (truncate:DI
8288           (lshiftrt:TI
8289             (mult:TI (sign_extend:TI
8290                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8291                      (sign_extend:TI
8292                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8293             (const_int 64))))
8294    (clobber (match_scratch:DI 3 "=1"))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "TARGET_64BIT
8297    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8298   "imul{q}\t%2"
8299   [(set_attr "type" "imul")
8300    (set (attr "athlon_decode")
8301      (if_then_else (eq_attr "cpu" "athlon")
8302         (const_string "vector")
8303         (const_string "double")))
8304    (set_attr "amdfam10_decode" "double")
8305    (set_attr "mode" "DI")])
8306
8307 (define_expand "smulsi3_highpart"
8308   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8309                    (truncate:SI
8310                      (lshiftrt:DI
8311                        (mult:DI (sign_extend:DI
8312                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8313                                 (sign_extend:DI
8314                                   (match_operand:SI 2 "register_operand" "")))
8315                        (const_int 32))))
8316               (clobber (match_scratch:SI 3 ""))
8317               (clobber (reg:CC FLAGS_REG))])]
8318   ""
8319   "")
8320
8321 (define_insn "*smulsi3_highpart_insn"
8322   [(set (match_operand:SI 0 "register_operand" "=d")
8323         (truncate:SI
8324           (lshiftrt:DI
8325             (mult:DI (sign_extend:DI
8326                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8327                      (sign_extend:DI
8328                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8329             (const_int 32))))
8330    (clobber (match_scratch:SI 3 "=1"))
8331    (clobber (reg:CC FLAGS_REG))]
8332   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8333   "imul{l}\t%2"
8334   [(set_attr "type" "imul")
8335    (set (attr "athlon_decode")
8336      (if_then_else (eq_attr "cpu" "athlon")
8337         (const_string "vector")
8338         (const_string "double")))
8339    (set_attr "amdfam10_decode" "double")
8340    (set_attr "mode" "SI")])
8341
8342 (define_insn "*smulsi3_highpart_zext"
8343   [(set (match_operand:DI 0 "register_operand" "=d")
8344         (zero_extend:DI (truncate:SI
8345           (lshiftrt:DI
8346             (mult:DI (sign_extend:DI
8347                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8348                      (sign_extend:DI
8349                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8350             (const_int 32)))))
8351    (clobber (match_scratch:SI 3 "=1"))
8352    (clobber (reg:CC FLAGS_REG))]
8353   "TARGET_64BIT
8354    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8355   "imul{l}\t%2"
8356   [(set_attr "type" "imul")
8357    (set (attr "athlon_decode")
8358      (if_then_else (eq_attr "cpu" "athlon")
8359         (const_string "vector")
8360         (const_string "double")))
8361    (set_attr "amdfam10_decode" "double")
8362    (set_attr "mode" "SI")])
8363
8364 ;; The patterns that match these are at the end of this file.
8365
8366 (define_expand "mulxf3"
8367   [(set (match_operand:XF 0 "register_operand" "")
8368         (mult:XF (match_operand:XF 1 "register_operand" "")
8369                  (match_operand:XF 2 "register_operand" "")))]
8370   "TARGET_80387"
8371   "")
8372
8373 (define_expand "mul<mode>3"
8374   [(set (match_operand:MODEF 0 "register_operand" "")
8375         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8376                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8377   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8378   "")
8379
8380 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8381
8382 \f
8383 ;; Divide instructions
8384
8385 (define_insn "divqi3"
8386   [(set (match_operand:QI 0 "register_operand" "=a")
8387         (div:QI (match_operand:HI 1 "register_operand" "0")
8388                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8389    (clobber (reg:CC FLAGS_REG))]
8390   "TARGET_QIMODE_MATH"
8391   "idiv{b}\t%2"
8392   [(set_attr "type" "idiv")
8393    (set_attr "mode" "QI")])
8394
8395 (define_insn "udivqi3"
8396   [(set (match_operand:QI 0 "register_operand" "=a")
8397         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8398                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8399    (clobber (reg:CC FLAGS_REG))]
8400   "TARGET_QIMODE_MATH"
8401   "div{b}\t%2"
8402   [(set_attr "type" "idiv")
8403    (set_attr "mode" "QI")])
8404
8405 ;; The patterns that match these are at the end of this file.
8406
8407 (define_expand "divxf3"
8408   [(set (match_operand:XF 0 "register_operand" "")
8409         (div:XF (match_operand:XF 1 "register_operand" "")
8410                 (match_operand:XF 2 "register_operand" "")))]
8411   "TARGET_80387"
8412   "")
8413
8414 (define_expand "divdf3"
8415   [(set (match_operand:DF 0 "register_operand" "")
8416         (div:DF (match_operand:DF 1 "register_operand" "")
8417                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8418    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8419    "")
8420
8421 (define_expand "divsf3"
8422   [(set (match_operand:SF 0 "register_operand" "")
8423         (div:SF (match_operand:SF 1 "register_operand" "")
8424                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8425   "TARGET_80387 || TARGET_SSE_MATH"
8426 {
8427   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8428       && flag_finite_math_only && !flag_trapping_math
8429       && flag_unsafe_math_optimizations)
8430     {
8431       ix86_emit_swdivsf (operands[0], operands[1],
8432                          operands[2], SFmode);
8433       DONE;
8434     }
8435 })
8436 \f
8437 ;; Remainder instructions.
8438
8439 (define_expand "divmoddi4"
8440   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8441                    (div:DI (match_operand:DI 1 "register_operand" "")
8442                            (match_operand:DI 2 "nonimmediate_operand" "")))
8443               (set (match_operand:DI 3 "register_operand" "")
8444                    (mod:DI (match_dup 1) (match_dup 2)))
8445               (clobber (reg:CC FLAGS_REG))])]
8446   "TARGET_64BIT"
8447   "")
8448
8449 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8450 ;; Penalize eax case slightly because it results in worse scheduling
8451 ;; of code.
8452 (define_insn "*divmoddi4_nocltd_rex64"
8453   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8454         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8455                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8456    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8457         (mod:DI (match_dup 2) (match_dup 3)))
8458    (clobber (reg:CC FLAGS_REG))]
8459   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8460   "#"
8461   [(set_attr "type" "multi")])
8462
8463 (define_insn "*divmoddi4_cltd_rex64"
8464   [(set (match_operand:DI 0 "register_operand" "=a")
8465         (div:DI (match_operand:DI 2 "register_operand" "a")
8466                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8467    (set (match_operand:DI 1 "register_operand" "=&d")
8468         (mod:DI (match_dup 2) (match_dup 3)))
8469    (clobber (reg:CC FLAGS_REG))]
8470   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8471   "#"
8472   [(set_attr "type" "multi")])
8473
8474 (define_insn "*divmoddi_noext_rex64"
8475   [(set (match_operand:DI 0 "register_operand" "=a")
8476         (div:DI (match_operand:DI 1 "register_operand" "0")
8477                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8478    (set (match_operand:DI 3 "register_operand" "=d")
8479         (mod:DI (match_dup 1) (match_dup 2)))
8480    (use (match_operand:DI 4 "register_operand" "3"))
8481    (clobber (reg:CC FLAGS_REG))]
8482   "TARGET_64BIT"
8483   "idiv{q}\t%2"
8484   [(set_attr "type" "idiv")
8485    (set_attr "mode" "DI")])
8486
8487 (define_split
8488   [(set (match_operand:DI 0 "register_operand" "")
8489         (div:DI (match_operand:DI 1 "register_operand" "")
8490                 (match_operand:DI 2 "nonimmediate_operand" "")))
8491    (set (match_operand:DI 3 "register_operand" "")
8492         (mod:DI (match_dup 1) (match_dup 2)))
8493    (clobber (reg:CC FLAGS_REG))]
8494   "TARGET_64BIT && reload_completed"
8495   [(parallel [(set (match_dup 3)
8496                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8497               (clobber (reg:CC FLAGS_REG))])
8498    (parallel [(set (match_dup 0)
8499                    (div:DI (reg:DI 0) (match_dup 2)))
8500               (set (match_dup 3)
8501                    (mod:DI (reg:DI 0) (match_dup 2)))
8502               (use (match_dup 3))
8503               (clobber (reg:CC FLAGS_REG))])]
8504 {
8505   /* Avoid use of cltd in favor of a mov+shift.  */
8506   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8507     {
8508       if (true_regnum (operands[1]))
8509         emit_move_insn (operands[0], operands[1]);
8510       else
8511         emit_move_insn (operands[3], operands[1]);
8512       operands[4] = operands[3];
8513     }
8514   else
8515     {
8516       gcc_assert (!true_regnum (operands[1]));
8517       operands[4] = operands[1];
8518     }
8519 })
8520
8521
8522 (define_expand "divmodsi4"
8523   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8524                    (div:SI (match_operand:SI 1 "register_operand" "")
8525                            (match_operand:SI 2 "nonimmediate_operand" "")))
8526               (set (match_operand:SI 3 "register_operand" "")
8527                    (mod:SI (match_dup 1) (match_dup 2)))
8528               (clobber (reg:CC FLAGS_REG))])]
8529   ""
8530   "")
8531
8532 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8533 ;; Penalize eax case slightly because it results in worse scheduling
8534 ;; of code.
8535 (define_insn "*divmodsi4_nocltd"
8536   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8537         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8538                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8539    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8540         (mod:SI (match_dup 2) (match_dup 3)))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8543   "#"
8544   [(set_attr "type" "multi")])
8545
8546 (define_insn "*divmodsi4_cltd"
8547   [(set (match_operand:SI 0 "register_operand" "=a")
8548         (div:SI (match_operand:SI 2 "register_operand" "a")
8549                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8550    (set (match_operand:SI 1 "register_operand" "=&d")
8551         (mod:SI (match_dup 2) (match_dup 3)))
8552    (clobber (reg:CC FLAGS_REG))]
8553   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8554   "#"
8555   [(set_attr "type" "multi")])
8556
8557 (define_insn "*divmodsi_noext"
8558   [(set (match_operand:SI 0 "register_operand" "=a")
8559         (div:SI (match_operand:SI 1 "register_operand" "0")
8560                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8561    (set (match_operand:SI 3 "register_operand" "=d")
8562         (mod:SI (match_dup 1) (match_dup 2)))
8563    (use (match_operand:SI 4 "register_operand" "3"))
8564    (clobber (reg:CC FLAGS_REG))]
8565   ""
8566   "idiv{l}\t%2"
8567   [(set_attr "type" "idiv")
8568    (set_attr "mode" "SI")])
8569
8570 (define_split
8571   [(set (match_operand:SI 0 "register_operand" "")
8572         (div:SI (match_operand:SI 1 "register_operand" "")
8573                 (match_operand:SI 2 "nonimmediate_operand" "")))
8574    (set (match_operand:SI 3 "register_operand" "")
8575         (mod:SI (match_dup 1) (match_dup 2)))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "reload_completed"
8578   [(parallel [(set (match_dup 3)
8579                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8580               (clobber (reg:CC FLAGS_REG))])
8581    (parallel [(set (match_dup 0)
8582                    (div:SI (reg:SI 0) (match_dup 2)))
8583               (set (match_dup 3)
8584                    (mod:SI (reg:SI 0) (match_dup 2)))
8585               (use (match_dup 3))
8586               (clobber (reg:CC FLAGS_REG))])]
8587 {
8588   /* Avoid use of cltd in favor of a mov+shift.  */
8589   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8590     {
8591       if (true_regnum (operands[1]))
8592         emit_move_insn (operands[0], operands[1]);
8593       else
8594         emit_move_insn (operands[3], operands[1]);
8595       operands[4] = operands[3];
8596     }
8597   else
8598     {
8599       gcc_assert (!true_regnum (operands[1]));
8600       operands[4] = operands[1];
8601     }
8602 })
8603 ;; %%% Split me.
8604 (define_insn "divmodhi4"
8605   [(set (match_operand:HI 0 "register_operand" "=a")
8606         (div:HI (match_operand:HI 1 "register_operand" "0")
8607                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8608    (set (match_operand:HI 3 "register_operand" "=&d")
8609         (mod:HI (match_dup 1) (match_dup 2)))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "TARGET_HIMODE_MATH"
8612   "cwtd\;idiv{w}\t%2"
8613   [(set_attr "type" "multi")
8614    (set_attr "length_immediate" "0")
8615    (set_attr "mode" "SI")])
8616
8617 (define_insn "udivmoddi4"
8618   [(set (match_operand:DI 0 "register_operand" "=a")
8619         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8620                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8621    (set (match_operand:DI 3 "register_operand" "=&d")
8622         (umod:DI (match_dup 1) (match_dup 2)))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "TARGET_64BIT"
8625   "xor{q}\t%3, %3\;div{q}\t%2"
8626   [(set_attr "type" "multi")
8627    (set_attr "length_immediate" "0")
8628    (set_attr "mode" "DI")])
8629
8630 (define_insn "*udivmoddi4_noext"
8631   [(set (match_operand:DI 0 "register_operand" "=a")
8632         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8633                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8634    (set (match_operand:DI 3 "register_operand" "=d")
8635         (umod:DI (match_dup 1) (match_dup 2)))
8636    (use (match_dup 3))
8637    (clobber (reg:CC FLAGS_REG))]
8638   "TARGET_64BIT"
8639   "div{q}\t%2"
8640   [(set_attr "type" "idiv")
8641    (set_attr "mode" "DI")])
8642
8643 (define_split
8644   [(set (match_operand:DI 0 "register_operand" "")
8645         (udiv:DI (match_operand:DI 1 "register_operand" "")
8646                  (match_operand:DI 2 "nonimmediate_operand" "")))
8647    (set (match_operand:DI 3 "register_operand" "")
8648         (umod:DI (match_dup 1) (match_dup 2)))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "TARGET_64BIT && reload_completed"
8651   [(set (match_dup 3) (const_int 0))
8652    (parallel [(set (match_dup 0)
8653                    (udiv:DI (match_dup 1) (match_dup 2)))
8654               (set (match_dup 3)
8655                    (umod:DI (match_dup 1) (match_dup 2)))
8656               (use (match_dup 3))
8657               (clobber (reg:CC FLAGS_REG))])]
8658   "")
8659
8660 (define_insn "udivmodsi4"
8661   [(set (match_operand:SI 0 "register_operand" "=a")
8662         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8663                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8664    (set (match_operand:SI 3 "register_operand" "=&d")
8665         (umod:SI (match_dup 1) (match_dup 2)))
8666    (clobber (reg:CC FLAGS_REG))]
8667   ""
8668   "xor{l}\t%3, %3\;div{l}\t%2"
8669   [(set_attr "type" "multi")
8670    (set_attr "length_immediate" "0")
8671    (set_attr "mode" "SI")])
8672
8673 (define_insn "*udivmodsi4_noext"
8674   [(set (match_operand:SI 0 "register_operand" "=a")
8675         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8676                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8677    (set (match_operand:SI 3 "register_operand" "=d")
8678         (umod:SI (match_dup 1) (match_dup 2)))
8679    (use (match_dup 3))
8680    (clobber (reg:CC FLAGS_REG))]
8681   ""
8682   "div{l}\t%2"
8683   [(set_attr "type" "idiv")
8684    (set_attr "mode" "SI")])
8685
8686 (define_split
8687   [(set (match_operand:SI 0 "register_operand" "")
8688         (udiv:SI (match_operand:SI 1 "register_operand" "")
8689                  (match_operand:SI 2 "nonimmediate_operand" "")))
8690    (set (match_operand:SI 3 "register_operand" "")
8691         (umod:SI (match_dup 1) (match_dup 2)))
8692    (clobber (reg:CC FLAGS_REG))]
8693   "reload_completed"
8694   [(set (match_dup 3) (const_int 0))
8695    (parallel [(set (match_dup 0)
8696                    (udiv:SI (match_dup 1) (match_dup 2)))
8697               (set (match_dup 3)
8698                    (umod:SI (match_dup 1) (match_dup 2)))
8699               (use (match_dup 3))
8700               (clobber (reg:CC FLAGS_REG))])]
8701   "")
8702
8703 (define_expand "udivmodhi4"
8704   [(set (match_dup 4) (const_int 0))
8705    (parallel [(set (match_operand:HI 0 "register_operand" "")
8706                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8707                             (match_operand:HI 2 "nonimmediate_operand" "")))
8708               (set (match_operand:HI 3 "register_operand" "")
8709                    (umod:HI (match_dup 1) (match_dup 2)))
8710               (use (match_dup 4))
8711               (clobber (reg:CC FLAGS_REG))])]
8712   "TARGET_HIMODE_MATH"
8713   "operands[4] = gen_reg_rtx (HImode);")
8714
8715 (define_insn "*udivmodhi_noext"
8716   [(set (match_operand:HI 0 "register_operand" "=a")
8717         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8718                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8719    (set (match_operand:HI 3 "register_operand" "=d")
8720         (umod:HI (match_dup 1) (match_dup 2)))
8721    (use (match_operand:HI 4 "register_operand" "3"))
8722    (clobber (reg:CC FLAGS_REG))]
8723   ""
8724   "div{w}\t%2"
8725   [(set_attr "type" "idiv")
8726    (set_attr "mode" "HI")])
8727
8728 ;; We cannot use div/idiv for double division, because it causes
8729 ;; "division by zero" on the overflow and that's not what we expect
8730 ;; from truncate.  Because true (non truncating) double division is
8731 ;; never generated, we can't create this insn anyway.
8732 ;
8733 ;(define_insn ""
8734 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8735 ;       (truncate:SI
8736 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8737 ;                  (zero_extend:DI
8738 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8739 ;   (set (match_operand:SI 3 "register_operand" "=d")
8740 ;       (truncate:SI
8741 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8742 ;   (clobber (reg:CC FLAGS_REG))]
8743 ;  ""
8744 ;  "div{l}\t{%2, %0|%0, %2}"
8745 ;  [(set_attr "type" "idiv")])
8746 \f
8747 ;;- Logical AND instructions
8748
8749 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8750 ;; Note that this excludes ah.
8751
8752 (define_insn "*testdi_1_rex64"
8753   [(set (reg FLAGS_REG)
8754         (compare
8755           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8756                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8757           (const_int 0)))]
8758   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8759    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8760   "@
8761    test{l}\t{%k1, %k0|%k0, %k1}
8762    test{l}\t{%k1, %k0|%k0, %k1}
8763    test{q}\t{%1, %0|%0, %1}
8764    test{q}\t{%1, %0|%0, %1}
8765    test{q}\t{%1, %0|%0, %1}"
8766   [(set_attr "type" "test")
8767    (set_attr "modrm" "0,1,0,1,1")
8768    (set_attr "mode" "SI,SI,DI,DI,DI")
8769    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8770
8771 (define_insn "testsi_1"
8772   [(set (reg FLAGS_REG)
8773         (compare
8774           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8775                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8776           (const_int 0)))]
8777   "ix86_match_ccmode (insn, CCNOmode)
8778    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8779   "test{l}\t{%1, %0|%0, %1}"
8780   [(set_attr "type" "test")
8781    (set_attr "modrm" "0,1,1")
8782    (set_attr "mode" "SI")
8783    (set_attr "pent_pair" "uv,np,uv")])
8784
8785 (define_expand "testsi_ccno_1"
8786   [(set (reg:CCNO FLAGS_REG)
8787         (compare:CCNO
8788           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8789                   (match_operand:SI 1 "nonmemory_operand" ""))
8790           (const_int 0)))]
8791   ""
8792   "")
8793
8794 (define_insn "*testhi_1"
8795   [(set (reg FLAGS_REG)
8796         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8797                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8798                  (const_int 0)))]
8799   "ix86_match_ccmode (insn, CCNOmode)
8800    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8801   "test{w}\t{%1, %0|%0, %1}"
8802   [(set_attr "type" "test")
8803    (set_attr "modrm" "0,1,1")
8804    (set_attr "mode" "HI")
8805    (set_attr "pent_pair" "uv,np,uv")])
8806
8807 (define_expand "testqi_ccz_1"
8808   [(set (reg:CCZ FLAGS_REG)
8809         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8810                              (match_operand:QI 1 "nonmemory_operand" ""))
8811                  (const_int 0)))]
8812   ""
8813   "")
8814
8815 (define_insn "*testqi_1_maybe_si"
8816   [(set (reg FLAGS_REG)
8817         (compare
8818           (and:QI
8819             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8820             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8821           (const_int 0)))]
8822    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8823     && ix86_match_ccmode (insn,
8824                          CONST_INT_P (operands[1])
8825                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8826 {
8827   if (which_alternative == 3)
8828     {
8829       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8830         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8831       return "test{l}\t{%1, %k0|%k0, %1}";
8832     }
8833   return "test{b}\t{%1, %0|%0, %1}";
8834 }
8835   [(set_attr "type" "test")
8836    (set_attr "modrm" "0,1,1,1")
8837    (set_attr "mode" "QI,QI,QI,SI")
8838    (set_attr "pent_pair" "uv,np,uv,np")])
8839
8840 (define_insn "*testqi_1"
8841   [(set (reg FLAGS_REG)
8842         (compare
8843           (and:QI
8844             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8845             (match_operand:QI 1 "general_operand" "n,n,qn"))
8846           (const_int 0)))]
8847   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8848    && ix86_match_ccmode (insn, CCNOmode)"
8849   "test{b}\t{%1, %0|%0, %1}"
8850   [(set_attr "type" "test")
8851    (set_attr "modrm" "0,1,1")
8852    (set_attr "mode" "QI")
8853    (set_attr "pent_pair" "uv,np,uv")])
8854
8855 (define_expand "testqi_ext_ccno_0"
8856   [(set (reg:CCNO FLAGS_REG)
8857         (compare:CCNO
8858           (and:SI
8859             (zero_extract:SI
8860               (match_operand 0 "ext_register_operand" "")
8861               (const_int 8)
8862               (const_int 8))
8863             (match_operand 1 "const_int_operand" ""))
8864           (const_int 0)))]
8865   ""
8866   "")
8867
8868 (define_insn "*testqi_ext_0"
8869   [(set (reg FLAGS_REG)
8870         (compare
8871           (and:SI
8872             (zero_extract:SI
8873               (match_operand 0 "ext_register_operand" "Q")
8874               (const_int 8)
8875               (const_int 8))
8876             (match_operand 1 "const_int_operand" "n"))
8877           (const_int 0)))]
8878   "ix86_match_ccmode (insn, CCNOmode)"
8879   "test{b}\t{%1, %h0|%h0, %1}"
8880   [(set_attr "type" "test")
8881    (set_attr "mode" "QI")
8882    (set_attr "length_immediate" "1")
8883    (set_attr "pent_pair" "np")])
8884
8885 (define_insn "*testqi_ext_1"
8886   [(set (reg FLAGS_REG)
8887         (compare
8888           (and:SI
8889             (zero_extract:SI
8890               (match_operand 0 "ext_register_operand" "Q")
8891               (const_int 8)
8892               (const_int 8))
8893             (zero_extend:SI
8894               (match_operand:QI 1 "general_operand" "Qm")))
8895           (const_int 0)))]
8896   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8897    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8898   "test{b}\t{%1, %h0|%h0, %1}"
8899   [(set_attr "type" "test")
8900    (set_attr "mode" "QI")])
8901
8902 (define_insn "*testqi_ext_1_rex64"
8903   [(set (reg FLAGS_REG)
8904         (compare
8905           (and:SI
8906             (zero_extract:SI
8907               (match_operand 0 "ext_register_operand" "Q")
8908               (const_int 8)
8909               (const_int 8))
8910             (zero_extend:SI
8911               (match_operand:QI 1 "register_operand" "Q")))
8912           (const_int 0)))]
8913   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8914   "test{b}\t{%1, %h0|%h0, %1}"
8915   [(set_attr "type" "test")
8916    (set_attr "mode" "QI")])
8917
8918 (define_insn "*testqi_ext_2"
8919   [(set (reg FLAGS_REG)
8920         (compare
8921           (and:SI
8922             (zero_extract:SI
8923               (match_operand 0 "ext_register_operand" "Q")
8924               (const_int 8)
8925               (const_int 8))
8926             (zero_extract:SI
8927               (match_operand 1 "ext_register_operand" "Q")
8928               (const_int 8)
8929               (const_int 8)))
8930           (const_int 0)))]
8931   "ix86_match_ccmode (insn, CCNOmode)"
8932   "test{b}\t{%h1, %h0|%h0, %h1}"
8933   [(set_attr "type" "test")
8934    (set_attr "mode" "QI")])
8935
8936 ;; Combine likes to form bit extractions for some tests.  Humor it.
8937 (define_insn "*testqi_ext_3"
8938   [(set (reg FLAGS_REG)
8939         (compare (zero_extract:SI
8940                    (match_operand 0 "nonimmediate_operand" "rm")
8941                    (match_operand:SI 1 "const_int_operand" "")
8942                    (match_operand:SI 2 "const_int_operand" ""))
8943                  (const_int 0)))]
8944   "ix86_match_ccmode (insn, CCNOmode)
8945    && INTVAL (operands[1]) > 0
8946    && INTVAL (operands[2]) >= 0
8947    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8948    && (GET_MODE (operands[0]) == SImode
8949        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8950        || GET_MODE (operands[0]) == HImode
8951        || GET_MODE (operands[0]) == QImode)"
8952   "#")
8953
8954 (define_insn "*testqi_ext_3_rex64"
8955   [(set (reg FLAGS_REG)
8956         (compare (zero_extract:DI
8957                    (match_operand 0 "nonimmediate_operand" "rm")
8958                    (match_operand:DI 1 "const_int_operand" "")
8959                    (match_operand:DI 2 "const_int_operand" ""))
8960                  (const_int 0)))]
8961   "TARGET_64BIT
8962    && ix86_match_ccmode (insn, CCNOmode)
8963    && INTVAL (operands[1]) > 0
8964    && INTVAL (operands[2]) >= 0
8965    /* Ensure that resulting mask is zero or sign extended operand.  */
8966    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8967        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8968            && INTVAL (operands[1]) > 32))
8969    && (GET_MODE (operands[0]) == SImode
8970        || GET_MODE (operands[0]) == DImode
8971        || GET_MODE (operands[0]) == HImode
8972        || GET_MODE (operands[0]) == QImode)"
8973   "#")
8974
8975 (define_split
8976   [(set (match_operand 0 "flags_reg_operand" "")
8977         (match_operator 1 "compare_operator"
8978           [(zero_extract
8979              (match_operand 2 "nonimmediate_operand" "")
8980              (match_operand 3 "const_int_operand" "")
8981              (match_operand 4 "const_int_operand" ""))
8982            (const_int 0)]))]
8983   "ix86_match_ccmode (insn, CCNOmode)"
8984   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8985 {
8986   rtx val = operands[2];
8987   HOST_WIDE_INT len = INTVAL (operands[3]);
8988   HOST_WIDE_INT pos = INTVAL (operands[4]);
8989   HOST_WIDE_INT mask;
8990   enum machine_mode mode, submode;
8991
8992   mode = GET_MODE (val);
8993   if (MEM_P (val))
8994     {
8995       /* ??? Combine likes to put non-volatile mem extractions in QImode
8996          no matter the size of the test.  So find a mode that works.  */
8997       if (! MEM_VOLATILE_P (val))
8998         {
8999           mode = smallest_mode_for_size (pos + len, MODE_INT);
9000           val = adjust_address (val, mode, 0);
9001         }
9002     }
9003   else if (GET_CODE (val) == SUBREG
9004            && (submode = GET_MODE (SUBREG_REG (val)),
9005                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9006            && pos + len <= GET_MODE_BITSIZE (submode))
9007     {
9008       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9009       mode = submode;
9010       val = SUBREG_REG (val);
9011     }
9012   else if (mode == HImode && pos + len <= 8)
9013     {
9014       /* Small HImode tests can be converted to QImode.  */
9015       mode = QImode;
9016       val = gen_lowpart (QImode, val);
9017     }
9018
9019   if (len == HOST_BITS_PER_WIDE_INT)
9020     mask = -1;
9021   else
9022     mask = ((HOST_WIDE_INT)1 << len) - 1;
9023   mask <<= pos;
9024
9025   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9026 })
9027
9028 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9029 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9030 ;; this is relatively important trick.
9031 ;; Do the conversion only post-reload to avoid limiting of the register class
9032 ;; to QI regs.
9033 (define_split
9034   [(set (match_operand 0 "flags_reg_operand" "")
9035         (match_operator 1 "compare_operator"
9036           [(and (match_operand 2 "register_operand" "")
9037                 (match_operand 3 "const_int_operand" ""))
9038            (const_int 0)]))]
9039    "reload_completed
9040     && QI_REG_P (operands[2])
9041     && GET_MODE (operands[2]) != QImode
9042     && ((ix86_match_ccmode (insn, CCZmode)
9043          && !(INTVAL (operands[3]) & ~(255 << 8)))
9044         || (ix86_match_ccmode (insn, CCNOmode)
9045             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9046   [(set (match_dup 0)
9047         (match_op_dup 1
9048           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9049                    (match_dup 3))
9050            (const_int 0)]))]
9051   "operands[2] = gen_lowpart (SImode, operands[2]);
9052    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9053
9054 (define_split
9055   [(set (match_operand 0 "flags_reg_operand" "")
9056         (match_operator 1 "compare_operator"
9057           [(and (match_operand 2 "nonimmediate_operand" "")
9058                 (match_operand 3 "const_int_operand" ""))
9059            (const_int 0)]))]
9060    "reload_completed
9061     && GET_MODE (operands[2]) != QImode
9062     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9063     && ((ix86_match_ccmode (insn, CCZmode)
9064          && !(INTVAL (operands[3]) & ~255))
9065         || (ix86_match_ccmode (insn, CCNOmode)
9066             && !(INTVAL (operands[3]) & ~127)))"
9067   [(set (match_dup 0)
9068         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9069                          (const_int 0)]))]
9070   "operands[2] = gen_lowpart (QImode, operands[2]);
9071    operands[3] = gen_lowpart (QImode, operands[3]);")
9072
9073
9074 ;; %%% This used to optimize known byte-wide and operations to memory,
9075 ;; and sometimes to QImode registers.  If this is considered useful,
9076 ;; it should be done with splitters.
9077
9078 (define_expand "anddi3"
9079   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9080         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9081                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9082   "TARGET_64BIT"
9083   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9084
9085 (define_insn "*anddi_1_rex64"
9086   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9087         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9088                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9089    (clobber (reg:CC FLAGS_REG))]
9090   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9091 {
9092   switch (get_attr_type (insn))
9093     {
9094     case TYPE_IMOVX:
9095       {
9096         enum machine_mode mode;
9097
9098         gcc_assert (CONST_INT_P (operands[2]));
9099         if (INTVAL (operands[2]) == 0xff)
9100           mode = QImode;
9101         else
9102           {
9103             gcc_assert (INTVAL (operands[2]) == 0xffff);
9104             mode = HImode;
9105           }
9106
9107         operands[1] = gen_lowpart (mode, operands[1]);
9108         if (mode == QImode)
9109           return "movz{bq|x}\t{%1,%0|%0, %1}";
9110         else
9111           return "movz{wq|x}\t{%1,%0|%0, %1}";
9112       }
9113
9114     default:
9115       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9116       if (get_attr_mode (insn) == MODE_SI)
9117         return "and{l}\t{%k2, %k0|%k0, %k2}";
9118       else
9119         return "and{q}\t{%2, %0|%0, %2}";
9120     }
9121 }
9122   [(set_attr "type" "alu,alu,alu,imovx")
9123    (set_attr "length_immediate" "*,*,*,0")
9124    (set_attr "mode" "SI,DI,DI,DI")])
9125
9126 (define_insn "*anddi_2"
9127   [(set (reg FLAGS_REG)
9128         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9129                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9130                  (const_int 0)))
9131    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9132         (and:DI (match_dup 1) (match_dup 2)))]
9133   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9134    && ix86_binary_operator_ok (AND, DImode, operands)"
9135   "@
9136    and{l}\t{%k2, %k0|%k0, %k2}
9137    and{q}\t{%2, %0|%0, %2}
9138    and{q}\t{%2, %0|%0, %2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "mode" "SI,DI,DI")])
9141
9142 (define_expand "andsi3"
9143   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9144         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9145                 (match_operand:SI 2 "general_operand" "")))]
9146   ""
9147   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9148
9149 (define_insn "*andsi_1"
9150   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9151         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9152                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9153    (clobber (reg:CC FLAGS_REG))]
9154   "ix86_binary_operator_ok (AND, SImode, operands)"
9155 {
9156   switch (get_attr_type (insn))
9157     {
9158     case TYPE_IMOVX:
9159       {
9160         enum machine_mode mode;
9161
9162         gcc_assert (CONST_INT_P (operands[2]));
9163         if (INTVAL (operands[2]) == 0xff)
9164           mode = QImode;
9165         else
9166           {
9167             gcc_assert (INTVAL (operands[2]) == 0xffff);
9168             mode = HImode;
9169           }
9170
9171         operands[1] = gen_lowpart (mode, operands[1]);
9172         if (mode == QImode)
9173           return "movz{bl|x}\t{%1,%0|%0, %1}";
9174         else
9175           return "movz{wl|x}\t{%1,%0|%0, %1}";
9176       }
9177
9178     default:
9179       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9180       return "and{l}\t{%2, %0|%0, %2}";
9181     }
9182 }
9183   [(set_attr "type" "alu,alu,imovx")
9184    (set_attr "length_immediate" "*,*,0")
9185    (set_attr "mode" "SI")])
9186
9187 (define_split
9188   [(set (match_operand 0 "register_operand" "")
9189         (and (match_dup 0)
9190              (const_int -65536)))
9191    (clobber (reg:CC FLAGS_REG))]
9192   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9193   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9194   "operands[1] = gen_lowpart (HImode, operands[0]);")
9195
9196 (define_split
9197   [(set (match_operand 0 "ext_register_operand" "")
9198         (and (match_dup 0)
9199              (const_int -256)))
9200    (clobber (reg:CC FLAGS_REG))]
9201   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9202   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9203   "operands[1] = gen_lowpart (QImode, operands[0]);")
9204
9205 (define_split
9206   [(set (match_operand 0 "ext_register_operand" "")
9207         (and (match_dup 0)
9208              (const_int -65281)))
9209    (clobber (reg:CC FLAGS_REG))]
9210   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9211   [(parallel [(set (zero_extract:SI (match_dup 0)
9212                                     (const_int 8)
9213                                     (const_int 8))
9214                    (xor:SI
9215                      (zero_extract:SI (match_dup 0)
9216                                       (const_int 8)
9217                                       (const_int 8))
9218                      (zero_extract:SI (match_dup 0)
9219                                       (const_int 8)
9220                                       (const_int 8))))
9221               (clobber (reg:CC FLAGS_REG))])]
9222   "operands[0] = gen_lowpart (SImode, operands[0]);")
9223
9224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9225 (define_insn "*andsi_1_zext"
9226   [(set (match_operand:DI 0 "register_operand" "=r")
9227         (zero_extend:DI
9228           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9229                   (match_operand:SI 2 "general_operand" "g"))))
9230    (clobber (reg:CC FLAGS_REG))]
9231   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9232   "and{l}\t{%2, %k0|%k0, %2}"
9233   [(set_attr "type" "alu")
9234    (set_attr "mode" "SI")])
9235
9236 (define_insn "*andsi_2"
9237   [(set (reg FLAGS_REG)
9238         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9239                          (match_operand:SI 2 "general_operand" "g,ri"))
9240                  (const_int 0)))
9241    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9242         (and:SI (match_dup 1) (match_dup 2)))]
9243   "ix86_match_ccmode (insn, CCNOmode)
9244    && ix86_binary_operator_ok (AND, SImode, operands)"
9245   "and{l}\t{%2, %0|%0, %2}"
9246   [(set_attr "type" "alu")
9247    (set_attr "mode" "SI")])
9248
9249 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9250 (define_insn "*andsi_2_zext"
9251   [(set (reg FLAGS_REG)
9252         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9253                          (match_operand:SI 2 "general_operand" "g"))
9254                  (const_int 0)))
9255    (set (match_operand:DI 0 "register_operand" "=r")
9256         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9257   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9258    && ix86_binary_operator_ok (AND, SImode, operands)"
9259   "and{l}\t{%2, %k0|%k0, %2}"
9260   [(set_attr "type" "alu")
9261    (set_attr "mode" "SI")])
9262
9263 (define_expand "andhi3"
9264   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9265         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9266                 (match_operand:HI 2 "general_operand" "")))]
9267   "TARGET_HIMODE_MATH"
9268   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9269
9270 (define_insn "*andhi_1"
9271   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9272         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9273                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9274    (clobber (reg:CC FLAGS_REG))]
9275   "ix86_binary_operator_ok (AND, HImode, operands)"
9276 {
9277   switch (get_attr_type (insn))
9278     {
9279     case TYPE_IMOVX:
9280       gcc_assert (CONST_INT_P (operands[2]));
9281       gcc_assert (INTVAL (operands[2]) == 0xff);
9282       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9283
9284     default:
9285       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9286
9287       return "and{w}\t{%2, %0|%0, %2}";
9288     }
9289 }
9290   [(set_attr "type" "alu,alu,imovx")
9291    (set_attr "length_immediate" "*,*,0")
9292    (set_attr "mode" "HI,HI,SI")])
9293
9294 (define_insn "*andhi_2"
9295   [(set (reg FLAGS_REG)
9296         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9297                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9298                  (const_int 0)))
9299    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9300         (and:HI (match_dup 1) (match_dup 2)))]
9301   "ix86_match_ccmode (insn, CCNOmode)
9302    && ix86_binary_operator_ok (AND, HImode, operands)"
9303   "and{w}\t{%2, %0|%0, %2}"
9304   [(set_attr "type" "alu")
9305    (set_attr "mode" "HI")])
9306
9307 (define_expand "andqi3"
9308   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9309         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9310                 (match_operand:QI 2 "general_operand" "")))]
9311   "TARGET_QIMODE_MATH"
9312   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9313
9314 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9315 (define_insn "*andqi_1"
9316   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9317         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9318                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "ix86_binary_operator_ok (AND, QImode, operands)"
9321   "@
9322    and{b}\t{%2, %0|%0, %2}
9323    and{b}\t{%2, %0|%0, %2}
9324    and{l}\t{%k2, %k0|%k0, %k2}"
9325   [(set_attr "type" "alu")
9326    (set_attr "mode" "QI,QI,SI")])
9327
9328 (define_insn "*andqi_1_slp"
9329   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9330         (and:QI (match_dup 0)
9331                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9334    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9335   "and{b}\t{%1, %0|%0, %1}"
9336   [(set_attr "type" "alu1")
9337    (set_attr "mode" "QI")])
9338
9339 (define_insn "*andqi_2_maybe_si"
9340   [(set (reg FLAGS_REG)
9341         (compare (and:QI
9342                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9343                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9344                  (const_int 0)))
9345    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9346         (and:QI (match_dup 1) (match_dup 2)))]
9347   "ix86_binary_operator_ok (AND, QImode, operands)
9348    && ix86_match_ccmode (insn,
9349                          CONST_INT_P (operands[2])
9350                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9351 {
9352   if (which_alternative == 2)
9353     {
9354       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9355         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9356       return "and{l}\t{%2, %k0|%k0, %2}";
9357     }
9358   return "and{b}\t{%2, %0|%0, %2}";
9359 }
9360   [(set_attr "type" "alu")
9361    (set_attr "mode" "QI,QI,SI")])
9362
9363 (define_insn "*andqi_2"
9364   [(set (reg FLAGS_REG)
9365         (compare (and:QI
9366                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9367                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9368                  (const_int 0)))
9369    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9370         (and:QI (match_dup 1) (match_dup 2)))]
9371   "ix86_match_ccmode (insn, CCNOmode)
9372    && ix86_binary_operator_ok (AND, QImode, operands)"
9373   "and{b}\t{%2, %0|%0, %2}"
9374   [(set_attr "type" "alu")
9375    (set_attr "mode" "QI")])
9376
9377 (define_insn "*andqi_2_slp"
9378   [(set (reg FLAGS_REG)
9379         (compare (and:QI
9380                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9381                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9382                  (const_int 0)))
9383    (set (strict_low_part (match_dup 0))
9384         (and:QI (match_dup 0) (match_dup 1)))]
9385   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9386    && ix86_match_ccmode (insn, CCNOmode)
9387    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9388   "and{b}\t{%1, %0|%0, %1}"
9389   [(set_attr "type" "alu1")
9390    (set_attr "mode" "QI")])
9391
9392 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9393 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9394 ;; for a QImode operand, which of course failed.
9395
9396 (define_insn "andqi_ext_0"
9397   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9398                          (const_int 8)
9399                          (const_int 8))
9400         (and:SI
9401           (zero_extract:SI
9402             (match_operand 1 "ext_register_operand" "0")
9403             (const_int 8)
9404             (const_int 8))
9405           (match_operand 2 "const_int_operand" "n")))
9406    (clobber (reg:CC FLAGS_REG))]
9407   ""
9408   "and{b}\t{%2, %h0|%h0, %2}"
9409   [(set_attr "type" "alu")
9410    (set_attr "length_immediate" "1")
9411    (set_attr "mode" "QI")])
9412
9413 ;; Generated by peephole translating test to and.  This shows up
9414 ;; often in fp comparisons.
9415
9416 (define_insn "*andqi_ext_0_cc"
9417   [(set (reg FLAGS_REG)
9418         (compare
9419           (and:SI
9420             (zero_extract:SI
9421               (match_operand 1 "ext_register_operand" "0")
9422               (const_int 8)
9423               (const_int 8))
9424             (match_operand 2 "const_int_operand" "n"))
9425           (const_int 0)))
9426    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9427                          (const_int 8)
9428                          (const_int 8))
9429         (and:SI
9430           (zero_extract:SI
9431             (match_dup 1)
9432             (const_int 8)
9433             (const_int 8))
9434           (match_dup 2)))]
9435   "ix86_match_ccmode (insn, CCNOmode)"
9436   "and{b}\t{%2, %h0|%h0, %2}"
9437   [(set_attr "type" "alu")
9438    (set_attr "length_immediate" "1")
9439    (set_attr "mode" "QI")])
9440
9441 (define_insn "*andqi_ext_1"
9442   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9443                          (const_int 8)
9444                          (const_int 8))
9445         (and:SI
9446           (zero_extract:SI
9447             (match_operand 1 "ext_register_operand" "0")
9448             (const_int 8)
9449             (const_int 8))
9450           (zero_extend:SI
9451             (match_operand:QI 2 "general_operand" "Qm"))))
9452    (clobber (reg:CC FLAGS_REG))]
9453   "!TARGET_64BIT"
9454   "and{b}\t{%2, %h0|%h0, %2}"
9455   [(set_attr "type" "alu")
9456    (set_attr "length_immediate" "0")
9457    (set_attr "mode" "QI")])
9458
9459 (define_insn "*andqi_ext_1_rex64"
9460   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9461                          (const_int 8)
9462                          (const_int 8))
9463         (and:SI
9464           (zero_extract:SI
9465             (match_operand 1 "ext_register_operand" "0")
9466             (const_int 8)
9467             (const_int 8))
9468           (zero_extend:SI
9469             (match_operand 2 "ext_register_operand" "Q"))))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "TARGET_64BIT"
9472   "and{b}\t{%2, %h0|%h0, %2}"
9473   [(set_attr "type" "alu")
9474    (set_attr "length_immediate" "0")
9475    (set_attr "mode" "QI")])
9476
9477 (define_insn "*andqi_ext_2"
9478   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9479                          (const_int 8)
9480                          (const_int 8))
9481         (and:SI
9482           (zero_extract:SI
9483             (match_operand 1 "ext_register_operand" "%0")
9484             (const_int 8)
9485             (const_int 8))
9486           (zero_extract:SI
9487             (match_operand 2 "ext_register_operand" "Q")
9488             (const_int 8)
9489             (const_int 8))))
9490    (clobber (reg:CC FLAGS_REG))]
9491   ""
9492   "and{b}\t{%h2, %h0|%h0, %h2}"
9493   [(set_attr "type" "alu")
9494    (set_attr "length_immediate" "0")
9495    (set_attr "mode" "QI")])
9496
9497 ;; Convert wide AND instructions with immediate operand to shorter QImode
9498 ;; equivalents when possible.
9499 ;; Don't do the splitting with memory operands, since it introduces risk
9500 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9501 ;; for size, but that can (should?) be handled by generic code instead.
9502 (define_split
9503   [(set (match_operand 0 "register_operand" "")
9504         (and (match_operand 1 "register_operand" "")
9505              (match_operand 2 "const_int_operand" "")))
9506    (clobber (reg:CC FLAGS_REG))]
9507    "reload_completed
9508     && QI_REG_P (operands[0])
9509     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9510     && !(~INTVAL (operands[2]) & ~(255 << 8))
9511     && GET_MODE (operands[0]) != QImode"
9512   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9513                    (and:SI (zero_extract:SI (match_dup 1)
9514                                             (const_int 8) (const_int 8))
9515                            (match_dup 2)))
9516               (clobber (reg:CC FLAGS_REG))])]
9517   "operands[0] = gen_lowpart (SImode, operands[0]);
9518    operands[1] = gen_lowpart (SImode, operands[1]);
9519    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9520
9521 ;; Since AND can be encoded with sign extended immediate, this is only
9522 ;; profitable when 7th bit is not set.
9523 (define_split
9524   [(set (match_operand 0 "register_operand" "")
9525         (and (match_operand 1 "general_operand" "")
9526              (match_operand 2 "const_int_operand" "")))
9527    (clobber (reg:CC FLAGS_REG))]
9528    "reload_completed
9529     && ANY_QI_REG_P (operands[0])
9530     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9531     && !(~INTVAL (operands[2]) & ~255)
9532     && !(INTVAL (operands[2]) & 128)
9533     && GET_MODE (operands[0]) != QImode"
9534   [(parallel [(set (strict_low_part (match_dup 0))
9535                    (and:QI (match_dup 1)
9536                            (match_dup 2)))
9537               (clobber (reg:CC FLAGS_REG))])]
9538   "operands[0] = gen_lowpart (QImode, operands[0]);
9539    operands[1] = gen_lowpart (QImode, operands[1]);
9540    operands[2] = gen_lowpart (QImode, operands[2]);")
9541 \f
9542 ;; Logical inclusive OR instructions
9543
9544 ;; %%% This used to optimize known byte-wide and operations to memory.
9545 ;; If this is considered useful, it should be done with splitters.
9546
9547 (define_expand "iordi3"
9548   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9549         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9550                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9551   "TARGET_64BIT"
9552   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9553
9554 (define_insn "*iordi_1_rex64"
9555   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9556         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9557                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "TARGET_64BIT
9560    && ix86_binary_operator_ok (IOR, DImode, operands)"
9561   "or{q}\t{%2, %0|%0, %2}"
9562   [(set_attr "type" "alu")
9563    (set_attr "mode" "DI")])
9564
9565 (define_insn "*iordi_2_rex64"
9566   [(set (reg FLAGS_REG)
9567         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9568                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9569                  (const_int 0)))
9570    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9571         (ior:DI (match_dup 1) (match_dup 2)))]
9572   "TARGET_64BIT
9573    && ix86_match_ccmode (insn, CCNOmode)
9574    && ix86_binary_operator_ok (IOR, DImode, operands)"
9575   "or{q}\t{%2, %0|%0, %2}"
9576   [(set_attr "type" "alu")
9577    (set_attr "mode" "DI")])
9578
9579 (define_insn "*iordi_3_rex64"
9580   [(set (reg FLAGS_REG)
9581         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9582                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9583                  (const_int 0)))
9584    (clobber (match_scratch:DI 0 "=r"))]
9585   "TARGET_64BIT
9586    && ix86_match_ccmode (insn, CCNOmode)
9587    && ix86_binary_operator_ok (IOR, DImode, operands)"
9588   "or{q}\t{%2, %0|%0, %2}"
9589   [(set_attr "type" "alu")
9590    (set_attr "mode" "DI")])
9591
9592
9593 (define_expand "iorsi3"
9594   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9595         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9596                 (match_operand:SI 2 "general_operand" "")))]
9597   ""
9598   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9599
9600 (define_insn "*iorsi_1"
9601   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9602         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9603                 (match_operand:SI 2 "general_operand" "ri,g")))
9604    (clobber (reg:CC FLAGS_REG))]
9605   "ix86_binary_operator_ok (IOR, SImode, operands)"
9606   "or{l}\t{%2, %0|%0, %2}"
9607   [(set_attr "type" "alu")
9608    (set_attr "mode" "SI")])
9609
9610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9611 (define_insn "*iorsi_1_zext"
9612   [(set (match_operand:DI 0 "register_operand" "=r")
9613         (zero_extend:DI
9614           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9615                   (match_operand:SI 2 "general_operand" "g"))))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9618   "or{l}\t{%2, %k0|%k0, %2}"
9619   [(set_attr "type" "alu")
9620    (set_attr "mode" "SI")])
9621
9622 (define_insn "*iorsi_1_zext_imm"
9623   [(set (match_operand:DI 0 "register_operand" "=r")
9624         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9625                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9626    (clobber (reg:CC FLAGS_REG))]
9627   "TARGET_64BIT"
9628   "or{l}\t{%2, %k0|%k0, %2}"
9629   [(set_attr "type" "alu")
9630    (set_attr "mode" "SI")])
9631
9632 (define_insn "*iorsi_2"
9633   [(set (reg FLAGS_REG)
9634         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9635                          (match_operand:SI 2 "general_operand" "g,ri"))
9636                  (const_int 0)))
9637    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9638         (ior:SI (match_dup 1) (match_dup 2)))]
9639   "ix86_match_ccmode (insn, CCNOmode)
9640    && ix86_binary_operator_ok (IOR, SImode, operands)"
9641   "or{l}\t{%2, %0|%0, %2}"
9642   [(set_attr "type" "alu")
9643    (set_attr "mode" "SI")])
9644
9645 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9646 ;; ??? Special case for immediate operand is missing - it is tricky.
9647 (define_insn "*iorsi_2_zext"
9648   [(set (reg FLAGS_REG)
9649         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9650                          (match_operand:SI 2 "general_operand" "g"))
9651                  (const_int 0)))
9652    (set (match_operand:DI 0 "register_operand" "=r")
9653         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9654   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9655    && ix86_binary_operator_ok (IOR, SImode, operands)"
9656   "or{l}\t{%2, %k0|%k0, %2}"
9657   [(set_attr "type" "alu")
9658    (set_attr "mode" "SI")])
9659
9660 (define_insn "*iorsi_2_zext_imm"
9661   [(set (reg FLAGS_REG)
9662         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9663                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9664                  (const_int 0)))
9665    (set (match_operand:DI 0 "register_operand" "=r")
9666         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9667   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9668    && ix86_binary_operator_ok (IOR, SImode, operands)"
9669   "or{l}\t{%2, %k0|%k0, %2}"
9670   [(set_attr "type" "alu")
9671    (set_attr "mode" "SI")])
9672
9673 (define_insn "*iorsi_3"
9674   [(set (reg FLAGS_REG)
9675         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9676                          (match_operand:SI 2 "general_operand" "g"))
9677                  (const_int 0)))
9678    (clobber (match_scratch:SI 0 "=r"))]
9679   "ix86_match_ccmode (insn, CCNOmode)
9680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9681   "or{l}\t{%2, %0|%0, %2}"
9682   [(set_attr "type" "alu")
9683    (set_attr "mode" "SI")])
9684
9685 (define_expand "iorhi3"
9686   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9687         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9688                 (match_operand:HI 2 "general_operand" "")))]
9689   "TARGET_HIMODE_MATH"
9690   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9691
9692 (define_insn "*iorhi_1"
9693   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9694         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9695                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9696    (clobber (reg:CC FLAGS_REG))]
9697   "ix86_binary_operator_ok (IOR, HImode, operands)"
9698   "or{w}\t{%2, %0|%0, %2}"
9699   [(set_attr "type" "alu")
9700    (set_attr "mode" "HI")])
9701
9702 (define_insn "*iorhi_2"
9703   [(set (reg FLAGS_REG)
9704         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9705                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9706                  (const_int 0)))
9707    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9708         (ior:HI (match_dup 1) (match_dup 2)))]
9709   "ix86_match_ccmode (insn, CCNOmode)
9710    && ix86_binary_operator_ok (IOR, HImode, operands)"
9711   "or{w}\t{%2, %0|%0, %2}"
9712   [(set_attr "type" "alu")
9713    (set_attr "mode" "HI")])
9714
9715 (define_insn "*iorhi_3"
9716   [(set (reg FLAGS_REG)
9717         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9718                          (match_operand:HI 2 "general_operand" "rmn"))
9719                  (const_int 0)))
9720    (clobber (match_scratch:HI 0 "=r"))]
9721   "ix86_match_ccmode (insn, CCNOmode)
9722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9723   "or{w}\t{%2, %0|%0, %2}"
9724   [(set_attr "type" "alu")
9725    (set_attr "mode" "HI")])
9726
9727 (define_expand "iorqi3"
9728   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9729         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9730                 (match_operand:QI 2 "general_operand" "")))]
9731   "TARGET_QIMODE_MATH"
9732   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9733
9734 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9735 (define_insn "*iorqi_1"
9736   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9737         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9738                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "ix86_binary_operator_ok (IOR, QImode, operands)"
9741   "@
9742    or{b}\t{%2, %0|%0, %2}
9743    or{b}\t{%2, %0|%0, %2}
9744    or{l}\t{%k2, %k0|%k0, %k2}"
9745   [(set_attr "type" "alu")
9746    (set_attr "mode" "QI,QI,SI")])
9747
9748 (define_insn "*iorqi_1_slp"
9749   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9750         (ior:QI (match_dup 0)
9751                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9754    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9755   "or{b}\t{%1, %0|%0, %1}"
9756   [(set_attr "type" "alu1")
9757    (set_attr "mode" "QI")])
9758
9759 (define_insn "*iorqi_2"
9760   [(set (reg FLAGS_REG)
9761         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9762                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9763                  (const_int 0)))
9764    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9765         (ior:QI (match_dup 1) (match_dup 2)))]
9766   "ix86_match_ccmode (insn, CCNOmode)
9767    && ix86_binary_operator_ok (IOR, QImode, operands)"
9768   "or{b}\t{%2, %0|%0, %2}"
9769   [(set_attr "type" "alu")
9770    (set_attr "mode" "QI")])
9771
9772 (define_insn "*iorqi_2_slp"
9773   [(set (reg FLAGS_REG)
9774         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9775                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9776                  (const_int 0)))
9777    (set (strict_low_part (match_dup 0))
9778         (ior:QI (match_dup 0) (match_dup 1)))]
9779   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9780    && ix86_match_ccmode (insn, CCNOmode)
9781    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9782   "or{b}\t{%1, %0|%0, %1}"
9783   [(set_attr "type" "alu1")
9784    (set_attr "mode" "QI")])
9785
9786 (define_insn "*iorqi_3"
9787   [(set (reg FLAGS_REG)
9788         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9789                          (match_operand:QI 2 "general_operand" "qmn"))
9790                  (const_int 0)))
9791    (clobber (match_scratch:QI 0 "=q"))]
9792   "ix86_match_ccmode (insn, CCNOmode)
9793    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9794   "or{b}\t{%2, %0|%0, %2}"
9795   [(set_attr "type" "alu")
9796    (set_attr "mode" "QI")])
9797
9798 (define_insn "*iorqi_ext_0"
9799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9800                          (const_int 8)
9801                          (const_int 8))
9802         (ior:SI
9803           (zero_extract:SI
9804             (match_operand 1 "ext_register_operand" "0")
9805             (const_int 8)
9806             (const_int 8))
9807           (match_operand 2 "const_int_operand" "n")))
9808    (clobber (reg:CC FLAGS_REG))]
9809   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9810   "or{b}\t{%2, %h0|%h0, %2}"
9811   [(set_attr "type" "alu")
9812    (set_attr "length_immediate" "1")
9813    (set_attr "mode" "QI")])
9814
9815 (define_insn "*iorqi_ext_1"
9816   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9817                          (const_int 8)
9818                          (const_int 8))
9819         (ior:SI
9820           (zero_extract:SI
9821             (match_operand 1 "ext_register_operand" "0")
9822             (const_int 8)
9823             (const_int 8))
9824           (zero_extend:SI
9825             (match_operand:QI 2 "general_operand" "Qm"))))
9826    (clobber (reg:CC FLAGS_REG))]
9827   "!TARGET_64BIT
9828    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9829   "or{b}\t{%2, %h0|%h0, %2}"
9830   [(set_attr "type" "alu")
9831    (set_attr "length_immediate" "0")
9832    (set_attr "mode" "QI")])
9833
9834 (define_insn "*iorqi_ext_1_rex64"
9835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9836                          (const_int 8)
9837                          (const_int 8))
9838         (ior:SI
9839           (zero_extract:SI
9840             (match_operand 1 "ext_register_operand" "0")
9841             (const_int 8)
9842             (const_int 8))
9843           (zero_extend:SI
9844             (match_operand 2 "ext_register_operand" "Q"))))
9845    (clobber (reg:CC FLAGS_REG))]
9846   "TARGET_64BIT
9847    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9848   "or{b}\t{%2, %h0|%h0, %2}"
9849   [(set_attr "type" "alu")
9850    (set_attr "length_immediate" "0")
9851    (set_attr "mode" "QI")])
9852
9853 (define_insn "*iorqi_ext_2"
9854   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9855                          (const_int 8)
9856                          (const_int 8))
9857         (ior:SI
9858           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9859                            (const_int 8)
9860                            (const_int 8))
9861           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9862                            (const_int 8)
9863                            (const_int 8))))
9864    (clobber (reg:CC FLAGS_REG))]
9865   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9866   "ior{b}\t{%h2, %h0|%h0, %h2}"
9867   [(set_attr "type" "alu")
9868    (set_attr "length_immediate" "0")
9869    (set_attr "mode" "QI")])
9870
9871 (define_split
9872   [(set (match_operand 0 "register_operand" "")
9873         (ior (match_operand 1 "register_operand" "")
9874              (match_operand 2 "const_int_operand" "")))
9875    (clobber (reg:CC FLAGS_REG))]
9876    "reload_completed
9877     && QI_REG_P (operands[0])
9878     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9879     && !(INTVAL (operands[2]) & ~(255 << 8))
9880     && GET_MODE (operands[0]) != QImode"
9881   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9882                    (ior:SI (zero_extract:SI (match_dup 1)
9883                                             (const_int 8) (const_int 8))
9884                            (match_dup 2)))
9885               (clobber (reg:CC FLAGS_REG))])]
9886   "operands[0] = gen_lowpart (SImode, operands[0]);
9887    operands[1] = gen_lowpart (SImode, operands[1]);
9888    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9889
9890 ;; Since OR can be encoded with sign extended immediate, this is only
9891 ;; profitable when 7th bit is set.
9892 (define_split
9893   [(set (match_operand 0 "register_operand" "")
9894         (ior (match_operand 1 "general_operand" "")
9895              (match_operand 2 "const_int_operand" "")))
9896    (clobber (reg:CC FLAGS_REG))]
9897    "reload_completed
9898     && ANY_QI_REG_P (operands[0])
9899     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9900     && !(INTVAL (operands[2]) & ~255)
9901     && (INTVAL (operands[2]) & 128)
9902     && GET_MODE (operands[0]) != QImode"
9903   [(parallel [(set (strict_low_part (match_dup 0))
9904                    (ior:QI (match_dup 1)
9905                            (match_dup 2)))
9906               (clobber (reg:CC FLAGS_REG))])]
9907   "operands[0] = gen_lowpart (QImode, operands[0]);
9908    operands[1] = gen_lowpart (QImode, operands[1]);
9909    operands[2] = gen_lowpart (QImode, operands[2]);")
9910 \f
9911 ;; Logical XOR instructions
9912
9913 ;; %%% This used to optimize known byte-wide and operations to memory.
9914 ;; If this is considered useful, it should be done with splitters.
9915
9916 (define_expand "xordi3"
9917   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9918         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9919                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9920   "TARGET_64BIT"
9921   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9922
9923 (define_insn "*xordi_1_rex64"
9924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9925         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9926                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9927    (clobber (reg:CC FLAGS_REG))]
9928   "TARGET_64BIT
9929    && ix86_binary_operator_ok (XOR, DImode, operands)"
9930   "xor{q}\t{%2, %0|%0, %2}"
9931   [(set_attr "type" "alu")
9932    (set_attr "mode" "DI")])
9933
9934 (define_insn "*xordi_2_rex64"
9935   [(set (reg FLAGS_REG)
9936         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9937                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9938                  (const_int 0)))
9939    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9940         (xor:DI (match_dup 1) (match_dup 2)))]
9941   "TARGET_64BIT
9942    && ix86_match_ccmode (insn, CCNOmode)
9943    && ix86_binary_operator_ok (XOR, DImode, operands)"
9944   "xor{q}\t{%2, %0|%0, %2}"
9945   [(set_attr "type" "alu")
9946    (set_attr "mode" "DI")])
9947
9948 (define_insn "*xordi_3_rex64"
9949   [(set (reg FLAGS_REG)
9950         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9951                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9952                  (const_int 0)))
9953    (clobber (match_scratch:DI 0 "=r"))]
9954   "TARGET_64BIT
9955    && ix86_match_ccmode (insn, CCNOmode)
9956    && ix86_binary_operator_ok (XOR, DImode, operands)"
9957   "xor{q}\t{%2, %0|%0, %2}"
9958   [(set_attr "type" "alu")
9959    (set_attr "mode" "DI")])
9960
9961 (define_expand "xorsi3"
9962   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9963         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9964                 (match_operand:SI 2 "general_operand" "")))]
9965   ""
9966   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9967
9968 (define_insn "*xorsi_1"
9969   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9970         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9971                 (match_operand:SI 2 "general_operand" "ri,rm")))
9972    (clobber (reg:CC FLAGS_REG))]
9973   "ix86_binary_operator_ok (XOR, SImode, operands)"
9974   "xor{l}\t{%2, %0|%0, %2}"
9975   [(set_attr "type" "alu")
9976    (set_attr "mode" "SI")])
9977
9978 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9979 ;; Add speccase for immediates
9980 (define_insn "*xorsi_1_zext"
9981   [(set (match_operand:DI 0 "register_operand" "=r")
9982         (zero_extend:DI
9983           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9984                   (match_operand:SI 2 "general_operand" "g"))))
9985    (clobber (reg:CC FLAGS_REG))]
9986   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9987   "xor{l}\t{%2, %k0|%k0, %2}"
9988   [(set_attr "type" "alu")
9989    (set_attr "mode" "SI")])
9990
9991 (define_insn "*xorsi_1_zext_imm"
9992   [(set (match_operand:DI 0 "register_operand" "=r")
9993         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9994                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9995    (clobber (reg:CC FLAGS_REG))]
9996   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9997   "xor{l}\t{%2, %k0|%k0, %2}"
9998   [(set_attr "type" "alu")
9999    (set_attr "mode" "SI")])
10000
10001 (define_insn "*xorsi_2"
10002   [(set (reg FLAGS_REG)
10003         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10004                          (match_operand:SI 2 "general_operand" "g,ri"))
10005                  (const_int 0)))
10006    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10007         (xor:SI (match_dup 1) (match_dup 2)))]
10008   "ix86_match_ccmode (insn, CCNOmode)
10009    && ix86_binary_operator_ok (XOR, SImode, operands)"
10010   "xor{l}\t{%2, %0|%0, %2}"
10011   [(set_attr "type" "alu")
10012    (set_attr "mode" "SI")])
10013
10014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10015 ;; ??? Special case for immediate operand is missing - it is tricky.
10016 (define_insn "*xorsi_2_zext"
10017   [(set (reg FLAGS_REG)
10018         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10019                          (match_operand:SI 2 "general_operand" "g"))
10020                  (const_int 0)))
10021    (set (match_operand:DI 0 "register_operand" "=r")
10022         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10023   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10024    && ix86_binary_operator_ok (XOR, SImode, operands)"
10025   "xor{l}\t{%2, %k0|%k0, %2}"
10026   [(set_attr "type" "alu")
10027    (set_attr "mode" "SI")])
10028
10029 (define_insn "*xorsi_2_zext_imm"
10030   [(set (reg FLAGS_REG)
10031         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10032                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10033                  (const_int 0)))
10034    (set (match_operand:DI 0 "register_operand" "=r")
10035         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10036   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10037    && ix86_binary_operator_ok (XOR, SImode, operands)"
10038   "xor{l}\t{%2, %k0|%k0, %2}"
10039   [(set_attr "type" "alu")
10040    (set_attr "mode" "SI")])
10041
10042 (define_insn "*xorsi_3"
10043   [(set (reg FLAGS_REG)
10044         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10045                          (match_operand:SI 2 "general_operand" "g"))
10046                  (const_int 0)))
10047    (clobber (match_scratch:SI 0 "=r"))]
10048   "ix86_match_ccmode (insn, CCNOmode)
10049    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10050   "xor{l}\t{%2, %0|%0, %2}"
10051   [(set_attr "type" "alu")
10052    (set_attr "mode" "SI")])
10053
10054 (define_expand "xorhi3"
10055   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10056         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10057                 (match_operand:HI 2 "general_operand" "")))]
10058   "TARGET_HIMODE_MATH"
10059   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10060
10061 (define_insn "*xorhi_1"
10062   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10063         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10064                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10065    (clobber (reg:CC FLAGS_REG))]
10066   "ix86_binary_operator_ok (XOR, HImode, operands)"
10067   "xor{w}\t{%2, %0|%0, %2}"
10068   [(set_attr "type" "alu")
10069    (set_attr "mode" "HI")])
10070
10071 (define_insn "*xorhi_2"
10072   [(set (reg FLAGS_REG)
10073         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10074                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10075                  (const_int 0)))
10076    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10077         (xor:HI (match_dup 1) (match_dup 2)))]
10078   "ix86_match_ccmode (insn, CCNOmode)
10079    && ix86_binary_operator_ok (XOR, HImode, operands)"
10080   "xor{w}\t{%2, %0|%0, %2}"
10081   [(set_attr "type" "alu")
10082    (set_attr "mode" "HI")])
10083
10084 (define_insn "*xorhi_3"
10085   [(set (reg FLAGS_REG)
10086         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10087                          (match_operand:HI 2 "general_operand" "rmn"))
10088                  (const_int 0)))
10089    (clobber (match_scratch:HI 0 "=r"))]
10090   "ix86_match_ccmode (insn, CCNOmode)
10091    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10092   "xor{w}\t{%2, %0|%0, %2}"
10093   [(set_attr "type" "alu")
10094    (set_attr "mode" "HI")])
10095
10096 (define_expand "xorqi3"
10097   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10098         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10099                 (match_operand:QI 2 "general_operand" "")))]
10100   "TARGET_QIMODE_MATH"
10101   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10102
10103 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10104 (define_insn "*xorqi_1"
10105   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10106         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10107                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10108    (clobber (reg:CC FLAGS_REG))]
10109   "ix86_binary_operator_ok (XOR, QImode, operands)"
10110   "@
10111    xor{b}\t{%2, %0|%0, %2}
10112    xor{b}\t{%2, %0|%0, %2}
10113    xor{l}\t{%k2, %k0|%k0, %k2}"
10114   [(set_attr "type" "alu")
10115    (set_attr "mode" "QI,QI,SI")])
10116
10117 (define_insn "*xorqi_1_slp"
10118   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10119         (xor:QI (match_dup 0)
10120                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10121    (clobber (reg:CC FLAGS_REG))]
10122   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10123    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10124   "xor{b}\t{%1, %0|%0, %1}"
10125   [(set_attr "type" "alu1")
10126    (set_attr "mode" "QI")])
10127
10128 (define_insn "*xorqi_ext_0"
10129   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10130                          (const_int 8)
10131                          (const_int 8))
10132         (xor:SI
10133           (zero_extract:SI
10134             (match_operand 1 "ext_register_operand" "0")
10135             (const_int 8)
10136             (const_int 8))
10137           (match_operand 2 "const_int_operand" "n")))
10138    (clobber (reg:CC FLAGS_REG))]
10139   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10140   "xor{b}\t{%2, %h0|%h0, %2}"
10141   [(set_attr "type" "alu")
10142    (set_attr "length_immediate" "1")
10143    (set_attr "mode" "QI")])
10144
10145 (define_insn "*xorqi_ext_1"
10146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10147                          (const_int 8)
10148                          (const_int 8))
10149         (xor:SI
10150           (zero_extract:SI
10151             (match_operand 1 "ext_register_operand" "0")
10152             (const_int 8)
10153             (const_int 8))
10154           (zero_extend:SI
10155             (match_operand:QI 2 "general_operand" "Qm"))))
10156    (clobber (reg:CC FLAGS_REG))]
10157   "!TARGET_64BIT
10158    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10159   "xor{b}\t{%2, %h0|%h0, %2}"
10160   [(set_attr "type" "alu")
10161    (set_attr "length_immediate" "0")
10162    (set_attr "mode" "QI")])
10163
10164 (define_insn "*xorqi_ext_1_rex64"
10165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10166                          (const_int 8)
10167                          (const_int 8))
10168         (xor:SI
10169           (zero_extract:SI
10170             (match_operand 1 "ext_register_operand" "0")
10171             (const_int 8)
10172             (const_int 8))
10173           (zero_extend:SI
10174             (match_operand 2 "ext_register_operand" "Q"))))
10175    (clobber (reg:CC FLAGS_REG))]
10176   "TARGET_64BIT
10177    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10178   "xor{b}\t{%2, %h0|%h0, %2}"
10179   [(set_attr "type" "alu")
10180    (set_attr "length_immediate" "0")
10181    (set_attr "mode" "QI")])
10182
10183 (define_insn "*xorqi_ext_2"
10184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10185                          (const_int 8)
10186                          (const_int 8))
10187         (xor:SI
10188           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10189                            (const_int 8)
10190                            (const_int 8))
10191           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10192                            (const_int 8)
10193                            (const_int 8))))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10196   "xor{b}\t{%h2, %h0|%h0, %h2}"
10197   [(set_attr "type" "alu")
10198    (set_attr "length_immediate" "0")
10199    (set_attr "mode" "QI")])
10200
10201 (define_insn "*xorqi_cc_1"
10202   [(set (reg FLAGS_REG)
10203         (compare
10204           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10205                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10206           (const_int 0)))
10207    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10208         (xor:QI (match_dup 1) (match_dup 2)))]
10209   "ix86_match_ccmode (insn, CCNOmode)
10210    && ix86_binary_operator_ok (XOR, QImode, operands)"
10211   "xor{b}\t{%2, %0|%0, %2}"
10212   [(set_attr "type" "alu")
10213    (set_attr "mode" "QI")])
10214
10215 (define_insn "*xorqi_2_slp"
10216   [(set (reg FLAGS_REG)
10217         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10218                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10219                  (const_int 0)))
10220    (set (strict_low_part (match_dup 0))
10221         (xor:QI (match_dup 0) (match_dup 1)))]
10222   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10223    && ix86_match_ccmode (insn, CCNOmode)
10224    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10225   "xor{b}\t{%1, %0|%0, %1}"
10226   [(set_attr "type" "alu1")
10227    (set_attr "mode" "QI")])
10228
10229 (define_insn "*xorqi_cc_2"
10230   [(set (reg FLAGS_REG)
10231         (compare
10232           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10233                   (match_operand:QI 2 "general_operand" "qmn"))
10234           (const_int 0)))
10235    (clobber (match_scratch:QI 0 "=q"))]
10236   "ix86_match_ccmode (insn, CCNOmode)
10237    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10238   "xor{b}\t{%2, %0|%0, %2}"
10239   [(set_attr "type" "alu")
10240    (set_attr "mode" "QI")])
10241
10242 (define_insn "*xorqi_cc_ext_1"
10243   [(set (reg FLAGS_REG)
10244         (compare
10245           (xor:SI
10246             (zero_extract:SI
10247               (match_operand 1 "ext_register_operand" "0")
10248               (const_int 8)
10249               (const_int 8))
10250             (match_operand:QI 2 "general_operand" "qmn"))
10251           (const_int 0)))
10252    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10253                          (const_int 8)
10254                          (const_int 8))
10255         (xor:SI
10256           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10257           (match_dup 2)))]
10258   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10259   "xor{b}\t{%2, %h0|%h0, %2}"
10260   [(set_attr "type" "alu")
10261    (set_attr "mode" "QI")])
10262
10263 (define_insn "*xorqi_cc_ext_1_rex64"
10264   [(set (reg FLAGS_REG)
10265         (compare
10266           (xor:SI
10267             (zero_extract:SI
10268               (match_operand 1 "ext_register_operand" "0")
10269               (const_int 8)
10270               (const_int 8))
10271             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10272           (const_int 0)))
10273    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10274                          (const_int 8)
10275                          (const_int 8))
10276         (xor:SI
10277           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10278           (match_dup 2)))]
10279   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10280   "xor{b}\t{%2, %h0|%h0, %2}"
10281   [(set_attr "type" "alu")
10282    (set_attr "mode" "QI")])
10283
10284 (define_expand "xorqi_cc_ext_1"
10285   [(parallel [
10286      (set (reg:CCNO FLAGS_REG)
10287           (compare:CCNO
10288             (xor:SI
10289               (zero_extract:SI
10290                 (match_operand 1 "ext_register_operand" "")
10291                 (const_int 8)
10292                 (const_int 8))
10293               (match_operand:QI 2 "general_operand" ""))
10294             (const_int 0)))
10295      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10296                            (const_int 8)
10297                            (const_int 8))
10298           (xor:SI
10299             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10300             (match_dup 2)))])]
10301   ""
10302   "")
10303
10304 (define_split
10305   [(set (match_operand 0 "register_operand" "")
10306         (xor (match_operand 1 "register_operand" "")
10307              (match_operand 2 "const_int_operand" "")))
10308    (clobber (reg:CC FLAGS_REG))]
10309    "reload_completed
10310     && QI_REG_P (operands[0])
10311     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10312     && !(INTVAL (operands[2]) & ~(255 << 8))
10313     && GET_MODE (operands[0]) != QImode"
10314   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10315                    (xor:SI (zero_extract:SI (match_dup 1)
10316                                             (const_int 8) (const_int 8))
10317                            (match_dup 2)))
10318               (clobber (reg:CC FLAGS_REG))])]
10319   "operands[0] = gen_lowpart (SImode, operands[0]);
10320    operands[1] = gen_lowpart (SImode, operands[1]);
10321    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10322
10323 ;; Since XOR can be encoded with sign extended immediate, this is only
10324 ;; profitable when 7th bit is set.
10325 (define_split
10326   [(set (match_operand 0 "register_operand" "")
10327         (xor (match_operand 1 "general_operand" "")
10328              (match_operand 2 "const_int_operand" "")))
10329    (clobber (reg:CC FLAGS_REG))]
10330    "reload_completed
10331     && ANY_QI_REG_P (operands[0])
10332     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10333     && !(INTVAL (operands[2]) & ~255)
10334     && (INTVAL (operands[2]) & 128)
10335     && GET_MODE (operands[0]) != QImode"
10336   [(parallel [(set (strict_low_part (match_dup 0))
10337                    (xor:QI (match_dup 1)
10338                            (match_dup 2)))
10339               (clobber (reg:CC FLAGS_REG))])]
10340   "operands[0] = gen_lowpart (QImode, operands[0]);
10341    operands[1] = gen_lowpart (QImode, operands[1]);
10342    operands[2] = gen_lowpart (QImode, operands[2]);")
10343 \f
10344 ;; Negation instructions
10345
10346 (define_expand "negti2"
10347   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10348         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10349   "TARGET_64BIT"
10350   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10351
10352 (define_insn "*negti2_1"
10353   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10354         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10355    (clobber (reg:CC FLAGS_REG))]
10356   "TARGET_64BIT
10357    && ix86_unary_operator_ok (NEG, TImode, operands)"
10358   "#")
10359
10360 (define_split
10361   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10362         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10363    (clobber (reg:CC FLAGS_REG))]
10364   "TARGET_64BIT && reload_completed"
10365   [(parallel
10366     [(set (reg:CCZ FLAGS_REG)
10367           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10368      (set (match_dup 0) (neg:DI (match_dup 1)))])
10369    (parallel
10370     [(set (match_dup 2)
10371           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10372                             (match_dup 3))
10373                    (const_int 0)))
10374      (clobber (reg:CC FLAGS_REG))])
10375    (parallel
10376     [(set (match_dup 2)
10377           (neg:DI (match_dup 2)))
10378      (clobber (reg:CC FLAGS_REG))])]
10379   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10380
10381 (define_expand "negdi2"
10382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10384   ""
10385   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10386
10387 (define_insn "*negdi2_1"
10388   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10389         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "!TARGET_64BIT
10392    && ix86_unary_operator_ok (NEG, DImode, operands)"
10393   "#")
10394
10395 (define_split
10396   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10397         (neg:DI (match_operand:DI 1 "general_operand" "")))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "!TARGET_64BIT && reload_completed"
10400   [(parallel
10401     [(set (reg:CCZ FLAGS_REG)
10402           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10403      (set (match_dup 0) (neg:SI (match_dup 1)))])
10404    (parallel
10405     [(set (match_dup 2)
10406           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10407                             (match_dup 3))
10408                    (const_int 0)))
10409      (clobber (reg:CC FLAGS_REG))])
10410    (parallel
10411     [(set (match_dup 2)
10412           (neg:SI (match_dup 2)))
10413      (clobber (reg:CC FLAGS_REG))])]
10414   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10415
10416 (define_insn "*negdi2_1_rex64"
10417   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10418         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10421   "neg{q}\t%0"
10422   [(set_attr "type" "negnot")
10423    (set_attr "mode" "DI")])
10424
10425 ;; The problem with neg is that it does not perform (compare x 0),
10426 ;; it really performs (compare 0 x), which leaves us with the zero
10427 ;; flag being the only useful item.
10428
10429 (define_insn "*negdi2_cmpz_rex64"
10430   [(set (reg:CCZ FLAGS_REG)
10431         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10432                      (const_int 0)))
10433    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434         (neg:DI (match_dup 1)))]
10435   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10436   "neg{q}\t%0"
10437   [(set_attr "type" "negnot")
10438    (set_attr "mode" "DI")])
10439
10440
10441 (define_expand "negsi2"
10442   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10443         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10444   ""
10445   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10446
10447 (define_insn "*negsi2_1"
10448   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10449         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10450    (clobber (reg:CC FLAGS_REG))]
10451   "ix86_unary_operator_ok (NEG, SImode, operands)"
10452   "neg{l}\t%0"
10453   [(set_attr "type" "negnot")
10454    (set_attr "mode" "SI")])
10455
10456 ;; Combine is quite creative about this pattern.
10457 (define_insn "*negsi2_1_zext"
10458   [(set (match_operand:DI 0 "register_operand" "=r")
10459         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10460                                         (const_int 32)))
10461                      (const_int 32)))
10462    (clobber (reg:CC FLAGS_REG))]
10463   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10464   "neg{l}\t%k0"
10465   [(set_attr "type" "negnot")
10466    (set_attr "mode" "SI")])
10467
10468 ;; The problem with neg is that it does not perform (compare x 0),
10469 ;; it really performs (compare 0 x), which leaves us with the zero
10470 ;; flag being the only useful item.
10471
10472 (define_insn "*negsi2_cmpz"
10473   [(set (reg:CCZ FLAGS_REG)
10474         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10475                      (const_int 0)))
10476    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10477         (neg:SI (match_dup 1)))]
10478   "ix86_unary_operator_ok (NEG, SImode, operands)"
10479   "neg{l}\t%0"
10480   [(set_attr "type" "negnot")
10481    (set_attr "mode" "SI")])
10482
10483 (define_insn "*negsi2_cmpz_zext"
10484   [(set (reg:CCZ FLAGS_REG)
10485         (compare:CCZ (lshiftrt:DI
10486                        (neg:DI (ashift:DI
10487                                  (match_operand:DI 1 "register_operand" "0")
10488                                  (const_int 32)))
10489                        (const_int 32))
10490                      (const_int 0)))
10491    (set (match_operand:DI 0 "register_operand" "=r")
10492         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10493                                         (const_int 32)))
10494                      (const_int 32)))]
10495   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10496   "neg{l}\t%k0"
10497   [(set_attr "type" "negnot")
10498    (set_attr "mode" "SI")])
10499
10500 (define_expand "neghi2"
10501   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10502         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10503   "TARGET_HIMODE_MATH"
10504   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10505
10506 (define_insn "*neghi2_1"
10507   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10508         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10509    (clobber (reg:CC FLAGS_REG))]
10510   "ix86_unary_operator_ok (NEG, HImode, operands)"
10511   "neg{w}\t%0"
10512   [(set_attr "type" "negnot")
10513    (set_attr "mode" "HI")])
10514
10515 (define_insn "*neghi2_cmpz"
10516   [(set (reg:CCZ FLAGS_REG)
10517         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10518                      (const_int 0)))
10519    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520         (neg:HI (match_dup 1)))]
10521   "ix86_unary_operator_ok (NEG, HImode, operands)"
10522   "neg{w}\t%0"
10523   [(set_attr "type" "negnot")
10524    (set_attr "mode" "HI")])
10525
10526 (define_expand "negqi2"
10527   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10528         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10529   "TARGET_QIMODE_MATH"
10530   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10531
10532 (define_insn "*negqi2_1"
10533   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10534         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10535    (clobber (reg:CC FLAGS_REG))]
10536   "ix86_unary_operator_ok (NEG, QImode, operands)"
10537   "neg{b}\t%0"
10538   [(set_attr "type" "negnot")
10539    (set_attr "mode" "QI")])
10540
10541 (define_insn "*negqi2_cmpz"
10542   [(set (reg:CCZ FLAGS_REG)
10543         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10544                      (const_int 0)))
10545    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10546         (neg:QI (match_dup 1)))]
10547   "ix86_unary_operator_ok (NEG, QImode, operands)"
10548   "neg{b}\t%0"
10549   [(set_attr "type" "negnot")
10550    (set_attr "mode" "QI")])
10551
10552 ;; Changing of sign for FP values is doable using integer unit too.
10553
10554 (define_expand "<code><mode>2"
10555   [(set (match_operand:X87MODEF 0 "register_operand" "")
10556         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10557   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10558   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10559
10560 (define_insn "*absneg<mode>2_mixed"
10561   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10562         (match_operator:MODEF 3 "absneg_operator"
10563           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10564    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10565    (clobber (reg:CC FLAGS_REG))]
10566   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10567   "#")
10568
10569 (define_insn "*absneg<mode>2_sse"
10570   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10571         (match_operator:MODEF 3 "absneg_operator"
10572           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10573    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10574    (clobber (reg:CC FLAGS_REG))]
10575   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10576   "#")
10577
10578 (define_insn "*absneg<mode>2_i387"
10579   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10580         (match_operator:X87MODEF 3 "absneg_operator"
10581           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10582    (use (match_operand 2 "" ""))
10583    (clobber (reg:CC FLAGS_REG))]
10584   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10585   "#")
10586
10587 (define_expand "<code>tf2"
10588   [(set (match_operand:TF 0 "register_operand" "")
10589         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10590   "TARGET_SSE2"
10591   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10592
10593 (define_insn "*absnegtf2_sse"
10594   [(set (match_operand:TF 0 "register_operand" "=x,x")
10595         (match_operator:TF 3 "absneg_operator"
10596           [(match_operand:TF 1 "register_operand" "0,x")]))
10597    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10598    (clobber (reg:CC FLAGS_REG))]
10599   "TARGET_SSE2"
10600   "#")
10601
10602 ;; Splitters for fp abs and neg.
10603
10604 (define_split
10605   [(set (match_operand 0 "fp_register_operand" "")
10606         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10607    (use (match_operand 2 "" ""))
10608    (clobber (reg:CC FLAGS_REG))]
10609   "reload_completed"
10610   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10611
10612 (define_split
10613   [(set (match_operand 0 "register_operand" "")
10614         (match_operator 3 "absneg_operator"
10615           [(match_operand 1 "register_operand" "")]))
10616    (use (match_operand 2 "nonimmediate_operand" ""))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "reload_completed && SSE_REG_P (operands[0])"
10619   [(set (match_dup 0) (match_dup 3))]
10620 {
10621   enum machine_mode mode = GET_MODE (operands[0]);
10622   enum machine_mode vmode = GET_MODE (operands[2]);
10623   rtx tmp;
10624
10625   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10626   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10627   if (operands_match_p (operands[0], operands[2]))
10628     {
10629       tmp = operands[1];
10630       operands[1] = operands[2];
10631       operands[2] = tmp;
10632     }
10633   if (GET_CODE (operands[3]) == ABS)
10634     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10635   else
10636     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10637   operands[3] = tmp;
10638 })
10639
10640 (define_split
10641   [(set (match_operand:SF 0 "register_operand" "")
10642         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10643    (use (match_operand:V4SF 2 "" ""))
10644    (clobber (reg:CC FLAGS_REG))]
10645   "reload_completed"
10646   [(parallel [(set (match_dup 0) (match_dup 1))
10647               (clobber (reg:CC FLAGS_REG))])]
10648 {
10649   rtx tmp;
10650   operands[0] = gen_lowpart (SImode, operands[0]);
10651   if (GET_CODE (operands[1]) == ABS)
10652     {
10653       tmp = gen_int_mode (0x7fffffff, SImode);
10654       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10655     }
10656   else
10657     {
10658       tmp = gen_int_mode (0x80000000, SImode);
10659       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10660     }
10661   operands[1] = tmp;
10662 })
10663
10664 (define_split
10665   [(set (match_operand:DF 0 "register_operand" "")
10666         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10667    (use (match_operand 2 "" ""))
10668    (clobber (reg:CC FLAGS_REG))]
10669   "reload_completed"
10670   [(parallel [(set (match_dup 0) (match_dup 1))
10671               (clobber (reg:CC FLAGS_REG))])]
10672 {
10673   rtx tmp;
10674   if (TARGET_64BIT)
10675     {
10676       tmp = gen_lowpart (DImode, operands[0]);
10677       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10678       operands[0] = tmp;
10679
10680       if (GET_CODE (operands[1]) == ABS)
10681         tmp = const0_rtx;
10682       else
10683         tmp = gen_rtx_NOT (DImode, tmp);
10684     }
10685   else
10686     {
10687       operands[0] = gen_highpart (SImode, operands[0]);
10688       if (GET_CODE (operands[1]) == ABS)
10689         {
10690           tmp = gen_int_mode (0x7fffffff, SImode);
10691           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10692         }
10693       else
10694         {
10695           tmp = gen_int_mode (0x80000000, SImode);
10696           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10697         }
10698     }
10699   operands[1] = tmp;
10700 })
10701
10702 (define_split
10703   [(set (match_operand:XF 0 "register_operand" "")
10704         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10705    (use (match_operand 2 "" ""))
10706    (clobber (reg:CC FLAGS_REG))]
10707   "reload_completed"
10708   [(parallel [(set (match_dup 0) (match_dup 1))
10709               (clobber (reg:CC FLAGS_REG))])]
10710 {
10711   rtx tmp;
10712   operands[0] = gen_rtx_REG (SImode,
10713                              true_regnum (operands[0])
10714                              + (TARGET_64BIT ? 1 : 2));
10715   if (GET_CODE (operands[1]) == ABS)
10716     {
10717       tmp = GEN_INT (0x7fff);
10718       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10719     }
10720   else
10721     {
10722       tmp = GEN_INT (0x8000);
10723       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10724     }
10725   operands[1] = tmp;
10726 })
10727
10728 ;; Conditionalize these after reload. If they match before reload, we
10729 ;; lose the clobber and ability to use integer instructions.
10730
10731 (define_insn "*<code><mode>2_1"
10732   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10733         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10734   "TARGET_80387
10735    && (reload_completed
10736        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10737   "f<absnegprefix>"
10738   [(set_attr "type" "fsgn")
10739    (set_attr "mode" "<MODE>")])
10740
10741 (define_insn "*<code>extendsfdf2"
10742   [(set (match_operand:DF 0 "register_operand" "=f")
10743         (absneg:DF (float_extend:DF
10744                      (match_operand:SF 1 "register_operand" "0"))))]
10745   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10746   "f<absnegprefix>"
10747   [(set_attr "type" "fsgn")
10748    (set_attr "mode" "DF")])
10749
10750 (define_insn "*<code>extendsfxf2"
10751   [(set (match_operand:XF 0 "register_operand" "=f")
10752         (absneg:XF (float_extend:XF
10753                      (match_operand:SF 1 "register_operand" "0"))))]
10754   "TARGET_80387"
10755   "f<absnegprefix>"
10756   [(set_attr "type" "fsgn")
10757    (set_attr "mode" "XF")])
10758
10759 (define_insn "*<code>extenddfxf2"
10760   [(set (match_operand:XF 0 "register_operand" "=f")
10761         (absneg:XF (float_extend:XF
10762                       (match_operand:DF 1 "register_operand" "0"))))]
10763   "TARGET_80387"
10764   "f<absnegprefix>"
10765   [(set_attr "type" "fsgn")
10766    (set_attr "mode" "XF")])
10767
10768 ;; Copysign instructions
10769
10770 (define_mode_iterator CSGNMODE [SF DF TF])
10771 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10772
10773 (define_expand "copysign<mode>3"
10774   [(match_operand:CSGNMODE 0 "register_operand" "")
10775    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10776    (match_operand:CSGNMODE 2 "register_operand" "")]
10777   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10778    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10779 {
10780   ix86_expand_copysign (operands);
10781   DONE;
10782 })
10783
10784 (define_insn_and_split "copysign<mode>3_const"
10785   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10786         (unspec:CSGNMODE
10787           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10788            (match_operand:CSGNMODE 2 "register_operand" "0")
10789            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10790           UNSPEC_COPYSIGN))]
10791   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10792    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10793   "#"
10794   "&& reload_completed"
10795   [(const_int 0)]
10796 {
10797   ix86_split_copysign_const (operands);
10798   DONE;
10799 })
10800
10801 (define_insn "copysign<mode>3_var"
10802   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10803         (unspec:CSGNMODE
10804           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10805            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10806            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10807            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10808           UNSPEC_COPYSIGN))
10809    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10810   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10811    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10812   "#")
10813
10814 (define_split
10815   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10816         (unspec:CSGNMODE
10817           [(match_operand:CSGNMODE 2 "register_operand" "")
10818            (match_operand:CSGNMODE 3 "register_operand" "")
10819            (match_operand:<CSGNVMODE> 4 "" "")
10820            (match_operand:<CSGNVMODE> 5 "" "")]
10821           UNSPEC_COPYSIGN))
10822    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10823   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10824     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10825    && reload_completed"
10826   [(const_int 0)]
10827 {
10828   ix86_split_copysign_var (operands);
10829   DONE;
10830 })
10831 \f
10832 ;; One complement instructions
10833
10834 (define_expand "one_cmpldi2"
10835   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10836         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10837   "TARGET_64BIT"
10838   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10839
10840 (define_insn "*one_cmpldi2_1_rex64"
10841   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10842         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10843   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10844   "not{q}\t%0"
10845   [(set_attr "type" "negnot")
10846    (set_attr "mode" "DI")])
10847
10848 (define_insn "*one_cmpldi2_2_rex64"
10849   [(set (reg FLAGS_REG)
10850         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10851                  (const_int 0)))
10852    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10853         (not:DI (match_dup 1)))]
10854   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10855    && ix86_unary_operator_ok (NOT, DImode, operands)"
10856   "#"
10857   [(set_attr "type" "alu1")
10858    (set_attr "mode" "DI")])
10859
10860 (define_split
10861   [(set (match_operand 0 "flags_reg_operand" "")
10862         (match_operator 2 "compare_operator"
10863           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10864            (const_int 0)]))
10865    (set (match_operand:DI 1 "nonimmediate_operand" "")
10866         (not:DI (match_dup 3)))]
10867   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10868   [(parallel [(set (match_dup 0)
10869                    (match_op_dup 2
10870                      [(xor:DI (match_dup 3) (const_int -1))
10871                       (const_int 0)]))
10872               (set (match_dup 1)
10873                    (xor:DI (match_dup 3) (const_int -1)))])]
10874   "")
10875
10876 (define_expand "one_cmplsi2"
10877   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10878         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10879   ""
10880   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10881
10882 (define_insn "*one_cmplsi2_1"
10883   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10884         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10885   "ix86_unary_operator_ok (NOT, SImode, operands)"
10886   "not{l}\t%0"
10887   [(set_attr "type" "negnot")
10888    (set_attr "mode" "SI")])
10889
10890 ;; ??? Currently never generated - xor is used instead.
10891 (define_insn "*one_cmplsi2_1_zext"
10892   [(set (match_operand:DI 0 "register_operand" "=r")
10893         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10894   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10895   "not{l}\t%k0"
10896   [(set_attr "type" "negnot")
10897    (set_attr "mode" "SI")])
10898
10899 (define_insn "*one_cmplsi2_2"
10900   [(set (reg FLAGS_REG)
10901         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10902                  (const_int 0)))
10903    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10904         (not:SI (match_dup 1)))]
10905   "ix86_match_ccmode (insn, CCNOmode)
10906    && ix86_unary_operator_ok (NOT, SImode, operands)"
10907   "#"
10908   [(set_attr "type" "alu1")
10909    (set_attr "mode" "SI")])
10910
10911 (define_split
10912   [(set (match_operand 0 "flags_reg_operand" "")
10913         (match_operator 2 "compare_operator"
10914           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10915            (const_int 0)]))
10916    (set (match_operand:SI 1 "nonimmediate_operand" "")
10917         (not:SI (match_dup 3)))]
10918   "ix86_match_ccmode (insn, CCNOmode)"
10919   [(parallel [(set (match_dup 0)
10920                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10921                                     (const_int 0)]))
10922               (set (match_dup 1)
10923                    (xor:SI (match_dup 3) (const_int -1)))])]
10924   "")
10925
10926 ;; ??? Currently never generated - xor is used instead.
10927 (define_insn "*one_cmplsi2_2_zext"
10928   [(set (reg FLAGS_REG)
10929         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10930                  (const_int 0)))
10931    (set (match_operand:DI 0 "register_operand" "=r")
10932         (zero_extend:DI (not:SI (match_dup 1))))]
10933   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10934    && ix86_unary_operator_ok (NOT, SImode, operands)"
10935   "#"
10936   [(set_attr "type" "alu1")
10937    (set_attr "mode" "SI")])
10938
10939 (define_split
10940   [(set (match_operand 0 "flags_reg_operand" "")
10941         (match_operator 2 "compare_operator"
10942           [(not:SI (match_operand:SI 3 "register_operand" ""))
10943            (const_int 0)]))
10944    (set (match_operand:DI 1 "register_operand" "")
10945         (zero_extend:DI (not:SI (match_dup 3))))]
10946   "ix86_match_ccmode (insn, CCNOmode)"
10947   [(parallel [(set (match_dup 0)
10948                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10949                                     (const_int 0)]))
10950               (set (match_dup 1)
10951                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10952   "")
10953
10954 (define_expand "one_cmplhi2"
10955   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10956         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10957   "TARGET_HIMODE_MATH"
10958   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10959
10960 (define_insn "*one_cmplhi2_1"
10961   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10962         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10963   "ix86_unary_operator_ok (NOT, HImode, operands)"
10964   "not{w}\t%0"
10965   [(set_attr "type" "negnot")
10966    (set_attr "mode" "HI")])
10967
10968 (define_insn "*one_cmplhi2_2"
10969   [(set (reg FLAGS_REG)
10970         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10971                  (const_int 0)))
10972    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10973         (not:HI (match_dup 1)))]
10974   "ix86_match_ccmode (insn, CCNOmode)
10975    && ix86_unary_operator_ok (NEG, HImode, operands)"
10976   "#"
10977   [(set_attr "type" "alu1")
10978    (set_attr "mode" "HI")])
10979
10980 (define_split
10981   [(set (match_operand 0 "flags_reg_operand" "")
10982         (match_operator 2 "compare_operator"
10983           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10984            (const_int 0)]))
10985    (set (match_operand:HI 1 "nonimmediate_operand" "")
10986         (not:HI (match_dup 3)))]
10987   "ix86_match_ccmode (insn, CCNOmode)"
10988   [(parallel [(set (match_dup 0)
10989                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10990                                     (const_int 0)]))
10991               (set (match_dup 1)
10992                    (xor:HI (match_dup 3) (const_int -1)))])]
10993   "")
10994
10995 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10996 (define_expand "one_cmplqi2"
10997   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10998         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10999   "TARGET_QIMODE_MATH"
11000   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11001
11002 (define_insn "*one_cmplqi2_1"
11003   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11004         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11005   "ix86_unary_operator_ok (NOT, QImode, operands)"
11006   "@
11007    not{b}\t%0
11008    not{l}\t%k0"
11009   [(set_attr "type" "negnot")
11010    (set_attr "mode" "QI,SI")])
11011
11012 (define_insn "*one_cmplqi2_2"
11013   [(set (reg FLAGS_REG)
11014         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11015                  (const_int 0)))
11016    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11017         (not:QI (match_dup 1)))]
11018   "ix86_match_ccmode (insn, CCNOmode)
11019    && ix86_unary_operator_ok (NOT, QImode, operands)"
11020   "#"
11021   [(set_attr "type" "alu1")
11022    (set_attr "mode" "QI")])
11023
11024 (define_split
11025   [(set (match_operand 0 "flags_reg_operand" "")
11026         (match_operator 2 "compare_operator"
11027           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11028            (const_int 0)]))
11029    (set (match_operand:QI 1 "nonimmediate_operand" "")
11030         (not:QI (match_dup 3)))]
11031   "ix86_match_ccmode (insn, CCNOmode)"
11032   [(parallel [(set (match_dup 0)
11033                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11034                                     (const_int 0)]))
11035               (set (match_dup 1)
11036                    (xor:QI (match_dup 3) (const_int -1)))])]
11037   "")
11038 \f
11039 ;; Arithmetic shift instructions
11040
11041 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11042 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11043 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11044 ;; from the assembler input.
11045 ;;
11046 ;; This instruction shifts the target reg/mem as usual, but instead of
11047 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11048 ;; is a left shift double, bits are taken from the high order bits of
11049 ;; reg, else if the insn is a shift right double, bits are taken from the
11050 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11051 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11052 ;;
11053 ;; Since sh[lr]d does not change the `reg' operand, that is done
11054 ;; separately, making all shifts emit pairs of shift double and normal
11055 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11056 ;; support a 63 bit shift, each shift where the count is in a reg expands
11057 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11058 ;;
11059 ;; If the shift count is a constant, we need never emit more than one
11060 ;; shift pair, instead using moves and sign extension for counts greater
11061 ;; than 31.
11062
11063 (define_expand "ashlti3"
11064   [(set (match_operand:TI 0 "register_operand" "")
11065         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11066                    (match_operand:QI 2 "nonmemory_operand" "")))]
11067   "TARGET_64BIT"
11068   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11069
11070 ;; This pattern must be defined before *ashlti3_1 to prevent
11071 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11072
11073 (define_insn "*avx_ashlti3"
11074   [(set (match_operand:TI 0 "register_operand" "=x")
11075         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11076                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11077   "TARGET_AVX"
11078 {
11079   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11080   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11081 }
11082   [(set_attr "type" "sseishft")
11083    (set_attr "prefix" "vex")
11084    (set_attr "mode" "TI")])
11085
11086 (define_insn "sse2_ashlti3"
11087   [(set (match_operand:TI 0 "register_operand" "=x")
11088         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11089                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11090   "TARGET_SSE2"
11091 {
11092   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11093   return "pslldq\t{%2, %0|%0, %2}";
11094 }
11095   [(set_attr "type" "sseishft")
11096    (set_attr "prefix_data16" "1")
11097    (set_attr "mode" "TI")])
11098
11099 (define_insn "*ashlti3_1"
11100   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11101         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11102                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11103    (clobber (reg:CC FLAGS_REG))]
11104   "TARGET_64BIT"
11105   "#"
11106   [(set_attr "type" "multi")])
11107
11108 (define_peephole2
11109   [(match_scratch:DI 3 "r")
11110    (parallel [(set (match_operand:TI 0 "register_operand" "")
11111                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11112                               (match_operand:QI 2 "nonmemory_operand" "")))
11113               (clobber (reg:CC FLAGS_REG))])
11114    (match_dup 3)]
11115   "TARGET_64BIT"
11116   [(const_int 0)]
11117   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11118
11119 (define_split
11120   [(set (match_operand:TI 0 "register_operand" "")
11121         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11122                    (match_operand:QI 2 "nonmemory_operand" "")))
11123    (clobber (reg:CC FLAGS_REG))]
11124   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11125                     ? epilogue_completed : reload_completed)"
11126   [(const_int 0)]
11127   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11128
11129 (define_insn "x86_64_shld"
11130   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11131         (ior:DI (ashift:DI (match_dup 0)
11132                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11133                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11134                   (minus:QI (const_int 64) (match_dup 2)))))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "TARGET_64BIT"
11137   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11138   [(set_attr "type" "ishift")
11139    (set_attr "prefix_0f" "1")
11140    (set_attr "mode" "DI")
11141    (set_attr "athlon_decode" "vector")
11142    (set_attr "amdfam10_decode" "vector")])
11143
11144 (define_expand "x86_64_shift_adj_1"
11145   [(set (reg:CCZ FLAGS_REG)
11146         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11147                              (const_int 64))
11148                      (const_int 0)))
11149    (set (match_operand:DI 0 "register_operand" "")
11150         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11151                          (match_operand:DI 1 "register_operand" "")
11152                          (match_dup 0)))
11153    (set (match_dup 1)
11154         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11155                          (match_operand:DI 3 "register_operand" "r")
11156                          (match_dup 1)))]
11157   "TARGET_64BIT"
11158   "")
11159
11160 (define_expand "x86_64_shift_adj_2"
11161   [(use (match_operand:DI 0 "register_operand" ""))
11162    (use (match_operand:DI 1 "register_operand" ""))
11163    (use (match_operand:QI 2 "register_operand" ""))]
11164   "TARGET_64BIT"
11165 {
11166   rtx label = gen_label_rtx ();
11167   rtx tmp;
11168
11169   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11170
11171   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11172   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11173   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11174                               gen_rtx_LABEL_REF (VOIDmode, label),
11175                               pc_rtx);
11176   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11177   JUMP_LABEL (tmp) = label;
11178
11179   emit_move_insn (operands[0], operands[1]);
11180   ix86_expand_clear (operands[1]);
11181
11182   emit_label (label);
11183   LABEL_NUSES (label) = 1;
11184
11185   DONE;
11186 })
11187
11188 (define_expand "ashldi3"
11189   [(set (match_operand:DI 0 "shiftdi_operand" "")
11190         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11191                    (match_operand:QI 2 "nonmemory_operand" "")))]
11192   ""
11193   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11194
11195 (define_insn "*ashldi3_1_rex64"
11196   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11197         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11198                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11201 {
11202   switch (get_attr_type (insn))
11203     {
11204     case TYPE_ALU:
11205       gcc_assert (operands[2] == const1_rtx);
11206       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11207       return "add{q}\t%0, %0";
11208
11209     case TYPE_LEA:
11210       gcc_assert (CONST_INT_P (operands[2]));
11211       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11212       operands[1] = gen_rtx_MULT (DImode, operands[1],
11213                                   GEN_INT (1 << INTVAL (operands[2])));
11214       return "lea{q}\t{%a1, %0|%0, %a1}";
11215
11216     default:
11217       if (REG_P (operands[2]))
11218         return "sal{q}\t{%b2, %0|%0, %b2}";
11219       else if (operands[2] == const1_rtx
11220                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11221         return "sal{q}\t%0";
11222       else
11223         return "sal{q}\t{%2, %0|%0, %2}";
11224     }
11225 }
11226   [(set (attr "type")
11227      (cond [(eq_attr "alternative" "1")
11228               (const_string "lea")
11229             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11230                           (const_int 0))
11231                       (match_operand 0 "register_operand" ""))
11232                  (match_operand 2 "const1_operand" ""))
11233               (const_string "alu")
11234            ]
11235            (const_string "ishift")))
11236    (set_attr "mode" "DI")])
11237
11238 ;; Convert lea to the lea pattern to avoid flags dependency.
11239 (define_split
11240   [(set (match_operand:DI 0 "register_operand" "")
11241         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11242                    (match_operand:QI 2 "immediate_operand" "")))
11243    (clobber (reg:CC FLAGS_REG))]
11244   "TARGET_64BIT && reload_completed
11245    && true_regnum (operands[0]) != true_regnum (operands[1])"
11246   [(set (match_dup 0)
11247         (mult:DI (match_dup 1)
11248                  (match_dup 2)))]
11249   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11250
11251 ;; This pattern can't accept a variable shift count, since shifts by
11252 ;; zero don't affect the flags.  We assume that shifts by constant
11253 ;; zero are optimized away.
11254 (define_insn "*ashldi3_cmp_rex64"
11255   [(set (reg FLAGS_REG)
11256         (compare
11257           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11258                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11259           (const_int 0)))
11260    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11261         (ashift:DI (match_dup 1) (match_dup 2)))]
11262   "TARGET_64BIT
11263    && (optimize_function_for_size_p (cfun)
11264        || !TARGET_PARTIAL_FLAG_REG_STALL
11265        || (operands[2] == const1_rtx
11266            && (TARGET_SHIFT1
11267                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11268    && ix86_match_ccmode (insn, CCGOCmode)
11269    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11270 {
11271   switch (get_attr_type (insn))
11272     {
11273     case TYPE_ALU:
11274       gcc_assert (operands[2] == const1_rtx);
11275       return "add{q}\t%0, %0";
11276
11277     default:
11278       if (REG_P (operands[2]))
11279         return "sal{q}\t{%b2, %0|%0, %b2}";
11280       else if (operands[2] == const1_rtx
11281                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11282         return "sal{q}\t%0";
11283       else
11284         return "sal{q}\t{%2, %0|%0, %2}";
11285     }
11286 }
11287   [(set (attr "type")
11288      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11289                           (const_int 0))
11290                       (match_operand 0 "register_operand" ""))
11291                  (match_operand 2 "const1_operand" ""))
11292               (const_string "alu")
11293            ]
11294            (const_string "ishift")))
11295    (set_attr "mode" "DI")])
11296
11297 (define_insn "*ashldi3_cconly_rex64"
11298   [(set (reg FLAGS_REG)
11299         (compare
11300           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11301                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11302           (const_int 0)))
11303    (clobber (match_scratch:DI 0 "=r"))]
11304   "TARGET_64BIT
11305    && (optimize_function_for_size_p (cfun)
11306        || !TARGET_PARTIAL_FLAG_REG_STALL
11307        || (operands[2] == const1_rtx
11308            && (TARGET_SHIFT1
11309                || TARGET_DOUBLE_WITH_ADD)))
11310    && ix86_match_ccmode (insn, CCGOCmode)
11311    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11312 {
11313   switch (get_attr_type (insn))
11314     {
11315     case TYPE_ALU:
11316       gcc_assert (operands[2] == const1_rtx);
11317       return "add{q}\t%0, %0";
11318
11319     default:
11320       if (REG_P (operands[2]))
11321         return "sal{q}\t{%b2, %0|%0, %b2}";
11322       else if (operands[2] == const1_rtx
11323                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11324         return "sal{q}\t%0";
11325       else
11326         return "sal{q}\t{%2, %0|%0, %2}";
11327     }
11328 }
11329   [(set (attr "type")
11330      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11331                           (const_int 0))
11332                       (match_operand 0 "register_operand" ""))
11333                  (match_operand 2 "const1_operand" ""))
11334               (const_string "alu")
11335            ]
11336            (const_string "ishift")))
11337    (set_attr "mode" "DI")])
11338
11339 (define_insn "*ashldi3_1"
11340   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11341         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11342                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11343    (clobber (reg:CC FLAGS_REG))]
11344   "!TARGET_64BIT"
11345   "#"
11346   [(set_attr "type" "multi")])
11347
11348 ;; By default we don't ask for a scratch register, because when DImode
11349 ;; values are manipulated, registers are already at a premium.  But if
11350 ;; we have one handy, we won't turn it away.
11351 (define_peephole2
11352   [(match_scratch:SI 3 "r")
11353    (parallel [(set (match_operand:DI 0 "register_operand" "")
11354                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11355                               (match_operand:QI 2 "nonmemory_operand" "")))
11356               (clobber (reg:CC FLAGS_REG))])
11357    (match_dup 3)]
11358   "!TARGET_64BIT && TARGET_CMOVE"
11359   [(const_int 0)]
11360   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11361
11362 (define_split
11363   [(set (match_operand:DI 0 "register_operand" "")
11364         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11365                    (match_operand:QI 2 "nonmemory_operand" "")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11368                      ? epilogue_completed : reload_completed)"
11369   [(const_int 0)]
11370   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11371
11372 (define_insn "x86_shld"
11373   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11374         (ior:SI (ashift:SI (match_dup 0)
11375                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11376                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11377                   (minus:QI (const_int 32) (match_dup 2)))))
11378    (clobber (reg:CC FLAGS_REG))]
11379   ""
11380   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11381   [(set_attr "type" "ishift")
11382    (set_attr "prefix_0f" "1")
11383    (set_attr "mode" "SI")
11384    (set_attr "pent_pair" "np")
11385    (set_attr "athlon_decode" "vector")
11386    (set_attr "amdfam10_decode" "vector")])
11387
11388 (define_expand "x86_shift_adj_1"
11389   [(set (reg:CCZ FLAGS_REG)
11390         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11391                              (const_int 32))
11392                      (const_int 0)))
11393    (set (match_operand:SI 0 "register_operand" "")
11394         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11395                          (match_operand:SI 1 "register_operand" "")
11396                          (match_dup 0)))
11397    (set (match_dup 1)
11398         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11399                          (match_operand:SI 3 "register_operand" "r")
11400                          (match_dup 1)))]
11401   "TARGET_CMOVE"
11402   "")
11403
11404 (define_expand "x86_shift_adj_2"
11405   [(use (match_operand:SI 0 "register_operand" ""))
11406    (use (match_operand:SI 1 "register_operand" ""))
11407    (use (match_operand:QI 2 "register_operand" ""))]
11408   ""
11409 {
11410   rtx label = gen_label_rtx ();
11411   rtx tmp;
11412
11413   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11414
11415   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11416   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11417   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11418                               gen_rtx_LABEL_REF (VOIDmode, label),
11419                               pc_rtx);
11420   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11421   JUMP_LABEL (tmp) = label;
11422
11423   emit_move_insn (operands[0], operands[1]);
11424   ix86_expand_clear (operands[1]);
11425
11426   emit_label (label);
11427   LABEL_NUSES (label) = 1;
11428
11429   DONE;
11430 })
11431
11432 (define_expand "ashlsi3"
11433   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11434         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11435                    (match_operand:QI 2 "nonmemory_operand" "")))]
11436   ""
11437   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11438
11439 (define_insn "*ashlsi3_1"
11440   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11441         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11442                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11443    (clobber (reg:CC FLAGS_REG))]
11444   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11445 {
11446   switch (get_attr_type (insn))
11447     {
11448     case TYPE_ALU:
11449       gcc_assert (operands[2] == const1_rtx);
11450       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11451       return "add{l}\t%0, %0";
11452
11453     case TYPE_LEA:
11454       return "#";
11455
11456     default:
11457       if (REG_P (operands[2]))
11458         return "sal{l}\t{%b2, %0|%0, %b2}";
11459       else if (operands[2] == const1_rtx
11460                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11461         return "sal{l}\t%0";
11462       else
11463         return "sal{l}\t{%2, %0|%0, %2}";
11464     }
11465 }
11466   [(set (attr "type")
11467      (cond [(eq_attr "alternative" "1")
11468               (const_string "lea")
11469             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11470                           (const_int 0))
11471                       (match_operand 0 "register_operand" ""))
11472                  (match_operand 2 "const1_operand" ""))
11473               (const_string "alu")
11474            ]
11475            (const_string "ishift")))
11476    (set_attr "mode" "SI")])
11477
11478 ;; Convert lea to the lea pattern to avoid flags dependency.
11479 (define_split
11480   [(set (match_operand 0 "register_operand" "")
11481         (ashift (match_operand 1 "index_register_operand" "")
11482                 (match_operand:QI 2 "const_int_operand" "")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "reload_completed
11485    && true_regnum (operands[0]) != true_regnum (operands[1])
11486    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11487   [(const_int 0)]
11488 {
11489   rtx pat;
11490   enum machine_mode mode = GET_MODE (operands[0]);
11491
11492   if (GET_MODE_SIZE (mode) < 4)
11493     operands[0] = gen_lowpart (SImode, operands[0]);
11494   if (mode != Pmode)
11495     operands[1] = gen_lowpart (Pmode, operands[1]);
11496   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11497
11498   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11499   if (Pmode != SImode)
11500     pat = gen_rtx_SUBREG (SImode, pat, 0);
11501   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11502   DONE;
11503 })
11504
11505 ;; Rare case of shifting RSP is handled by generating move and shift
11506 (define_split
11507   [(set (match_operand 0 "register_operand" "")
11508         (ashift (match_operand 1 "register_operand" "")
11509                 (match_operand:QI 2 "const_int_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "reload_completed
11512    && true_regnum (operands[0]) != true_regnum (operands[1])"
11513   [(const_int 0)]
11514 {
11515   rtx pat, clob;
11516   emit_move_insn (operands[0], operands[1]);
11517   pat = gen_rtx_SET (VOIDmode, operands[0],
11518                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11519                                      operands[0], operands[2]));
11520   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11521   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11522   DONE;
11523 })
11524
11525 (define_insn "*ashlsi3_1_zext"
11526   [(set (match_operand:DI 0 "register_operand" "=r,r")
11527         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11528                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11531 {
11532   switch (get_attr_type (insn))
11533     {
11534     case TYPE_ALU:
11535       gcc_assert (operands[2] == const1_rtx);
11536       return "add{l}\t%k0, %k0";
11537
11538     case TYPE_LEA:
11539       return "#";
11540
11541     default:
11542       if (REG_P (operands[2]))
11543         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11544       else if (operands[2] == const1_rtx
11545                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11546         return "sal{l}\t%k0";
11547       else
11548         return "sal{l}\t{%2, %k0|%k0, %2}";
11549     }
11550 }
11551   [(set (attr "type")
11552      (cond [(eq_attr "alternative" "1")
11553               (const_string "lea")
11554             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11555                      (const_int 0))
11556                  (match_operand 2 "const1_operand" ""))
11557               (const_string "alu")
11558            ]
11559            (const_string "ishift")))
11560    (set_attr "mode" "SI")])
11561
11562 ;; Convert lea to the lea pattern to avoid flags dependency.
11563 (define_split
11564   [(set (match_operand:DI 0 "register_operand" "")
11565         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11566                                 (match_operand:QI 2 "const_int_operand" ""))))
11567    (clobber (reg:CC FLAGS_REG))]
11568   "TARGET_64BIT && reload_completed
11569    && true_regnum (operands[0]) != true_regnum (operands[1])"
11570   [(set (match_dup 0) (zero_extend:DI
11571                         (subreg:SI (mult:SI (match_dup 1)
11572                                             (match_dup 2)) 0)))]
11573 {
11574   operands[1] = gen_lowpart (Pmode, operands[1]);
11575   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11576 })
11577
11578 ;; This pattern can't accept a variable shift count, since shifts by
11579 ;; zero don't affect the flags.  We assume that shifts by constant
11580 ;; zero are optimized away.
11581 (define_insn "*ashlsi3_cmp"
11582   [(set (reg FLAGS_REG)
11583         (compare
11584           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11585                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11586           (const_int 0)))
11587    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588         (ashift:SI (match_dup 1) (match_dup 2)))]
11589    "(optimize_function_for_size_p (cfun)
11590      || !TARGET_PARTIAL_FLAG_REG_STALL
11591      || (operands[2] == const1_rtx
11592          && (TARGET_SHIFT1
11593              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11594    && ix86_match_ccmode (insn, CCGOCmode)
11595    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11596 {
11597   switch (get_attr_type (insn))
11598     {
11599     case TYPE_ALU:
11600       gcc_assert (operands[2] == const1_rtx);
11601       return "add{l}\t%0, %0";
11602
11603     default:
11604       if (REG_P (operands[2]))
11605         return "sal{l}\t{%b2, %0|%0, %b2}";
11606       else if (operands[2] == const1_rtx
11607                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11608         return "sal{l}\t%0";
11609       else
11610         return "sal{l}\t{%2, %0|%0, %2}";
11611     }
11612 }
11613   [(set (attr "type")
11614      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11615                           (const_int 0))
11616                       (match_operand 0 "register_operand" ""))
11617                  (match_operand 2 "const1_operand" ""))
11618               (const_string "alu")
11619            ]
11620            (const_string "ishift")))
11621    (set_attr "mode" "SI")])
11622
11623 (define_insn "*ashlsi3_cconly"
11624   [(set (reg FLAGS_REG)
11625         (compare
11626           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11627                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11628           (const_int 0)))
11629    (clobber (match_scratch:SI 0 "=r"))]
11630   "(optimize_function_for_size_p (cfun)
11631     || !TARGET_PARTIAL_FLAG_REG_STALL
11632     || (operands[2] == const1_rtx
11633         && (TARGET_SHIFT1
11634             || TARGET_DOUBLE_WITH_ADD)))
11635    && ix86_match_ccmode (insn, CCGOCmode)
11636    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11637 {
11638   switch (get_attr_type (insn))
11639     {
11640     case TYPE_ALU:
11641       gcc_assert (operands[2] == const1_rtx);
11642       return "add{l}\t%0, %0";
11643
11644     default:
11645       if (REG_P (operands[2]))
11646         return "sal{l}\t{%b2, %0|%0, %b2}";
11647       else if (operands[2] == const1_rtx
11648                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11649         return "sal{l}\t%0";
11650       else
11651         return "sal{l}\t{%2, %0|%0, %2}";
11652     }
11653 }
11654   [(set (attr "type")
11655      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11656                           (const_int 0))
11657                       (match_operand 0 "register_operand" ""))
11658                  (match_operand 2 "const1_operand" ""))
11659               (const_string "alu")
11660            ]
11661            (const_string "ishift")))
11662    (set_attr "mode" "SI")])
11663
11664 (define_insn "*ashlsi3_cmp_zext"
11665   [(set (reg FLAGS_REG)
11666         (compare
11667           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11668                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11669           (const_int 0)))
11670    (set (match_operand:DI 0 "register_operand" "=r")
11671         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11672   "TARGET_64BIT
11673    && (optimize_function_for_size_p (cfun)
11674        || !TARGET_PARTIAL_FLAG_REG_STALL
11675        || (operands[2] == const1_rtx
11676            && (TARGET_SHIFT1
11677                || TARGET_DOUBLE_WITH_ADD)))
11678    && ix86_match_ccmode (insn, CCGOCmode)
11679    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11680 {
11681   switch (get_attr_type (insn))
11682     {
11683     case TYPE_ALU:
11684       gcc_assert (operands[2] == const1_rtx);
11685       return "add{l}\t%k0, %k0";
11686
11687     default:
11688       if (REG_P (operands[2]))
11689         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11690       else if (operands[2] == const1_rtx
11691                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11692         return "sal{l}\t%k0";
11693       else
11694         return "sal{l}\t{%2, %k0|%k0, %2}";
11695     }
11696 }
11697   [(set (attr "type")
11698      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11699                      (const_int 0))
11700                  (match_operand 2 "const1_operand" ""))
11701               (const_string "alu")
11702            ]
11703            (const_string "ishift")))
11704    (set_attr "mode" "SI")])
11705
11706 (define_expand "ashlhi3"
11707   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709                    (match_operand:QI 2 "nonmemory_operand" "")))]
11710   "TARGET_HIMODE_MATH"
11711   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11712
11713 (define_insn "*ashlhi3_1_lea"
11714   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11715         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11716                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11717    (clobber (reg:CC FLAGS_REG))]
11718   "!TARGET_PARTIAL_REG_STALL
11719    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11720 {
11721   switch (get_attr_type (insn))
11722     {
11723     case TYPE_LEA:
11724       return "#";
11725     case TYPE_ALU:
11726       gcc_assert (operands[2] == const1_rtx);
11727       return "add{w}\t%0, %0";
11728
11729     default:
11730       if (REG_P (operands[2]))
11731         return "sal{w}\t{%b2, %0|%0, %b2}";
11732       else if (operands[2] == const1_rtx
11733                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11734         return "sal{w}\t%0";
11735       else
11736         return "sal{w}\t{%2, %0|%0, %2}";
11737     }
11738 }
11739   [(set (attr "type")
11740      (cond [(eq_attr "alternative" "1")
11741               (const_string "lea")
11742             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11743                           (const_int 0))
11744                       (match_operand 0 "register_operand" ""))
11745                  (match_operand 2 "const1_operand" ""))
11746               (const_string "alu")
11747            ]
11748            (const_string "ishift")))
11749    (set_attr "mode" "HI,SI")])
11750
11751 (define_insn "*ashlhi3_1"
11752   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11753         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11754                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11755    (clobber (reg:CC FLAGS_REG))]
11756   "TARGET_PARTIAL_REG_STALL
11757    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11758 {
11759   switch (get_attr_type (insn))
11760     {
11761     case TYPE_ALU:
11762       gcc_assert (operands[2] == const1_rtx);
11763       return "add{w}\t%0, %0";
11764
11765     default:
11766       if (REG_P (operands[2]))
11767         return "sal{w}\t{%b2, %0|%0, %b2}";
11768       else if (operands[2] == const1_rtx
11769                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11770         return "sal{w}\t%0";
11771       else
11772         return "sal{w}\t{%2, %0|%0, %2}";
11773     }
11774 }
11775   [(set (attr "type")
11776      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11777                           (const_int 0))
11778                       (match_operand 0 "register_operand" ""))
11779                  (match_operand 2 "const1_operand" ""))
11780               (const_string "alu")
11781            ]
11782            (const_string "ishift")))
11783    (set_attr "mode" "HI")])
11784
11785 ;; This pattern can't accept a variable shift count, since shifts by
11786 ;; zero don't affect the flags.  We assume that shifts by constant
11787 ;; zero are optimized away.
11788 (define_insn "*ashlhi3_cmp"
11789   [(set (reg FLAGS_REG)
11790         (compare
11791           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11792                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11793           (const_int 0)))
11794    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11795         (ashift:HI (match_dup 1) (match_dup 2)))]
11796   "(optimize_function_for_size_p (cfun)
11797     || !TARGET_PARTIAL_FLAG_REG_STALL
11798     || (operands[2] == const1_rtx
11799         && (TARGET_SHIFT1
11800             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11801    && ix86_match_ccmode (insn, CCGOCmode)
11802    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11803 {
11804   switch (get_attr_type (insn))
11805     {
11806     case TYPE_ALU:
11807       gcc_assert (operands[2] == const1_rtx);
11808       return "add{w}\t%0, %0";
11809
11810     default:
11811       if (REG_P (operands[2]))
11812         return "sal{w}\t{%b2, %0|%0, %b2}";
11813       else if (operands[2] == const1_rtx
11814                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11815         return "sal{w}\t%0";
11816       else
11817         return "sal{w}\t{%2, %0|%0, %2}";
11818     }
11819 }
11820   [(set (attr "type")
11821      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11822                           (const_int 0))
11823                       (match_operand 0 "register_operand" ""))
11824                  (match_operand 2 "const1_operand" ""))
11825               (const_string "alu")
11826            ]
11827            (const_string "ishift")))
11828    (set_attr "mode" "HI")])
11829
11830 (define_insn "*ashlhi3_cconly"
11831   [(set (reg FLAGS_REG)
11832         (compare
11833           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11834                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11835           (const_int 0)))
11836    (clobber (match_scratch:HI 0 "=r"))]
11837   "(optimize_function_for_size_p (cfun)
11838     || !TARGET_PARTIAL_FLAG_REG_STALL
11839     || (operands[2] == const1_rtx
11840         && (TARGET_SHIFT1
11841             || TARGET_DOUBLE_WITH_ADD)))
11842    && ix86_match_ccmode (insn, CCGOCmode)
11843    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11844 {
11845   switch (get_attr_type (insn))
11846     {
11847     case TYPE_ALU:
11848       gcc_assert (operands[2] == const1_rtx);
11849       return "add{w}\t%0, %0";
11850
11851     default:
11852       if (REG_P (operands[2]))
11853         return "sal{w}\t{%b2, %0|%0, %b2}";
11854       else if (operands[2] == const1_rtx
11855                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11856         return "sal{w}\t%0";
11857       else
11858         return "sal{w}\t{%2, %0|%0, %2}";
11859     }
11860 }
11861   [(set (attr "type")
11862      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11863                           (const_int 0))
11864                       (match_operand 0 "register_operand" ""))
11865                  (match_operand 2 "const1_operand" ""))
11866               (const_string "alu")
11867            ]
11868            (const_string "ishift")))
11869    (set_attr "mode" "HI")])
11870
11871 (define_expand "ashlqi3"
11872   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11873         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11874                    (match_operand:QI 2 "nonmemory_operand" "")))]
11875   "TARGET_QIMODE_MATH"
11876   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11877
11878 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11879
11880 (define_insn "*ashlqi3_1_lea"
11881   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11882         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11883                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11884    (clobber (reg:CC FLAGS_REG))]
11885   "!TARGET_PARTIAL_REG_STALL
11886    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11887 {
11888   switch (get_attr_type (insn))
11889     {
11890     case TYPE_LEA:
11891       return "#";
11892     case TYPE_ALU:
11893       gcc_assert (operands[2] == const1_rtx);
11894       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11895         return "add{l}\t%k0, %k0";
11896       else
11897         return "add{b}\t%0, %0";
11898
11899     default:
11900       if (REG_P (operands[2]))
11901         {
11902           if (get_attr_mode (insn) == MODE_SI)
11903             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11904           else
11905             return "sal{b}\t{%b2, %0|%0, %b2}";
11906         }
11907       else if (operands[2] == const1_rtx
11908                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11909         {
11910           if (get_attr_mode (insn) == MODE_SI)
11911             return "sal{l}\t%0";
11912           else
11913             return "sal{b}\t%0";
11914         }
11915       else
11916         {
11917           if (get_attr_mode (insn) == MODE_SI)
11918             return "sal{l}\t{%2, %k0|%k0, %2}";
11919           else
11920             return "sal{b}\t{%2, %0|%0, %2}";
11921         }
11922     }
11923 }
11924   [(set (attr "type")
11925      (cond [(eq_attr "alternative" "2")
11926               (const_string "lea")
11927             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11928                           (const_int 0))
11929                       (match_operand 0 "register_operand" ""))
11930                  (match_operand 2 "const1_operand" ""))
11931               (const_string "alu")
11932            ]
11933            (const_string "ishift")))
11934    (set_attr "mode" "QI,SI,SI")])
11935
11936 (define_insn "*ashlqi3_1"
11937   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11938         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11939                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "TARGET_PARTIAL_REG_STALL
11942    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11943 {
11944   switch (get_attr_type (insn))
11945     {
11946     case TYPE_ALU:
11947       gcc_assert (operands[2] == const1_rtx);
11948       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11949         return "add{l}\t%k0, %k0";
11950       else
11951         return "add{b}\t%0, %0";
11952
11953     default:
11954       if (REG_P (operands[2]))
11955         {
11956           if (get_attr_mode (insn) == MODE_SI)
11957             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11958           else
11959             return "sal{b}\t{%b2, %0|%0, %b2}";
11960         }
11961       else if (operands[2] == const1_rtx
11962                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11963         {
11964           if (get_attr_mode (insn) == MODE_SI)
11965             return "sal{l}\t%0";
11966           else
11967             return "sal{b}\t%0";
11968         }
11969       else
11970         {
11971           if (get_attr_mode (insn) == MODE_SI)
11972             return "sal{l}\t{%2, %k0|%k0, %2}";
11973           else
11974             return "sal{b}\t{%2, %0|%0, %2}";
11975         }
11976     }
11977 }
11978   [(set (attr "type")
11979      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11980                           (const_int 0))
11981                       (match_operand 0 "register_operand" ""))
11982                  (match_operand 2 "const1_operand" ""))
11983               (const_string "alu")
11984            ]
11985            (const_string "ishift")))
11986    (set_attr "mode" "QI,SI")])
11987
11988 ;; This pattern can't accept a variable shift count, since shifts by
11989 ;; zero don't affect the flags.  We assume that shifts by constant
11990 ;; zero are optimized away.
11991 (define_insn "*ashlqi3_cmp"
11992   [(set (reg FLAGS_REG)
11993         (compare
11994           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11995                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11996           (const_int 0)))
11997    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11998         (ashift:QI (match_dup 1) (match_dup 2)))]
11999   "(optimize_function_for_size_p (cfun)
12000     || !TARGET_PARTIAL_FLAG_REG_STALL
12001     || (operands[2] == const1_rtx
12002         && (TARGET_SHIFT1
12003             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12004    && ix86_match_ccmode (insn, CCGOCmode)
12005    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12006 {
12007   switch (get_attr_type (insn))
12008     {
12009     case TYPE_ALU:
12010       gcc_assert (operands[2] == const1_rtx);
12011       return "add{b}\t%0, %0";
12012
12013     default:
12014       if (REG_P (operands[2]))
12015         return "sal{b}\t{%b2, %0|%0, %b2}";
12016       else if (operands[2] == const1_rtx
12017                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12018         return "sal{b}\t%0";
12019       else
12020         return "sal{b}\t{%2, %0|%0, %2}";
12021     }
12022 }
12023   [(set (attr "type")
12024      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12025                           (const_int 0))
12026                       (match_operand 0 "register_operand" ""))
12027                  (match_operand 2 "const1_operand" ""))
12028               (const_string "alu")
12029            ]
12030            (const_string "ishift")))
12031    (set_attr "mode" "QI")])
12032
12033 (define_insn "*ashlqi3_cconly"
12034   [(set (reg FLAGS_REG)
12035         (compare
12036           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12037                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12038           (const_int 0)))
12039    (clobber (match_scratch:QI 0 "=q"))]
12040   "(optimize_function_for_size_p (cfun)
12041     || !TARGET_PARTIAL_FLAG_REG_STALL
12042     || (operands[2] == const1_rtx
12043         && (TARGET_SHIFT1
12044             || TARGET_DOUBLE_WITH_ADD)))
12045    && ix86_match_ccmode (insn, CCGOCmode)
12046    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12047 {
12048   switch (get_attr_type (insn))
12049     {
12050     case TYPE_ALU:
12051       gcc_assert (operands[2] == const1_rtx);
12052       return "add{b}\t%0, %0";
12053
12054     default:
12055       if (REG_P (operands[2]))
12056         return "sal{b}\t{%b2, %0|%0, %b2}";
12057       else if (operands[2] == const1_rtx
12058                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12059         return "sal{b}\t%0";
12060       else
12061         return "sal{b}\t{%2, %0|%0, %2}";
12062     }
12063 }
12064   [(set (attr "type")
12065      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12066                           (const_int 0))
12067                       (match_operand 0 "register_operand" ""))
12068                  (match_operand 2 "const1_operand" ""))
12069               (const_string "alu")
12070            ]
12071            (const_string "ishift")))
12072    (set_attr "mode" "QI")])
12073
12074 ;; See comment above `ashldi3' about how this works.
12075
12076 (define_expand "ashrti3"
12077   [(set (match_operand:TI 0 "register_operand" "")
12078         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12079                      (match_operand:QI 2 "nonmemory_operand" "")))]
12080   "TARGET_64BIT"
12081   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12082
12083 (define_insn "*ashrti3_1"
12084   [(set (match_operand:TI 0 "register_operand" "=r")
12085         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12086                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12087    (clobber (reg:CC FLAGS_REG))]
12088   "TARGET_64BIT"
12089   "#"
12090   [(set_attr "type" "multi")])
12091
12092 (define_peephole2
12093   [(match_scratch:DI 3 "r")
12094    (parallel [(set (match_operand:TI 0 "register_operand" "")
12095                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12096                                 (match_operand:QI 2 "nonmemory_operand" "")))
12097               (clobber (reg:CC FLAGS_REG))])
12098    (match_dup 3)]
12099   "TARGET_64BIT"
12100   [(const_int 0)]
12101   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12102
12103 (define_split
12104   [(set (match_operand:TI 0 "register_operand" "")
12105         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12106                      (match_operand:QI 2 "nonmemory_operand" "")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12109                     ? epilogue_completed : reload_completed)"
12110   [(const_int 0)]
12111   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12112
12113 (define_insn "x86_64_shrd"
12114   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12115         (ior:DI (ashiftrt:DI (match_dup 0)
12116                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12117                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12118                   (minus:QI (const_int 64) (match_dup 2)))))
12119    (clobber (reg:CC FLAGS_REG))]
12120   "TARGET_64BIT"
12121   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12122   [(set_attr "type" "ishift")
12123    (set_attr "prefix_0f" "1")
12124    (set_attr "mode" "DI")
12125    (set_attr "athlon_decode" "vector")
12126    (set_attr "amdfam10_decode" "vector")])
12127
12128 (define_expand "ashrdi3"
12129   [(set (match_operand:DI 0 "shiftdi_operand" "")
12130         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12131                      (match_operand:QI 2 "nonmemory_operand" "")))]
12132   ""
12133   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12134
12135 (define_expand "x86_64_shift_adj_3"
12136   [(use (match_operand:DI 0 "register_operand" ""))
12137    (use (match_operand:DI 1 "register_operand" ""))
12138    (use (match_operand:QI 2 "register_operand" ""))]
12139   ""
12140 {
12141   rtx label = gen_label_rtx ();
12142   rtx tmp;
12143
12144   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12145
12146   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12147   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12148   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12149                               gen_rtx_LABEL_REF (VOIDmode, label),
12150                               pc_rtx);
12151   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12152   JUMP_LABEL (tmp) = label;
12153
12154   emit_move_insn (operands[0], operands[1]);
12155   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12156
12157   emit_label (label);
12158   LABEL_NUSES (label) = 1;
12159
12160   DONE;
12161 })
12162
12163 (define_insn "ashrdi3_63_rex64"
12164   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12165         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12166                      (match_operand:DI 2 "const_int_operand" "i,i")))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "TARGET_64BIT && INTVAL (operands[2]) == 63
12169    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12170    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12171   "@
12172    {cqto|cqo}
12173    sar{q}\t{%2, %0|%0, %2}"
12174   [(set_attr "type" "imovx,ishift")
12175    (set_attr "prefix_0f" "0,*")
12176    (set_attr "length_immediate" "0,*")
12177    (set_attr "modrm" "0,1")
12178    (set_attr "mode" "DI")])
12179
12180 (define_insn "*ashrdi3_1_one_bit_rex64"
12181   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12182         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12183                      (match_operand:QI 2 "const1_operand" "")))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "TARGET_64BIT
12186    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12187    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12188   "sar{q}\t%0"
12189   [(set_attr "type" "ishift")
12190    (set (attr "length")
12191      (if_then_else (match_operand:DI 0 "register_operand" "")
12192         (const_string "2")
12193         (const_string "*")))])
12194
12195 (define_insn "*ashrdi3_1_rex64"
12196   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12197         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12198                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12199    (clobber (reg:CC FLAGS_REG))]
12200   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12201   "@
12202    sar{q}\t{%2, %0|%0, %2}
12203    sar{q}\t{%b2, %0|%0, %b2}"
12204   [(set_attr "type" "ishift")
12205    (set_attr "mode" "DI")])
12206
12207 ;; This pattern can't accept a variable shift count, since shifts by
12208 ;; zero don't affect the flags.  We assume that shifts by constant
12209 ;; zero are optimized away.
12210 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12211   [(set (reg FLAGS_REG)
12212         (compare
12213           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12214                        (match_operand:QI 2 "const1_operand" ""))
12215           (const_int 0)))
12216    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12217         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12218   "TARGET_64BIT
12219    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12220    && ix86_match_ccmode (insn, CCGOCmode)
12221    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12222   "sar{q}\t%0"
12223   [(set_attr "type" "ishift")
12224    (set (attr "length")
12225      (if_then_else (match_operand:DI 0 "register_operand" "")
12226         (const_string "2")
12227         (const_string "*")))])
12228
12229 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12230   [(set (reg FLAGS_REG)
12231         (compare
12232           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12233                        (match_operand:QI 2 "const1_operand" ""))
12234           (const_int 0)))
12235    (clobber (match_scratch:DI 0 "=r"))]
12236   "TARGET_64BIT
12237    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12238    && ix86_match_ccmode (insn, CCGOCmode)
12239    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12240   "sar{q}\t%0"
12241   [(set_attr "type" "ishift")
12242    (set_attr "length" "2")])
12243
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags.  We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrdi3_cmp_rex64"
12248   [(set (reg FLAGS_REG)
12249         (compare
12250           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12251                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12252           (const_int 0)))
12253    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12254         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12255   "TARGET_64BIT
12256    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12257    && ix86_match_ccmode (insn, CCGOCmode)
12258    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12259   "sar{q}\t{%2, %0|%0, %2}"
12260   [(set_attr "type" "ishift")
12261    (set_attr "mode" "DI")])
12262
12263 (define_insn "*ashrdi3_cconly_rex64"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12268           (const_int 0)))
12269    (clobber (match_scratch:DI 0 "=r"))]
12270   "TARGET_64BIT
12271    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12272    && ix86_match_ccmode (insn, CCGOCmode)
12273    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12274   "sar{q}\t{%2, %0|%0, %2}"
12275   [(set_attr "type" "ishift")
12276    (set_attr "mode" "DI")])
12277
12278 (define_insn "*ashrdi3_1"
12279   [(set (match_operand:DI 0 "register_operand" "=r")
12280         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12281                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12282    (clobber (reg:CC FLAGS_REG))]
12283   "!TARGET_64BIT"
12284   "#"
12285   [(set_attr "type" "multi")])
12286
12287 ;; By default we don't ask for a scratch register, because when DImode
12288 ;; values are manipulated, registers are already at a premium.  But if
12289 ;; we have one handy, we won't turn it away.
12290 (define_peephole2
12291   [(match_scratch:SI 3 "r")
12292    (parallel [(set (match_operand:DI 0 "register_operand" "")
12293                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12294                                 (match_operand:QI 2 "nonmemory_operand" "")))
12295               (clobber (reg:CC FLAGS_REG))])
12296    (match_dup 3)]
12297   "!TARGET_64BIT && TARGET_CMOVE"
12298   [(const_int 0)]
12299   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12300
12301 (define_split
12302   [(set (match_operand:DI 0 "register_operand" "")
12303         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12304                      (match_operand:QI 2 "nonmemory_operand" "")))
12305    (clobber (reg:CC FLAGS_REG))]
12306   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12307                      ? epilogue_completed : reload_completed)"
12308   [(const_int 0)]
12309   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12310
12311 (define_insn "x86_shrd"
12312   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12313         (ior:SI (ashiftrt:SI (match_dup 0)
12314                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12315                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12316                   (minus:QI (const_int 32) (match_dup 2)))))
12317    (clobber (reg:CC FLAGS_REG))]
12318   ""
12319   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12320   [(set_attr "type" "ishift")
12321    (set_attr "prefix_0f" "1")
12322    (set_attr "pent_pair" "np")
12323    (set_attr "mode" "SI")])
12324
12325 (define_expand "x86_shift_adj_3"
12326   [(use (match_operand:SI 0 "register_operand" ""))
12327    (use (match_operand:SI 1 "register_operand" ""))
12328    (use (match_operand:QI 2 "register_operand" ""))]
12329   ""
12330 {
12331   rtx label = gen_label_rtx ();
12332   rtx tmp;
12333
12334   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12335
12336   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12337   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12338   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12339                               gen_rtx_LABEL_REF (VOIDmode, label),
12340                               pc_rtx);
12341   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12342   JUMP_LABEL (tmp) = label;
12343
12344   emit_move_insn (operands[0], operands[1]);
12345   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12346
12347   emit_label (label);
12348   LABEL_NUSES (label) = 1;
12349
12350   DONE;
12351 })
12352
12353 (define_expand "ashrsi3_31"
12354   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12355                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12356                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12357               (clobber (reg:CC FLAGS_REG))])]
12358   "")
12359
12360 (define_insn "*ashrsi3_31"
12361   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12362         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12363                      (match_operand:SI 2 "const_int_operand" "i,i")))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "INTVAL (operands[2]) == 31
12366    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12367    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12368   "@
12369    {cltd|cdq}
12370    sar{l}\t{%2, %0|%0, %2}"
12371   [(set_attr "type" "imovx,ishift")
12372    (set_attr "prefix_0f" "0,*")
12373    (set_attr "length_immediate" "0,*")
12374    (set_attr "modrm" "0,1")
12375    (set_attr "mode" "SI")])
12376
12377 (define_insn "*ashrsi3_31_zext"
12378   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12379         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12380                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12383    && INTVAL (operands[2]) == 31
12384    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12385   "@
12386    {cltd|cdq}
12387    sar{l}\t{%2, %k0|%k0, %2}"
12388   [(set_attr "type" "imovx,ishift")
12389    (set_attr "prefix_0f" "0,*")
12390    (set_attr "length_immediate" "0,*")
12391    (set_attr "modrm" "0,1")
12392    (set_attr "mode" "SI")])
12393
12394 (define_expand "ashrsi3"
12395   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12396         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12397                      (match_operand:QI 2 "nonmemory_operand" "")))]
12398   ""
12399   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12400
12401 (define_insn "*ashrsi3_1_one_bit"
12402   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12403         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12404                      (match_operand:QI 2 "const1_operand" "")))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12407    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12408   "sar{l}\t%0"
12409   [(set_attr "type" "ishift")
12410    (set (attr "length")
12411      (if_then_else (match_operand:SI 0 "register_operand" "")
12412         (const_string "2")
12413         (const_string "*")))])
12414
12415 (define_insn "*ashrsi3_1_one_bit_zext"
12416   [(set (match_operand:DI 0 "register_operand" "=r")
12417         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12418                                      (match_operand:QI 2 "const1_operand" ""))))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "TARGET_64BIT
12421    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12422    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12423   "sar{l}\t%k0"
12424   [(set_attr "type" "ishift")
12425    (set_attr "length" "2")])
12426
12427 (define_insn "*ashrsi3_1"
12428   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12429         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12430                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12431    (clobber (reg:CC FLAGS_REG))]
12432   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12433   "@
12434    sar{l}\t{%2, %0|%0, %2}
12435    sar{l}\t{%b2, %0|%0, %b2}"
12436   [(set_attr "type" "ishift")
12437    (set_attr "mode" "SI")])
12438
12439 (define_insn "*ashrsi3_1_zext"
12440   [(set (match_operand:DI 0 "register_operand" "=r,r")
12441         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12442                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12445   "@
12446    sar{l}\t{%2, %k0|%k0, %2}
12447    sar{l}\t{%b2, %k0|%k0, %b2}"
12448   [(set_attr "type" "ishift")
12449    (set_attr "mode" "SI")])
12450
12451 ;; This pattern can't accept a variable shift count, since shifts by
12452 ;; zero don't affect the flags.  We assume that shifts by constant
12453 ;; zero are optimized away.
12454 (define_insn "*ashrsi3_one_bit_cmp"
12455   [(set (reg FLAGS_REG)
12456         (compare
12457           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12458                        (match_operand:QI 2 "const1_operand" ""))
12459           (const_int 0)))
12460    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12461         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12462   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12463    && ix86_match_ccmode (insn, CCGOCmode)
12464    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12465   "sar{l}\t%0"
12466   [(set_attr "type" "ishift")
12467    (set (attr "length")
12468      (if_then_else (match_operand:SI 0 "register_operand" "")
12469         (const_string "2")
12470         (const_string "*")))])
12471
12472 (define_insn "*ashrsi3_one_bit_cconly"
12473   [(set (reg FLAGS_REG)
12474         (compare
12475           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12476                        (match_operand:QI 2 "const1_operand" ""))
12477           (const_int 0)))
12478    (clobber (match_scratch:SI 0 "=r"))]
12479   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12480    && ix86_match_ccmode (insn, CCGOCmode)
12481    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12482   "sar{l}\t%0"
12483   [(set_attr "type" "ishift")
12484    (set_attr "length" "2")])
12485
12486 (define_insn "*ashrsi3_one_bit_cmp_zext"
12487   [(set (reg FLAGS_REG)
12488         (compare
12489           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12490                        (match_operand:QI 2 "const1_operand" ""))
12491           (const_int 0)))
12492    (set (match_operand:DI 0 "register_operand" "=r")
12493         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12494   "TARGET_64BIT
12495    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12496    && ix86_match_ccmode (insn, CCmode)
12497    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12498   "sar{l}\t%k0"
12499   [(set_attr "type" "ishift")
12500    (set_attr "length" "2")])
12501
12502 ;; This pattern can't accept a variable shift count, since shifts by
12503 ;; zero don't affect the flags.  We assume that shifts by constant
12504 ;; zero are optimized away.
12505 (define_insn "*ashrsi3_cmp"
12506   [(set (reg FLAGS_REG)
12507         (compare
12508           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12509                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12510           (const_int 0)))
12511    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12512         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12513   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12514    && ix86_match_ccmode (insn, CCGOCmode)
12515    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12516   "sar{l}\t{%2, %0|%0, %2}"
12517   [(set_attr "type" "ishift")
12518    (set_attr "mode" "SI")])
12519
12520 (define_insn "*ashrsi3_cconly"
12521   [(set (reg FLAGS_REG)
12522         (compare
12523           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12524                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12525           (const_int 0)))
12526    (clobber (match_scratch:SI 0 "=r"))]
12527   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12528    && ix86_match_ccmode (insn, CCGOCmode)
12529    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12530   "sar{l}\t{%2, %0|%0, %2}"
12531   [(set_attr "type" "ishift")
12532    (set_attr "mode" "SI")])
12533
12534 (define_insn "*ashrsi3_cmp_zext"
12535   [(set (reg FLAGS_REG)
12536         (compare
12537           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12538                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12539           (const_int 0)))
12540    (set (match_operand:DI 0 "register_operand" "=r")
12541         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12542   "TARGET_64BIT
12543    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12544    && ix86_match_ccmode (insn, CCGOCmode)
12545    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546   "sar{l}\t{%2, %k0|%k0, %2}"
12547   [(set_attr "type" "ishift")
12548    (set_attr "mode" "SI")])
12549
12550 (define_expand "ashrhi3"
12551   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12552         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12553                      (match_operand:QI 2 "nonmemory_operand" "")))]
12554   "TARGET_HIMODE_MATH"
12555   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12556
12557 (define_insn "*ashrhi3_1_one_bit"
12558   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12559         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12560                      (match_operand:QI 2 "const1_operand" "")))
12561    (clobber (reg:CC FLAGS_REG))]
12562   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12563    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12564   "sar{w}\t%0"
12565   [(set_attr "type" "ishift")
12566    (set (attr "length")
12567      (if_then_else (match_operand 0 "register_operand" "")
12568         (const_string "2")
12569         (const_string "*")))])
12570
12571 (define_insn "*ashrhi3_1"
12572   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12573         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12574                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12575    (clobber (reg:CC FLAGS_REG))]
12576   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12577   "@
12578    sar{w}\t{%2, %0|%0, %2}
12579    sar{w}\t{%b2, %0|%0, %b2}"
12580   [(set_attr "type" "ishift")
12581    (set_attr "mode" "HI")])
12582
12583 ;; This pattern can't accept a variable shift count, since shifts by
12584 ;; zero don't affect the flags.  We assume that shifts by constant
12585 ;; zero are optimized away.
12586 (define_insn "*ashrhi3_one_bit_cmp"
12587   [(set (reg FLAGS_REG)
12588         (compare
12589           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12590                        (match_operand:QI 2 "const1_operand" ""))
12591           (const_int 0)))
12592    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12593         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
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")
12600      (if_then_else (match_operand 0 "register_operand" "")
12601         (const_string "2")
12602         (const_string "*")))])
12603
12604 (define_insn "*ashrhi3_one_bit_cconly"
12605   [(set (reg FLAGS_REG)
12606         (compare
12607           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12608                        (match_operand:QI 2 "const1_operand" ""))
12609           (const_int 0)))
12610    (clobber (match_scratch:HI 0 "=r"))]
12611   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12612    && ix86_match_ccmode (insn, CCGOCmode)
12613    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12614   "sar{w}\t%0"
12615   [(set_attr "type" "ishift")
12616    (set_attr "length" "2")])
12617
12618 ;; This pattern can't accept a variable shift count, since shifts by
12619 ;; zero don't affect the flags.  We assume that shifts by constant
12620 ;; zero are optimized away.
12621 (define_insn "*ashrhi3_cmp"
12622   [(set (reg FLAGS_REG)
12623         (compare
12624           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12625                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12626           (const_int 0)))
12627    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12628         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12629   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12630    && ix86_match_ccmode (insn, CCGOCmode)
12631    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12632   "sar{w}\t{%2, %0|%0, %2}"
12633   [(set_attr "type" "ishift")
12634    (set_attr "mode" "HI")])
12635
12636 (define_insn "*ashrhi3_cconly"
12637   [(set (reg FLAGS_REG)
12638         (compare
12639           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12640                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12641           (const_int 0)))
12642    (clobber (match_scratch:HI 0 "=r"))]
12643   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12644    && ix86_match_ccmode (insn, CCGOCmode)
12645    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12646   "sar{w}\t{%2, %0|%0, %2}"
12647   [(set_attr "type" "ishift")
12648    (set_attr "mode" "HI")])
12649
12650 (define_expand "ashrqi3"
12651   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12652         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12653                      (match_operand:QI 2 "nonmemory_operand" "")))]
12654   "TARGET_QIMODE_MATH"
12655   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12656
12657 (define_insn "*ashrqi3_1_one_bit"
12658   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12659         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12660                      (match_operand:QI 2 "const1_operand" "")))
12661    (clobber (reg:CC FLAGS_REG))]
12662   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12663    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12664   "sar{b}\t%0"
12665   [(set_attr "type" "ishift")
12666    (set (attr "length")
12667      (if_then_else (match_operand 0 "register_operand" "")
12668         (const_string "2")
12669         (const_string "*")))])
12670
12671 (define_insn "*ashrqi3_1_one_bit_slp"
12672   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12673         (ashiftrt:QI (match_dup 0)
12674                      (match_operand:QI 1 "const1_operand" "")))
12675    (clobber (reg:CC FLAGS_REG))]
12676   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12677    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12678    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12679   "sar{b}\t%0"
12680   [(set_attr "type" "ishift1")
12681    (set (attr "length")
12682      (if_then_else (match_operand 0 "register_operand" "")
12683         (const_string "2")
12684         (const_string "*")))])
12685
12686 (define_insn "*ashrqi3_1"
12687   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12688         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12689                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12690    (clobber (reg:CC FLAGS_REG))]
12691   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12692   "@
12693    sar{b}\t{%2, %0|%0, %2}
12694    sar{b}\t{%b2, %0|%0, %b2}"
12695   [(set_attr "type" "ishift")
12696    (set_attr "mode" "QI")])
12697
12698 (define_insn "*ashrqi3_1_slp"
12699   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12700         (ashiftrt:QI (match_dup 0)
12701                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12702    (clobber (reg:CC FLAGS_REG))]
12703   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12704    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12705   "@
12706    sar{b}\t{%1, %0|%0, %1}
12707    sar{b}\t{%b1, %0|%0, %b1}"
12708   [(set_attr "type" "ishift1")
12709    (set_attr "mode" "QI")])
12710
12711 ;; This pattern can't accept a variable shift count, since shifts by
12712 ;; zero don't affect the flags.  We assume that shifts by constant
12713 ;; zero are optimized away.
12714 (define_insn "*ashrqi3_one_bit_cmp"
12715   [(set (reg FLAGS_REG)
12716         (compare
12717           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12718                        (match_operand:QI 2 "const1_operand" "I"))
12719           (const_int 0)))
12720    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12721         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12722   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12723    && ix86_match_ccmode (insn, CCGOCmode)
12724    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12725   "sar{b}\t%0"
12726   [(set_attr "type" "ishift")
12727    (set (attr "length")
12728      (if_then_else (match_operand 0 "register_operand" "")
12729         (const_string "2")
12730         (const_string "*")))])
12731
12732 (define_insn "*ashrqi3_one_bit_cconly"
12733   [(set (reg FLAGS_REG)
12734         (compare
12735           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12736                        (match_operand:QI 2 "const1_operand" ""))
12737           (const_int 0)))
12738    (clobber (match_scratch:QI 0 "=q"))]
12739   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12740    && ix86_match_ccmode (insn, CCGOCmode)
12741    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12742   "sar{b}\t%0"
12743   [(set_attr "type" "ishift")
12744    (set_attr "length" "2")])
12745
12746 ;; This pattern can't accept a variable shift count, since shifts by
12747 ;; zero don't affect the flags.  We assume that shifts by constant
12748 ;; zero are optimized away.
12749 (define_insn "*ashrqi3_cmp"
12750   [(set (reg FLAGS_REG)
12751         (compare
12752           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12753                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12754           (const_int 0)))
12755    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12756         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12757   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12758    && ix86_match_ccmode (insn, CCGOCmode)
12759    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12760   "sar{b}\t{%2, %0|%0, %2}"
12761   [(set_attr "type" "ishift")
12762    (set_attr "mode" "QI")])
12763
12764 (define_insn "*ashrqi3_cconly"
12765   [(set (reg FLAGS_REG)
12766         (compare
12767           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12768                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12769           (const_int 0)))
12770    (clobber (match_scratch:QI 0 "=q"))]
12771   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12772    && ix86_match_ccmode (insn, CCGOCmode)
12773    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12774   "sar{b}\t{%2, %0|%0, %2}"
12775   [(set_attr "type" "ishift")
12776    (set_attr "mode" "QI")])
12777
12778 \f
12779 ;; Logical shift instructions
12780
12781 ;; See comment above `ashldi3' about how this works.
12782
12783 (define_expand "lshrti3"
12784   [(set (match_operand:TI 0 "register_operand" "")
12785         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12786                      (match_operand:QI 2 "nonmemory_operand" "")))]
12787   "TARGET_64BIT"
12788   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12789
12790 ;; This pattern must be defined before *lshrti3_1 to prevent
12791 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12792
12793 (define_insn "*avx_lshrti3"
12794   [(set (match_operand:TI 0 "register_operand" "=x")
12795         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12796                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12797   "TARGET_AVX"
12798 {
12799   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12800   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12801 }
12802   [(set_attr "type" "sseishft")
12803    (set_attr "prefix" "vex")
12804    (set_attr "mode" "TI")])
12805
12806 (define_insn "sse2_lshrti3"
12807   [(set (match_operand:TI 0 "register_operand" "=x")
12808         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12809                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12810   "TARGET_SSE2"
12811 {
12812   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12813   return "psrldq\t{%2, %0|%0, %2}";
12814 }
12815   [(set_attr "type" "sseishft")
12816    (set_attr "prefix_data16" "1")
12817    (set_attr "mode" "TI")])
12818
12819 (define_insn "*lshrti3_1"
12820   [(set (match_operand:TI 0 "register_operand" "=r")
12821         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12822                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12823    (clobber (reg:CC FLAGS_REG))]
12824   "TARGET_64BIT"
12825   "#"
12826   [(set_attr "type" "multi")])
12827
12828 (define_peephole2
12829   [(match_scratch:DI 3 "r")
12830    (parallel [(set (match_operand:TI 0 "register_operand" "")
12831                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12832                                 (match_operand:QI 2 "nonmemory_operand" "")))
12833               (clobber (reg:CC FLAGS_REG))])
12834    (match_dup 3)]
12835   "TARGET_64BIT"
12836   [(const_int 0)]
12837   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12838
12839 (define_split
12840   [(set (match_operand:TI 0 "register_operand" "")
12841         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12842                      (match_operand:QI 2 "nonmemory_operand" "")))
12843    (clobber (reg:CC FLAGS_REG))]
12844   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12845                     ? epilogue_completed : reload_completed)"
12846   [(const_int 0)]
12847   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12848
12849 (define_expand "lshrdi3"
12850   [(set (match_operand:DI 0 "shiftdi_operand" "")
12851         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12852                      (match_operand:QI 2 "nonmemory_operand" "")))]
12853   ""
12854   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12855
12856 (define_insn "*lshrdi3_1_one_bit_rex64"
12857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12858         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12859                      (match_operand:QI 2 "const1_operand" "")))
12860    (clobber (reg:CC FLAGS_REG))]
12861   "TARGET_64BIT
12862    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12863    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12864   "shr{q}\t%0"
12865   [(set_attr "type" "ishift")
12866    (set (attr "length")
12867      (if_then_else (match_operand:DI 0 "register_operand" "")
12868         (const_string "2")
12869         (const_string "*")))])
12870
12871 (define_insn "*lshrdi3_1_rex64"
12872   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12873         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12874                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12875    (clobber (reg:CC FLAGS_REG))]
12876   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877   "@
12878    shr{q}\t{%2, %0|%0, %2}
12879    shr{q}\t{%b2, %0|%0, %b2}"
12880   [(set_attr "type" "ishift")
12881    (set_attr "mode" "DI")])
12882
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags.  We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12887   [(set (reg FLAGS_REG)
12888         (compare
12889           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12890                        (match_operand:QI 2 "const1_operand" ""))
12891           (const_int 0)))
12892    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12893         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12894   "TARGET_64BIT
12895    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12896    && ix86_match_ccmode (insn, CCGOCmode)
12897    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898   "shr{q}\t%0"
12899   [(set_attr "type" "ishift")
12900    (set (attr "length")
12901      (if_then_else (match_operand:DI 0 "register_operand" "")
12902         (const_string "2")
12903         (const_string "*")))])
12904
12905 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12906   [(set (reg FLAGS_REG)
12907         (compare
12908           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12909                        (match_operand:QI 2 "const1_operand" ""))
12910           (const_int 0)))
12911    (clobber (match_scratch:DI 0 "=r"))]
12912   "TARGET_64BIT
12913    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12914    && ix86_match_ccmode (insn, CCGOCmode)
12915    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12916   "shr{q}\t%0"
12917   [(set_attr "type" "ishift")
12918    (set_attr "length" "2")])
12919
12920 ;; This pattern can't accept a variable shift count, since shifts by
12921 ;; zero don't affect the flags.  We assume that shifts by constant
12922 ;; zero are optimized away.
12923 (define_insn "*lshrdi3_cmp_rex64"
12924   [(set (reg FLAGS_REG)
12925         (compare
12926           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12927                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12928           (const_int 0)))
12929    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12930         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12931   "TARGET_64BIT
12932    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12933    && ix86_match_ccmode (insn, CCGOCmode)
12934    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12935   "shr{q}\t{%2, %0|%0, %2}"
12936   [(set_attr "type" "ishift")
12937    (set_attr "mode" "DI")])
12938
12939 (define_insn "*lshrdi3_cconly_rex64"
12940   [(set (reg FLAGS_REG)
12941         (compare
12942           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12944           (const_int 0)))
12945    (clobber (match_scratch:DI 0 "=r"))]
12946   "TARGET_64BIT
12947    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12948    && ix86_match_ccmode (insn, CCGOCmode)
12949    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12950   "shr{q}\t{%2, %0|%0, %2}"
12951   [(set_attr "type" "ishift")
12952    (set_attr "mode" "DI")])
12953
12954 (define_insn "*lshrdi3_1"
12955   [(set (match_operand:DI 0 "register_operand" "=r")
12956         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12957                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12958    (clobber (reg:CC FLAGS_REG))]
12959   "!TARGET_64BIT"
12960   "#"
12961   [(set_attr "type" "multi")])
12962
12963 ;; By default we don't ask for a scratch register, because when DImode
12964 ;; values are manipulated, registers are already at a premium.  But if
12965 ;; we have one handy, we won't turn it away.
12966 (define_peephole2
12967   [(match_scratch:SI 3 "r")
12968    (parallel [(set (match_operand:DI 0 "register_operand" "")
12969                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12970                                 (match_operand:QI 2 "nonmemory_operand" "")))
12971               (clobber (reg:CC FLAGS_REG))])
12972    (match_dup 3)]
12973   "!TARGET_64BIT && TARGET_CMOVE"
12974   [(const_int 0)]
12975   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12976
12977 (define_split
12978   [(set (match_operand:DI 0 "register_operand" "")
12979         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12980                      (match_operand:QI 2 "nonmemory_operand" "")))
12981    (clobber (reg:CC FLAGS_REG))]
12982   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12983                      ? epilogue_completed : reload_completed)"
12984   [(const_int 0)]
12985   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12986
12987 (define_expand "lshrsi3"
12988   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12989         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12990                      (match_operand:QI 2 "nonmemory_operand" "")))]
12991   ""
12992   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12993
12994 (define_insn "*lshrsi3_1_one_bit"
12995   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12996         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12997                      (match_operand:QI 2 "const1_operand" "")))
12998    (clobber (reg:CC FLAGS_REG))]
12999   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13000    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13001   "shr{l}\t%0"
13002   [(set_attr "type" "ishift")
13003    (set (attr "length")
13004      (if_then_else (match_operand:SI 0 "register_operand" "")
13005         (const_string "2")
13006         (const_string "*")))])
13007
13008 (define_insn "*lshrsi3_1_one_bit_zext"
13009   [(set (match_operand:DI 0 "register_operand" "=r")
13010         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13011                      (match_operand:QI 2 "const1_operand" "")))
13012    (clobber (reg:CC FLAGS_REG))]
13013   "TARGET_64BIT
13014    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13015    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13016   "shr{l}\t%k0"
13017   [(set_attr "type" "ishift")
13018    (set_attr "length" "2")])
13019
13020 (define_insn "*lshrsi3_1"
13021   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13022         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13023                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024    (clobber (reg:CC FLAGS_REG))]
13025   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13026   "@
13027    shr{l}\t{%2, %0|%0, %2}
13028    shr{l}\t{%b2, %0|%0, %b2}"
13029   [(set_attr "type" "ishift")
13030    (set_attr "mode" "SI")])
13031
13032 (define_insn "*lshrsi3_1_zext"
13033   [(set (match_operand:DI 0 "register_operand" "=r,r")
13034         (zero_extend:DI
13035           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13036                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13037    (clobber (reg:CC FLAGS_REG))]
13038   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13039   "@
13040    shr{l}\t{%2, %k0|%k0, %2}
13041    shr{l}\t{%b2, %k0|%k0, %b2}"
13042   [(set_attr "type" "ishift")
13043    (set_attr "mode" "SI")])
13044
13045 ;; This pattern can't accept a variable shift count, since shifts by
13046 ;; zero don't affect the flags.  We assume that shifts by constant
13047 ;; zero are optimized away.
13048 (define_insn "*lshrsi3_one_bit_cmp"
13049   [(set (reg FLAGS_REG)
13050         (compare
13051           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13052                        (match_operand:QI 2 "const1_operand" ""))
13053           (const_int 0)))
13054    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13055         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13056   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13057    && ix86_match_ccmode (insn, CCGOCmode)
13058    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13059   "shr{l}\t%0"
13060   [(set_attr "type" "ishift")
13061    (set (attr "length")
13062      (if_then_else (match_operand:SI 0 "register_operand" "")
13063         (const_string "2")
13064         (const_string "*")))])
13065
13066 (define_insn "*lshrsi3_one_bit_cconly"
13067   [(set (reg FLAGS_REG)
13068         (compare
13069           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13070                        (match_operand:QI 2 "const1_operand" ""))
13071           (const_int 0)))
13072    (clobber (match_scratch:SI 0 "=r"))]
13073   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13074    && ix86_match_ccmode (insn, CCGOCmode)
13075    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13076   "shr{l}\t%0"
13077   [(set_attr "type" "ishift")
13078    (set_attr "length" "2")])
13079
13080 (define_insn "*lshrsi3_cmp_one_bit_zext"
13081   [(set (reg FLAGS_REG)
13082         (compare
13083           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13084                        (match_operand:QI 2 "const1_operand" ""))
13085           (const_int 0)))
13086    (set (match_operand:DI 0 "register_operand" "=r")
13087         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13088   "TARGET_64BIT
13089    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13090    && ix86_match_ccmode (insn, CCGOCmode)
13091    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13092   "shr{l}\t%k0"
13093   [(set_attr "type" "ishift")
13094    (set_attr "length" "2")])
13095
13096 ;; This pattern can't accept a variable shift count, since shifts by
13097 ;; zero don't affect the flags.  We assume that shifts by constant
13098 ;; zero are optimized away.
13099 (define_insn "*lshrsi3_cmp"
13100   [(set (reg FLAGS_REG)
13101         (compare
13102           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13103                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13104           (const_int 0)))
13105    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13106         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13107   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13108    && ix86_match_ccmode (insn, CCGOCmode)
13109    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13110   "shr{l}\t{%2, %0|%0, %2}"
13111   [(set_attr "type" "ishift")
13112    (set_attr "mode" "SI")])
13113
13114 (define_insn "*lshrsi3_cconly"
13115   [(set (reg FLAGS_REG)
13116       (compare
13117         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13118                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13119         (const_int 0)))
13120    (clobber (match_scratch:SI 0 "=r"))]
13121   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13122    && ix86_match_ccmode (insn, CCGOCmode)
13123    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13124   "shr{l}\t{%2, %0|%0, %2}"
13125   [(set_attr "type" "ishift")
13126    (set_attr "mode" "SI")])
13127
13128 (define_insn "*lshrsi3_cmp_zext"
13129   [(set (reg FLAGS_REG)
13130         (compare
13131           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13132                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13133           (const_int 0)))
13134    (set (match_operand:DI 0 "register_operand" "=r")
13135         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13136   "TARGET_64BIT
13137    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13138    && ix86_match_ccmode (insn, CCGOCmode)
13139    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140   "shr{l}\t{%2, %k0|%k0, %2}"
13141   [(set_attr "type" "ishift")
13142    (set_attr "mode" "SI")])
13143
13144 (define_expand "lshrhi3"
13145   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13146         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13147                      (match_operand:QI 2 "nonmemory_operand" "")))]
13148   "TARGET_HIMODE_MATH"
13149   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13150
13151 (define_insn "*lshrhi3_1_one_bit"
13152   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13153         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13154                      (match_operand:QI 2 "const1_operand" "")))
13155    (clobber (reg:CC FLAGS_REG))]
13156   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13157    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13158   "shr{w}\t%0"
13159   [(set_attr "type" "ishift")
13160    (set (attr "length")
13161      (if_then_else (match_operand 0 "register_operand" "")
13162         (const_string "2")
13163         (const_string "*")))])
13164
13165 (define_insn "*lshrhi3_1"
13166   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13167         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13168                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13169    (clobber (reg:CC FLAGS_REG))]
13170   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13171   "@
13172    shr{w}\t{%2, %0|%0, %2}
13173    shr{w}\t{%b2, %0|%0, %b2}"
13174   [(set_attr "type" "ishift")
13175    (set_attr "mode" "HI")])
13176
13177 ;; This pattern can't accept a variable shift count, since shifts by
13178 ;; zero don't affect the flags.  We assume that shifts by constant
13179 ;; zero are optimized away.
13180 (define_insn "*lshrhi3_one_bit_cmp"
13181   [(set (reg FLAGS_REG)
13182         (compare
13183           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13184                        (match_operand:QI 2 "const1_operand" ""))
13185           (const_int 0)))
13186    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13187         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13188   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13189    && ix86_match_ccmode (insn, CCGOCmode)
13190    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13191   "shr{w}\t%0"
13192   [(set_attr "type" "ishift")
13193    (set (attr "length")
13194      (if_then_else (match_operand:SI 0 "register_operand" "")
13195         (const_string "2")
13196         (const_string "*")))])
13197
13198 (define_insn "*lshrhi3_one_bit_cconly"
13199   [(set (reg FLAGS_REG)
13200         (compare
13201           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13202                        (match_operand:QI 2 "const1_operand" ""))
13203           (const_int 0)))
13204    (clobber (match_scratch:HI 0 "=r"))]
13205   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13206    && ix86_match_ccmode (insn, CCGOCmode)
13207    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13208   "shr{w}\t%0"
13209   [(set_attr "type" "ishift")
13210    (set_attr "length" "2")])
13211
13212 ;; This pattern can't accept a variable shift count, since shifts by
13213 ;; zero don't affect the flags.  We assume that shifts by constant
13214 ;; zero are optimized away.
13215 (define_insn "*lshrhi3_cmp"
13216   [(set (reg FLAGS_REG)
13217         (compare
13218           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13219                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13220           (const_int 0)))
13221    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13222         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13223   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13224    && ix86_match_ccmode (insn, CCGOCmode)
13225    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13226   "shr{w}\t{%2, %0|%0, %2}"
13227   [(set_attr "type" "ishift")
13228    (set_attr "mode" "HI")])
13229
13230 (define_insn "*lshrhi3_cconly"
13231   [(set (reg FLAGS_REG)
13232         (compare
13233           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13234                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13235           (const_int 0)))
13236    (clobber (match_scratch:HI 0 "=r"))]
13237   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13238    && ix86_match_ccmode (insn, CCGOCmode)
13239    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13240   "shr{w}\t{%2, %0|%0, %2}"
13241   [(set_attr "type" "ishift")
13242    (set_attr "mode" "HI")])
13243
13244 (define_expand "lshrqi3"
13245   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13246         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13247                      (match_operand:QI 2 "nonmemory_operand" "")))]
13248   "TARGET_QIMODE_MATH"
13249   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13250
13251 (define_insn "*lshrqi3_1_one_bit"
13252   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13253         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13254                      (match_operand:QI 2 "const1_operand" "")))
13255    (clobber (reg:CC FLAGS_REG))]
13256   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13257    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13258   "shr{b}\t%0"
13259   [(set_attr "type" "ishift")
13260    (set (attr "length")
13261      (if_then_else (match_operand 0 "register_operand" "")
13262         (const_string "2")
13263         (const_string "*")))])
13264
13265 (define_insn "*lshrqi3_1_one_bit_slp"
13266   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13267         (lshiftrt:QI (match_dup 0)
13268                      (match_operand:QI 1 "const1_operand" "")))
13269    (clobber (reg:CC FLAGS_REG))]
13270   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13271    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13272   "shr{b}\t%0"
13273   [(set_attr "type" "ishift1")
13274    (set (attr "length")
13275      (if_then_else (match_operand 0 "register_operand" "")
13276         (const_string "2")
13277         (const_string "*")))])
13278
13279 (define_insn "*lshrqi3_1"
13280   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13281         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13282                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13283    (clobber (reg:CC FLAGS_REG))]
13284   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13285   "@
13286    shr{b}\t{%2, %0|%0, %2}
13287    shr{b}\t{%b2, %0|%0, %b2}"
13288   [(set_attr "type" "ishift")
13289    (set_attr "mode" "QI")])
13290
13291 (define_insn "*lshrqi3_1_slp"
13292   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293         (lshiftrt:QI (match_dup 0)
13294                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13297    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13298   "@
13299    shr{b}\t{%1, %0|%0, %1}
13300    shr{b}\t{%b1, %0|%0, %b1}"
13301   [(set_attr "type" "ishift1")
13302    (set_attr "mode" "QI")])
13303
13304 ;; This pattern can't accept a variable shift count, since shifts by
13305 ;; zero don't affect the flags.  We assume that shifts by constant
13306 ;; zero are optimized away.
13307 (define_insn "*lshrqi2_one_bit_cmp"
13308   [(set (reg FLAGS_REG)
13309         (compare
13310           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13311                        (match_operand:QI 2 "const1_operand" ""))
13312           (const_int 0)))
13313    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13314         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13315   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13316    && ix86_match_ccmode (insn, CCGOCmode)
13317    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13318   "shr{b}\t%0"
13319   [(set_attr "type" "ishift")
13320    (set (attr "length")
13321      (if_then_else (match_operand:SI 0 "register_operand" "")
13322         (const_string "2")
13323         (const_string "*")))])
13324
13325 (define_insn "*lshrqi2_one_bit_cconly"
13326   [(set (reg FLAGS_REG)
13327         (compare
13328           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13329                        (match_operand:QI 2 "const1_operand" ""))
13330           (const_int 0)))
13331    (clobber (match_scratch:QI 0 "=q"))]
13332   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13333    && ix86_match_ccmode (insn, CCGOCmode)
13334    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13335   "shr{b}\t%0"
13336   [(set_attr "type" "ishift")
13337    (set_attr "length" "2")])
13338
13339 ;; This pattern can't accept a variable shift count, since shifts by
13340 ;; zero don't affect the flags.  We assume that shifts by constant
13341 ;; zero are optimized away.
13342 (define_insn "*lshrqi2_cmp"
13343   [(set (reg FLAGS_REG)
13344         (compare
13345           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13346                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13347           (const_int 0)))
13348    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13349         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13350   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13351    && ix86_match_ccmode (insn, CCGOCmode)
13352    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13353   "shr{b}\t{%2, %0|%0, %2}"
13354   [(set_attr "type" "ishift")
13355    (set_attr "mode" "QI")])
13356
13357 (define_insn "*lshrqi2_cconly"
13358   [(set (reg FLAGS_REG)
13359         (compare
13360           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13361                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13362           (const_int 0)))
13363    (clobber (match_scratch:QI 0 "=q"))]
13364   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13365    && ix86_match_ccmode (insn, CCGOCmode)
13366    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13367   "shr{b}\t{%2, %0|%0, %2}"
13368   [(set_attr "type" "ishift")
13369    (set_attr "mode" "QI")])
13370 \f
13371 ;; Rotate instructions
13372
13373 (define_expand "rotldi3"
13374   [(set (match_operand:DI 0 "shiftdi_operand" "")
13375         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13376                    (match_operand:QI 2 "nonmemory_operand" "")))]
13377  ""
13378 {
13379   if (TARGET_64BIT)
13380     {
13381       ix86_expand_binary_operator (ROTATE, DImode, operands);
13382       DONE;
13383     }
13384   if (!const_1_to_31_operand (operands[2], VOIDmode))
13385     FAIL;
13386   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13387   DONE;
13388 })
13389
13390 ;; Implement rotation using two double-precision shift instructions
13391 ;; and a scratch register.
13392 (define_insn_and_split "ix86_rotldi3"
13393  [(set (match_operand:DI 0 "register_operand" "=r")
13394        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13395                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13396   (clobber (reg:CC FLAGS_REG))
13397   (clobber (match_scratch:SI 3 "=&r"))]
13398  "!TARGET_64BIT"
13399  ""
13400  "&& reload_completed"
13401  [(set (match_dup 3) (match_dup 4))
13402   (parallel
13403    [(set (match_dup 4)
13404          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13405                  (lshiftrt:SI (match_dup 5)
13406                               (minus:QI (const_int 32) (match_dup 2)))))
13407     (clobber (reg:CC FLAGS_REG))])
13408   (parallel
13409    [(set (match_dup 5)
13410          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13411                  (lshiftrt:SI (match_dup 3)
13412                               (minus:QI (const_int 32) (match_dup 2)))))
13413     (clobber (reg:CC FLAGS_REG))])]
13414  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13415
13416 (define_insn "*rotlsi3_1_one_bit_rex64"
13417   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13418         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13419                    (match_operand:QI 2 "const1_operand" "")))
13420    (clobber (reg:CC FLAGS_REG))]
13421   "TARGET_64BIT
13422    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13423    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13424   "rol{q}\t%0"
13425   [(set_attr "type" "rotate")
13426    (set (attr "length")
13427      (if_then_else (match_operand:DI 0 "register_operand" "")
13428         (const_string "2")
13429         (const_string "*")))])
13430
13431 (define_insn "*rotldi3_1_rex64"
13432   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13433         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13434                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13435    (clobber (reg:CC FLAGS_REG))]
13436   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13437   "@
13438    rol{q}\t{%2, %0|%0, %2}
13439    rol{q}\t{%b2, %0|%0, %b2}"
13440   [(set_attr "type" "rotate")
13441    (set_attr "mode" "DI")])
13442
13443 (define_expand "rotlsi3"
13444   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13445         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13446                    (match_operand:QI 2 "nonmemory_operand" "")))]
13447   ""
13448   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13449
13450 (define_insn "*rotlsi3_1_one_bit"
13451   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13452         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13453                    (match_operand:QI 2 "const1_operand" "")))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13456    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13457   "rol{l}\t%0"
13458   [(set_attr "type" "rotate")
13459    (set (attr "length")
13460      (if_then_else (match_operand:SI 0 "register_operand" "")
13461         (const_string "2")
13462         (const_string "*")))])
13463
13464 (define_insn "*rotlsi3_1_one_bit_zext"
13465   [(set (match_operand:DI 0 "register_operand" "=r")
13466         (zero_extend:DI
13467           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13468                      (match_operand:QI 2 "const1_operand" ""))))
13469    (clobber (reg:CC FLAGS_REG))]
13470   "TARGET_64BIT
13471    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13472    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13473   "rol{l}\t%k0"
13474   [(set_attr "type" "rotate")
13475    (set_attr "length" "2")])
13476
13477 (define_insn "*rotlsi3_1"
13478   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13479         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13480                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13481    (clobber (reg:CC FLAGS_REG))]
13482   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13483   "@
13484    rol{l}\t{%2, %0|%0, %2}
13485    rol{l}\t{%b2, %0|%0, %b2}"
13486   [(set_attr "type" "rotate")
13487    (set_attr "mode" "SI")])
13488
13489 (define_insn "*rotlsi3_1_zext"
13490   [(set (match_operand:DI 0 "register_operand" "=r,r")
13491         (zero_extend:DI
13492           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13493                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13494    (clobber (reg:CC FLAGS_REG))]
13495   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13496   "@
13497    rol{l}\t{%2, %k0|%k0, %2}
13498    rol{l}\t{%b2, %k0|%k0, %b2}"
13499   [(set_attr "type" "rotate")
13500    (set_attr "mode" "SI")])
13501
13502 (define_expand "rotlhi3"
13503   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13504         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13505                    (match_operand:QI 2 "nonmemory_operand" "")))]
13506   "TARGET_HIMODE_MATH"
13507   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13508
13509 (define_insn "*rotlhi3_1_one_bit"
13510   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13511         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13512                    (match_operand:QI 2 "const1_operand" "")))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13515    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13516   "rol{w}\t%0"
13517   [(set_attr "type" "rotate")
13518    (set (attr "length")
13519      (if_then_else (match_operand 0 "register_operand" "")
13520         (const_string "2")
13521         (const_string "*")))])
13522
13523 (define_insn "*rotlhi3_1"
13524   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13525         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13526                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13527    (clobber (reg:CC FLAGS_REG))]
13528   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13529   "@
13530    rol{w}\t{%2, %0|%0, %2}
13531    rol{w}\t{%b2, %0|%0, %b2}"
13532   [(set_attr "type" "rotate")
13533    (set_attr "mode" "HI")])
13534
13535 (define_split
13536  [(set (match_operand:HI 0 "register_operand" "")
13537        (rotate:HI (match_dup 0) (const_int 8)))
13538   (clobber (reg:CC FLAGS_REG))]
13539  "reload_completed"
13540  [(parallel [(set (strict_low_part (match_dup 0))
13541                   (bswap:HI (match_dup 0)))
13542              (clobber (reg:CC FLAGS_REG))])]
13543  "")
13544
13545 (define_expand "rotlqi3"
13546   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13547         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13548                    (match_operand:QI 2 "nonmemory_operand" "")))]
13549   "TARGET_QIMODE_MATH"
13550   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13551
13552 (define_insn "*rotlqi3_1_one_bit_slp"
13553   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13554         (rotate:QI (match_dup 0)
13555                    (match_operand:QI 1 "const1_operand" "")))
13556    (clobber (reg:CC FLAGS_REG))]
13557   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13558    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13559   "rol{b}\t%0"
13560   [(set_attr "type" "rotate1")
13561    (set (attr "length")
13562      (if_then_else (match_operand 0 "register_operand" "")
13563         (const_string "2")
13564         (const_string "*")))])
13565
13566 (define_insn "*rotlqi3_1_one_bit"
13567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13568         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13569                    (match_operand:QI 2 "const1_operand" "")))
13570    (clobber (reg:CC FLAGS_REG))]
13571   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13572    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13573   "rol{b}\t%0"
13574   [(set_attr "type" "rotate")
13575    (set (attr "length")
13576      (if_then_else (match_operand 0 "register_operand" "")
13577         (const_string "2")
13578         (const_string "*")))])
13579
13580 (define_insn "*rotlqi3_1_slp"
13581   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13582         (rotate:QI (match_dup 0)
13583                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13584    (clobber (reg:CC FLAGS_REG))]
13585   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13586    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13587   "@
13588    rol{b}\t{%1, %0|%0, %1}
13589    rol{b}\t{%b1, %0|%0, %b1}"
13590   [(set_attr "type" "rotate1")
13591    (set_attr "mode" "QI")])
13592
13593 (define_insn "*rotlqi3_1"
13594   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13595         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13596                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13597    (clobber (reg:CC FLAGS_REG))]
13598   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13599   "@
13600    rol{b}\t{%2, %0|%0, %2}
13601    rol{b}\t{%b2, %0|%0, %b2}"
13602   [(set_attr "type" "rotate")
13603    (set_attr "mode" "QI")])
13604
13605 (define_expand "rotrdi3"
13606   [(set (match_operand:DI 0 "shiftdi_operand" "")
13607         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13608                    (match_operand:QI 2 "nonmemory_operand" "")))]
13609  ""
13610 {
13611   if (TARGET_64BIT)
13612     {
13613       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13614       DONE;
13615     }
13616   if (!const_1_to_31_operand (operands[2], VOIDmode))
13617     FAIL;
13618   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13619   DONE;
13620 })
13621
13622 ;; Implement rotation using two double-precision shift instructions
13623 ;; and a scratch register.
13624 (define_insn_and_split "ix86_rotrdi3"
13625  [(set (match_operand:DI 0 "register_operand" "=r")
13626        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13627                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13628   (clobber (reg:CC FLAGS_REG))
13629   (clobber (match_scratch:SI 3 "=&r"))]
13630  "!TARGET_64BIT"
13631  ""
13632  "&& reload_completed"
13633  [(set (match_dup 3) (match_dup 4))
13634   (parallel
13635    [(set (match_dup 4)
13636          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13637                  (ashift:SI (match_dup 5)
13638                             (minus:QI (const_int 32) (match_dup 2)))))
13639     (clobber (reg:CC FLAGS_REG))])
13640   (parallel
13641    [(set (match_dup 5)
13642          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13643                  (ashift:SI (match_dup 3)
13644                             (minus:QI (const_int 32) (match_dup 2)))))
13645     (clobber (reg:CC FLAGS_REG))])]
13646  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13647
13648 (define_insn "*rotrdi3_1_one_bit_rex64"
13649   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13650         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13651                      (match_operand:QI 2 "const1_operand" "")))
13652    (clobber (reg:CC FLAGS_REG))]
13653   "TARGET_64BIT
13654    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13655    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13656   "ror{q}\t%0"
13657   [(set_attr "type" "rotate")
13658    (set (attr "length")
13659      (if_then_else (match_operand:DI 0 "register_operand" "")
13660         (const_string "2")
13661         (const_string "*")))])
13662
13663 (define_insn "*rotrdi3_1_rex64"
13664   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13665         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13666                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13667    (clobber (reg:CC FLAGS_REG))]
13668   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13669   "@
13670    ror{q}\t{%2, %0|%0, %2}
13671    ror{q}\t{%b2, %0|%0, %b2}"
13672   [(set_attr "type" "rotate")
13673    (set_attr "mode" "DI")])
13674
13675 (define_expand "rotrsi3"
13676   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13677         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13678                      (match_operand:QI 2 "nonmemory_operand" "")))]
13679   ""
13680   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13681
13682 (define_insn "*rotrsi3_1_one_bit"
13683   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13684         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13685                      (match_operand:QI 2 "const1_operand" "")))
13686    (clobber (reg:CC FLAGS_REG))]
13687   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13688    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13689   "ror{l}\t%0"
13690   [(set_attr "type" "rotate")
13691    (set (attr "length")
13692      (if_then_else (match_operand:SI 0 "register_operand" "")
13693         (const_string "2")
13694         (const_string "*")))])
13695
13696 (define_insn "*rotrsi3_1_one_bit_zext"
13697   [(set (match_operand:DI 0 "register_operand" "=r")
13698         (zero_extend:DI
13699           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13700                        (match_operand:QI 2 "const1_operand" ""))))
13701    (clobber (reg:CC FLAGS_REG))]
13702   "TARGET_64BIT
13703    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13705   "ror{l}\t%k0"
13706   [(set_attr "type" "rotate")
13707    (set (attr "length")
13708      (if_then_else (match_operand:SI 0 "register_operand" "")
13709         (const_string "2")
13710         (const_string "*")))])
13711
13712 (define_insn "*rotrsi3_1"
13713   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13714         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13715                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13716    (clobber (reg:CC FLAGS_REG))]
13717   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13718   "@
13719    ror{l}\t{%2, %0|%0, %2}
13720    ror{l}\t{%b2, %0|%0, %b2}"
13721   [(set_attr "type" "rotate")
13722    (set_attr "mode" "SI")])
13723
13724 (define_insn "*rotrsi3_1_zext"
13725   [(set (match_operand:DI 0 "register_operand" "=r,r")
13726         (zero_extend:DI
13727           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13728                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13729    (clobber (reg:CC FLAGS_REG))]
13730   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13731   "@
13732    ror{l}\t{%2, %k0|%k0, %2}
13733    ror{l}\t{%b2, %k0|%k0, %b2}"
13734   [(set_attr "type" "rotate")
13735    (set_attr "mode" "SI")])
13736
13737 (define_expand "rotrhi3"
13738   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13739         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13740                      (match_operand:QI 2 "nonmemory_operand" "")))]
13741   "TARGET_HIMODE_MATH"
13742   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13743
13744 (define_insn "*rotrhi3_one_bit"
13745   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13746         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13747                      (match_operand:QI 2 "const1_operand" "")))
13748    (clobber (reg:CC FLAGS_REG))]
13749   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13750    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13751   "ror{w}\t%0"
13752   [(set_attr "type" "rotate")
13753    (set (attr "length")
13754      (if_then_else (match_operand 0 "register_operand" "")
13755         (const_string "2")
13756         (const_string "*")))])
13757
13758 (define_insn "*rotrhi3_1"
13759   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13760         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13761                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13762    (clobber (reg:CC FLAGS_REG))]
13763   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13764   "@
13765    ror{w}\t{%2, %0|%0, %2}
13766    ror{w}\t{%b2, %0|%0, %b2}"
13767   [(set_attr "type" "rotate")
13768    (set_attr "mode" "HI")])
13769
13770 (define_split
13771  [(set (match_operand:HI 0 "register_operand" "")
13772        (rotatert:HI (match_dup 0) (const_int 8)))
13773   (clobber (reg:CC FLAGS_REG))]
13774  "reload_completed"
13775  [(parallel [(set (strict_low_part (match_dup 0))
13776                   (bswap:HI (match_dup 0)))
13777              (clobber (reg:CC FLAGS_REG))])]
13778  "")
13779
13780 (define_expand "rotrqi3"
13781   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13782         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13783                      (match_operand:QI 2 "nonmemory_operand" "")))]
13784   "TARGET_QIMODE_MATH"
13785   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13786
13787 (define_insn "*rotrqi3_1_one_bit"
13788   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13789         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13790                      (match_operand:QI 2 "const1_operand" "")))
13791    (clobber (reg:CC FLAGS_REG))]
13792   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13793    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13794   "ror{b}\t%0"
13795   [(set_attr "type" "rotate")
13796    (set (attr "length")
13797      (if_then_else (match_operand 0 "register_operand" "")
13798         (const_string "2")
13799         (const_string "*")))])
13800
13801 (define_insn "*rotrqi3_1_one_bit_slp"
13802   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13803         (rotatert:QI (match_dup 0)
13804                      (match_operand:QI 1 "const1_operand" "")))
13805    (clobber (reg:CC FLAGS_REG))]
13806   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13807    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13808   "ror{b}\t%0"
13809   [(set_attr "type" "rotate1")
13810    (set (attr "length")
13811      (if_then_else (match_operand 0 "register_operand" "")
13812         (const_string "2")
13813         (const_string "*")))])
13814
13815 (define_insn "*rotrqi3_1"
13816   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13817         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13818                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13819    (clobber (reg:CC FLAGS_REG))]
13820   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13821   "@
13822    ror{b}\t{%2, %0|%0, %2}
13823    ror{b}\t{%b2, %0|%0, %b2}"
13824   [(set_attr "type" "rotate")
13825    (set_attr "mode" "QI")])
13826
13827 (define_insn "*rotrqi3_1_slp"
13828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13829         (rotatert:QI (match_dup 0)
13830                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13831    (clobber (reg:CC FLAGS_REG))]
13832   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13833    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13834   "@
13835    ror{b}\t{%1, %0|%0, %1}
13836    ror{b}\t{%b1, %0|%0, %b1}"
13837   [(set_attr "type" "rotate1")
13838    (set_attr "mode" "QI")])
13839 \f
13840 ;; Bit set / bit test instructions
13841
13842 (define_expand "extv"
13843   [(set (match_operand:SI 0 "register_operand" "")
13844         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13845                          (match_operand:SI 2 "const8_operand" "")
13846                          (match_operand:SI 3 "const8_operand" "")))]
13847   ""
13848 {
13849   /* Handle extractions from %ah et al.  */
13850   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13851     FAIL;
13852
13853   /* From mips.md: extract_bit_field doesn't verify that our source
13854      matches the predicate, so check it again here.  */
13855   if (! ext_register_operand (operands[1], VOIDmode))
13856     FAIL;
13857 })
13858
13859 (define_expand "extzv"
13860   [(set (match_operand:SI 0 "register_operand" "")
13861         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13862                          (match_operand:SI 2 "const8_operand" "")
13863                          (match_operand:SI 3 "const8_operand" "")))]
13864   ""
13865 {
13866   /* Handle extractions from %ah et al.  */
13867   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13868     FAIL;
13869
13870   /* From mips.md: extract_bit_field doesn't verify that our source
13871      matches the predicate, so check it again here.  */
13872   if (! ext_register_operand (operands[1], VOIDmode))
13873     FAIL;
13874 })
13875
13876 (define_expand "insv"
13877   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13878                       (match_operand 1 "const8_operand" "")
13879                       (match_operand 2 "const8_operand" ""))
13880         (match_operand 3 "register_operand" ""))]
13881   ""
13882 {
13883   /* Handle insertions to %ah et al.  */
13884   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13885     FAIL;
13886
13887   /* From mips.md: insert_bit_field doesn't verify that our source
13888      matches the predicate, so check it again here.  */
13889   if (! ext_register_operand (operands[0], VOIDmode))
13890     FAIL;
13891
13892   if (TARGET_64BIT)
13893     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13894   else
13895     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13896
13897   DONE;
13898 })
13899
13900 ;; %%% bts, btr, btc, bt.
13901 ;; In general these instructions are *slow* when applied to memory,
13902 ;; since they enforce atomic operation.  When applied to registers,
13903 ;; it depends on the cpu implementation.  They're never faster than
13904 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13905 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13906 ;; within the instruction itself, so operating on bits in the high
13907 ;; 32-bits of a register becomes easier.
13908 ;;
13909 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13910 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13911 ;; negdf respectively, so they can never be disabled entirely.
13912
13913 (define_insn "*btsq"
13914   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13915                          (const_int 1)
13916                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13917         (const_int 1))
13918    (clobber (reg:CC FLAGS_REG))]
13919   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13920   "bts{q}\t{%1, %0|%0, %1}"
13921   [(set_attr "type" "alu1")])
13922
13923 (define_insn "*btrq"
13924   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13925                          (const_int 1)
13926                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13927         (const_int 0))
13928    (clobber (reg:CC FLAGS_REG))]
13929   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13930   "btr{q}\t{%1, %0|%0, %1}"
13931   [(set_attr "type" "alu1")])
13932
13933 (define_insn "*btcq"
13934   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13935                          (const_int 1)
13936                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13937         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13938    (clobber (reg:CC FLAGS_REG))]
13939   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13940   "btc{q}\t{%1, %0|%0, %1}"
13941   [(set_attr "type" "alu1")])
13942
13943 ;; Allow Nocona to avoid these instructions if a register is available.
13944
13945 (define_peephole2
13946   [(match_scratch:DI 2 "r")
13947    (parallel [(set (zero_extract:DI
13948                      (match_operand:DI 0 "register_operand" "")
13949                      (const_int 1)
13950                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13951                    (const_int 1))
13952               (clobber (reg:CC FLAGS_REG))])]
13953   "TARGET_64BIT && !TARGET_USE_BT"
13954   [(const_int 0)]
13955 {
13956   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13957   rtx op1;
13958
13959   if (HOST_BITS_PER_WIDE_INT >= 64)
13960     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13961   else if (i < HOST_BITS_PER_WIDE_INT)
13962     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13963   else
13964     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13965
13966   op1 = immed_double_const (lo, hi, DImode);
13967   if (i >= 31)
13968     {
13969       emit_move_insn (operands[2], op1);
13970       op1 = operands[2];
13971     }
13972
13973   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13974   DONE;
13975 })
13976
13977 (define_peephole2
13978   [(match_scratch:DI 2 "r")
13979    (parallel [(set (zero_extract:DI
13980                      (match_operand:DI 0 "register_operand" "")
13981                      (const_int 1)
13982                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13983                    (const_int 0))
13984               (clobber (reg:CC FLAGS_REG))])]
13985   "TARGET_64BIT && !TARGET_USE_BT"
13986   [(const_int 0)]
13987 {
13988   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13989   rtx op1;
13990
13991   if (HOST_BITS_PER_WIDE_INT >= 64)
13992     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13993   else if (i < HOST_BITS_PER_WIDE_INT)
13994     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13995   else
13996     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13997
13998   op1 = immed_double_const (~lo, ~hi, DImode);
13999   if (i >= 32)
14000     {
14001       emit_move_insn (operands[2], op1);
14002       op1 = operands[2];
14003     }
14004
14005   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14006   DONE;
14007 })
14008
14009 (define_peephole2
14010   [(match_scratch:DI 2 "r")
14011    (parallel [(set (zero_extract:DI
14012                      (match_operand:DI 0 "register_operand" "")
14013                      (const_int 1)
14014                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14015               (not:DI (zero_extract:DI
14016                         (match_dup 0) (const_int 1) (match_dup 1))))
14017               (clobber (reg:CC FLAGS_REG))])]
14018   "TARGET_64BIT && !TARGET_USE_BT"
14019   [(const_int 0)]
14020 {
14021   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14022   rtx op1;
14023
14024   if (HOST_BITS_PER_WIDE_INT >= 64)
14025     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14026   else if (i < HOST_BITS_PER_WIDE_INT)
14027     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14028   else
14029     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14030
14031   op1 = immed_double_const (lo, hi, DImode);
14032   if (i >= 31)
14033     {
14034       emit_move_insn (operands[2], op1);
14035       op1 = operands[2];
14036     }
14037
14038   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14039   DONE;
14040 })
14041
14042 (define_insn "*btdi_rex64"
14043   [(set (reg:CCC FLAGS_REG)
14044         (compare:CCC
14045           (zero_extract:DI
14046             (match_operand:DI 0 "register_operand" "r")
14047             (const_int 1)
14048             (match_operand:DI 1 "nonmemory_operand" "rN"))
14049           (const_int 0)))]
14050   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14051   "bt{q}\t{%1, %0|%0, %1}"
14052   [(set_attr "type" "alu1")])
14053
14054 (define_insn "*btsi"
14055   [(set (reg:CCC FLAGS_REG)
14056         (compare:CCC
14057           (zero_extract:SI
14058             (match_operand:SI 0 "register_operand" "r")
14059             (const_int 1)
14060             (match_operand:SI 1 "nonmemory_operand" "rN"))
14061           (const_int 0)))]
14062   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14063   "bt{l}\t{%1, %0|%0, %1}"
14064   [(set_attr "type" "alu1")])
14065 \f
14066 ;; Store-flag instructions.
14067
14068 ;; For all sCOND expanders, also expand the compare or test insn that
14069 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14070
14071 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14072 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14073 ;; way, which can later delete the movzx if only QImode is needed.
14074
14075 (define_expand "s<code>"
14076   [(set (match_operand:QI 0 "register_operand" "")
14077         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14078   ""
14079   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14080
14081 (define_expand "s<code>"
14082   [(set (match_operand:QI 0 "register_operand" "")
14083         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14084   "TARGET_80387 || TARGET_SSE"
14085   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14086
14087 (define_insn "*setcc_1"
14088   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14089         (match_operator:QI 1 "ix86_comparison_operator"
14090           [(reg FLAGS_REG) (const_int 0)]))]
14091   ""
14092   "set%C1\t%0"
14093   [(set_attr "type" "setcc")
14094    (set_attr "mode" "QI")])
14095
14096 (define_insn "*setcc_2"
14097   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14098         (match_operator:QI 1 "ix86_comparison_operator"
14099           [(reg FLAGS_REG) (const_int 0)]))]
14100   ""
14101   "set%C1\t%0"
14102   [(set_attr "type" "setcc")
14103    (set_attr "mode" "QI")])
14104
14105 ;; In general it is not safe to assume too much about CCmode registers,
14106 ;; so simplify-rtx stops when it sees a second one.  Under certain
14107 ;; conditions this is safe on x86, so help combine not create
14108 ;;
14109 ;;      seta    %al
14110 ;;      testb   %al, %al
14111 ;;      sete    %al
14112
14113 (define_split
14114   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14115         (ne:QI (match_operator 1 "ix86_comparison_operator"
14116                  [(reg FLAGS_REG) (const_int 0)])
14117             (const_int 0)))]
14118   ""
14119   [(set (match_dup 0) (match_dup 1))]
14120 {
14121   PUT_MODE (operands[1], QImode);
14122 })
14123
14124 (define_split
14125   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14126         (ne:QI (match_operator 1 "ix86_comparison_operator"
14127                  [(reg FLAGS_REG) (const_int 0)])
14128             (const_int 0)))]
14129   ""
14130   [(set (match_dup 0) (match_dup 1))]
14131 {
14132   PUT_MODE (operands[1], QImode);
14133 })
14134
14135 (define_split
14136   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14137         (eq:QI (match_operator 1 "ix86_comparison_operator"
14138                  [(reg FLAGS_REG) (const_int 0)])
14139             (const_int 0)))]
14140   ""
14141   [(set (match_dup 0) (match_dup 1))]
14142 {
14143   rtx new_op1 = copy_rtx (operands[1]);
14144   operands[1] = new_op1;
14145   PUT_MODE (new_op1, QImode);
14146   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14147                                              GET_MODE (XEXP (new_op1, 0))));
14148
14149   /* Make sure that (a) the CCmode we have for the flags is strong
14150      enough for the reversed compare or (b) we have a valid FP compare.  */
14151   if (! ix86_comparison_operator (new_op1, VOIDmode))
14152     FAIL;
14153 })
14154
14155 (define_split
14156   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14157         (eq:QI (match_operator 1 "ix86_comparison_operator"
14158                  [(reg FLAGS_REG) (const_int 0)])
14159             (const_int 0)))]
14160   ""
14161   [(set (match_dup 0) (match_dup 1))]
14162 {
14163   rtx new_op1 = copy_rtx (operands[1]);
14164   operands[1] = new_op1;
14165   PUT_MODE (new_op1, QImode);
14166   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14167                                              GET_MODE (XEXP (new_op1, 0))));
14168
14169   /* Make sure that (a) the CCmode we have for the flags is strong
14170      enough for the reversed compare or (b) we have a valid FP compare.  */
14171   if (! ix86_comparison_operator (new_op1, VOIDmode))
14172     FAIL;
14173 })
14174
14175 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14176 ;; subsequent logical operations are used to imitate conditional moves.
14177 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14178 ;; it directly.
14179
14180 (define_insn "*avx_setcc<mode>"
14181   [(set (match_operand:MODEF 0 "register_operand" "=x")
14182         (match_operator:MODEF 1 "avx_comparison_float_operator"
14183           [(match_operand:MODEF 2 "register_operand" "x")
14184            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14185   "TARGET_AVX"
14186   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14187   [(set_attr "type" "ssecmp")
14188    (set_attr "prefix" "vex")
14189    (set_attr "mode" "<MODE>")])
14190
14191 (define_insn "*sse_setcc<mode>"
14192   [(set (match_operand:MODEF 0 "register_operand" "=x")
14193         (match_operator:MODEF 1 "sse_comparison_operator"
14194           [(match_operand:MODEF 2 "register_operand" "0")
14195            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14196   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14197   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14198   [(set_attr "type" "ssecmp")
14199    (set_attr "mode" "<MODE>")])
14200
14201 (define_insn "*sse5_setcc<mode>"
14202   [(set (match_operand:MODEF 0 "register_operand" "=x")
14203         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14204           [(match_operand:MODEF 2 "register_operand" "x")
14205            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14206   "TARGET_SSE5"
14207   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14208   [(set_attr "type" "sse4arg")
14209    (set_attr "mode" "<MODE>")])
14210
14211 \f
14212 ;; Basic conditional jump instructions.
14213 ;; We ignore the overflow flag for signed branch instructions.
14214
14215 ;; For all bCOND expanders, also expand the compare or test insn that
14216 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14217
14218 (define_expand "b<code>"
14219   [(set (pc)
14220         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14221                                    (const_int 0))
14222                       (label_ref (match_operand 0 ""))
14223                       (pc)))]
14224   ""
14225   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14226
14227 (define_expand "b<code>"
14228   [(set (pc)
14229         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14230                                   (const_int 0))
14231                       (label_ref (match_operand 0 ""))
14232                       (pc)))]
14233   "TARGET_80387 || TARGET_SSE_MATH"
14234   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14235
14236 (define_insn "*jcc_1"
14237   [(set (pc)
14238         (if_then_else (match_operator 1 "ix86_comparison_operator"
14239                                       [(reg FLAGS_REG) (const_int 0)])
14240                       (label_ref (match_operand 0 "" ""))
14241                       (pc)))]
14242   ""
14243   "%+j%C1\t%l0"
14244   [(set_attr "type" "ibr")
14245    (set_attr "modrm" "0")
14246    (set (attr "length")
14247            (if_then_else (and (ge (minus (match_dup 0) (pc))
14248                                   (const_int -126))
14249                               (lt (minus (match_dup 0) (pc))
14250                                   (const_int 128)))
14251              (const_int 2)
14252              (const_int 6)))])
14253
14254 (define_insn "*jcc_2"
14255   [(set (pc)
14256         (if_then_else (match_operator 1 "ix86_comparison_operator"
14257                                       [(reg FLAGS_REG) (const_int 0)])
14258                       (pc)
14259                       (label_ref (match_operand 0 "" ""))))]
14260   ""
14261   "%+j%c1\t%l0"
14262   [(set_attr "type" "ibr")
14263    (set_attr "modrm" "0")
14264    (set (attr "length")
14265            (if_then_else (and (ge (minus (match_dup 0) (pc))
14266                                   (const_int -126))
14267                               (lt (minus (match_dup 0) (pc))
14268                                   (const_int 128)))
14269              (const_int 2)
14270              (const_int 6)))])
14271
14272 ;; In general it is not safe to assume too much about CCmode registers,
14273 ;; so simplify-rtx stops when it sees a second one.  Under certain
14274 ;; conditions this is safe on x86, so help combine not create
14275 ;;
14276 ;;      seta    %al
14277 ;;      testb   %al, %al
14278 ;;      je      Lfoo
14279
14280 (define_split
14281   [(set (pc)
14282         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14283                                       [(reg FLAGS_REG) (const_int 0)])
14284                           (const_int 0))
14285                       (label_ref (match_operand 1 "" ""))
14286                       (pc)))]
14287   ""
14288   [(set (pc)
14289         (if_then_else (match_dup 0)
14290                       (label_ref (match_dup 1))
14291                       (pc)))]
14292 {
14293   PUT_MODE (operands[0], VOIDmode);
14294 })
14295
14296 (define_split
14297   [(set (pc)
14298         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14299                                       [(reg FLAGS_REG) (const_int 0)])
14300                           (const_int 0))
14301                       (label_ref (match_operand 1 "" ""))
14302                       (pc)))]
14303   ""
14304   [(set (pc)
14305         (if_then_else (match_dup 0)
14306                       (label_ref (match_dup 1))
14307                       (pc)))]
14308 {
14309   rtx new_op0 = copy_rtx (operands[0]);
14310   operands[0] = new_op0;
14311   PUT_MODE (new_op0, VOIDmode);
14312   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14313                                              GET_MODE (XEXP (new_op0, 0))));
14314
14315   /* Make sure that (a) the CCmode we have for the flags is strong
14316      enough for the reversed compare or (b) we have a valid FP compare.  */
14317   if (! ix86_comparison_operator (new_op0, VOIDmode))
14318     FAIL;
14319 })
14320
14321 ;; zero_extend in SImode is correct, since this is what combine pass
14322 ;; generates from shift insn with QImode operand.  Actually, the mode of
14323 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14324 ;; appropriate modulo of the bit offset value.
14325
14326 (define_insn_and_split "*jcc_btdi_rex64"
14327   [(set (pc)
14328         (if_then_else (match_operator 0 "bt_comparison_operator"
14329                         [(zero_extract:DI
14330                            (match_operand:DI 1 "register_operand" "r")
14331                            (const_int 1)
14332                            (zero_extend:SI
14333                              (match_operand:QI 2 "register_operand" "r")))
14334                          (const_int 0)])
14335                       (label_ref (match_operand 3 "" ""))
14336                       (pc)))
14337    (clobber (reg:CC FLAGS_REG))]
14338   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14339   "#"
14340   "&& 1"
14341   [(set (reg:CCC FLAGS_REG)
14342         (compare:CCC
14343           (zero_extract:DI
14344             (match_dup 1)
14345             (const_int 1)
14346             (match_dup 2))
14347           (const_int 0)))
14348    (set (pc)
14349         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14350                       (label_ref (match_dup 3))
14351                       (pc)))]
14352 {
14353   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14354
14355   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14356 })
14357
14358 ;; avoid useless masking of bit offset operand
14359 (define_insn_and_split "*jcc_btdi_mask_rex64"
14360   [(set (pc)
14361         (if_then_else (match_operator 0 "bt_comparison_operator"
14362                         [(zero_extract:DI
14363                            (match_operand:DI 1 "register_operand" "r")
14364                            (const_int 1)
14365                            (and:SI
14366                              (match_operand:SI 2 "register_operand" "r")
14367                              (match_operand:SI 3 "const_int_operand" "n")))])
14368                       (label_ref (match_operand 4 "" ""))
14369                       (pc)))
14370    (clobber (reg:CC FLAGS_REG))]
14371   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14372    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14373   "#"
14374   "&& 1"
14375   [(set (reg:CCC FLAGS_REG)
14376         (compare:CCC
14377           (zero_extract:DI
14378             (match_dup 1)
14379             (const_int 1)
14380             (match_dup 2))
14381           (const_int 0)))
14382    (set (pc)
14383         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14384                       (label_ref (match_dup 4))
14385                       (pc)))]
14386 {
14387   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14388
14389   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14390 })
14391
14392 (define_insn_and_split "*jcc_btsi"
14393   [(set (pc)
14394         (if_then_else (match_operator 0 "bt_comparison_operator"
14395                         [(zero_extract:SI
14396                            (match_operand:SI 1 "register_operand" "r")
14397                            (const_int 1)
14398                            (zero_extend:SI
14399                              (match_operand:QI 2 "register_operand" "r")))
14400                          (const_int 0)])
14401                       (label_ref (match_operand 3 "" ""))
14402                       (pc)))
14403    (clobber (reg:CC FLAGS_REG))]
14404   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14405   "#"
14406   "&& 1"
14407   [(set (reg:CCC FLAGS_REG)
14408         (compare:CCC
14409           (zero_extract:SI
14410             (match_dup 1)
14411             (const_int 1)
14412             (match_dup 2))
14413           (const_int 0)))
14414    (set (pc)
14415         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14416                       (label_ref (match_dup 3))
14417                       (pc)))]
14418 {
14419   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14420
14421   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14422 })
14423
14424 ;; avoid useless masking of bit offset operand
14425 (define_insn_and_split "*jcc_btsi_mask"
14426   [(set (pc)
14427         (if_then_else (match_operator 0 "bt_comparison_operator"
14428                         [(zero_extract:SI
14429                            (match_operand:SI 1 "register_operand" "r")
14430                            (const_int 1)
14431                            (and:SI
14432                              (match_operand:SI 2 "register_operand" "r")
14433                              (match_operand:SI 3 "const_int_operand" "n")))])
14434                       (label_ref (match_operand 4 "" ""))
14435                       (pc)))
14436    (clobber (reg:CC FLAGS_REG))]
14437   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14438    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14439   "#"
14440   "&& 1"
14441   [(set (reg:CCC FLAGS_REG)
14442         (compare:CCC
14443           (zero_extract:SI
14444             (match_dup 1)
14445             (const_int 1)
14446             (match_dup 2))
14447           (const_int 0)))
14448    (set (pc)
14449         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14450                       (label_ref (match_dup 4))
14451                       (pc)))]
14452   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14453
14454 (define_insn_and_split "*jcc_btsi_1"
14455   [(set (pc)
14456         (if_then_else (match_operator 0 "bt_comparison_operator"
14457                         [(and:SI
14458                            (lshiftrt:SI
14459                              (match_operand:SI 1 "register_operand" "r")
14460                              (match_operand:QI 2 "register_operand" "r"))
14461                            (const_int 1))
14462                          (const_int 0)])
14463                       (label_ref (match_operand 3 "" ""))
14464                       (pc)))
14465    (clobber (reg:CC FLAGS_REG))]
14466   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14467   "#"
14468   "&& 1"
14469   [(set (reg:CCC FLAGS_REG)
14470         (compare:CCC
14471           (zero_extract:SI
14472             (match_dup 1)
14473             (const_int 1)
14474             (match_dup 2))
14475           (const_int 0)))
14476    (set (pc)
14477         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14478                       (label_ref (match_dup 3))
14479                       (pc)))]
14480 {
14481   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14482
14483   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14484 })
14485
14486 ;; avoid useless masking of bit offset operand
14487 (define_insn_and_split "*jcc_btsi_mask_1"
14488   [(set (pc)
14489         (if_then_else
14490           (match_operator 0 "bt_comparison_operator"
14491             [(and:SI
14492                (lshiftrt:SI
14493                  (match_operand:SI 1 "register_operand" "r")
14494                  (subreg:QI
14495                    (and:SI
14496                      (match_operand:SI 2 "register_operand" "r")
14497                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14498                (const_int 1))
14499              (const_int 0)])
14500           (label_ref (match_operand 4 "" ""))
14501           (pc)))
14502    (clobber (reg:CC FLAGS_REG))]
14503   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14504    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14505   "#"
14506   "&& 1"
14507   [(set (reg:CCC FLAGS_REG)
14508         (compare:CCC
14509           (zero_extract:SI
14510             (match_dup 1)
14511             (const_int 1)
14512             (match_dup 2))
14513           (const_int 0)))
14514    (set (pc)
14515         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14516                       (label_ref (match_dup 4))
14517                       (pc)))]
14518   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14519
14520 ;; Define combination compare-and-branch fp compare instructions to use
14521 ;; during early optimization.  Splitting the operation apart early makes
14522 ;; for bad code when we want to reverse the operation.
14523
14524 (define_insn "*fp_jcc_1_mixed"
14525   [(set (pc)
14526         (if_then_else (match_operator 0 "comparison_operator"
14527                         [(match_operand 1 "register_operand" "f,x")
14528                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14529           (label_ref (match_operand 3 "" ""))
14530           (pc)))
14531    (clobber (reg:CCFP FPSR_REG))
14532    (clobber (reg:CCFP FLAGS_REG))]
14533   "TARGET_MIX_SSE_I387
14534    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14535    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14536    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14537   "#")
14538
14539 (define_insn "*fp_jcc_1_sse"
14540   [(set (pc)
14541         (if_then_else (match_operator 0 "comparison_operator"
14542                         [(match_operand 1 "register_operand" "x")
14543                          (match_operand 2 "nonimmediate_operand" "xm")])
14544           (label_ref (match_operand 3 "" ""))
14545           (pc)))
14546    (clobber (reg:CCFP FPSR_REG))
14547    (clobber (reg:CCFP FLAGS_REG))]
14548   "TARGET_SSE_MATH
14549    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14550    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14551    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14552   "#")
14553
14554 (define_insn "*fp_jcc_1_387"
14555   [(set (pc)
14556         (if_then_else (match_operator 0 "comparison_operator"
14557                         [(match_operand 1 "register_operand" "f")
14558                          (match_operand 2 "register_operand" "f")])
14559           (label_ref (match_operand 3 "" ""))
14560           (pc)))
14561    (clobber (reg:CCFP FPSR_REG))
14562    (clobber (reg:CCFP FLAGS_REG))]
14563   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14564    && TARGET_CMOVE
14565    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14566    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14567   "#")
14568
14569 (define_insn "*fp_jcc_2_mixed"
14570   [(set (pc)
14571         (if_then_else (match_operator 0 "comparison_operator"
14572                         [(match_operand 1 "register_operand" "f,x")
14573                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14574           (pc)
14575           (label_ref (match_operand 3 "" ""))))
14576    (clobber (reg:CCFP FPSR_REG))
14577    (clobber (reg:CCFP FLAGS_REG))]
14578   "TARGET_MIX_SSE_I387
14579    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14580    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14581    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14582   "#")
14583
14584 (define_insn "*fp_jcc_2_sse"
14585   [(set (pc)
14586         (if_then_else (match_operator 0 "comparison_operator"
14587                         [(match_operand 1 "register_operand" "x")
14588                          (match_operand 2 "nonimmediate_operand" "xm")])
14589           (pc)
14590           (label_ref (match_operand 3 "" ""))))
14591    (clobber (reg:CCFP FPSR_REG))
14592    (clobber (reg:CCFP FLAGS_REG))]
14593   "TARGET_SSE_MATH
14594    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14595    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14596    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14597   "#")
14598
14599 (define_insn "*fp_jcc_2_387"
14600   [(set (pc)
14601         (if_then_else (match_operator 0 "comparison_operator"
14602                         [(match_operand 1 "register_operand" "f")
14603                          (match_operand 2 "register_operand" "f")])
14604           (pc)
14605           (label_ref (match_operand 3 "" ""))))
14606    (clobber (reg:CCFP FPSR_REG))
14607    (clobber (reg:CCFP FLAGS_REG))]
14608   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14609    && TARGET_CMOVE
14610    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14611    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14612   "#")
14613
14614 (define_insn "*fp_jcc_3_387"
14615   [(set (pc)
14616         (if_then_else (match_operator 0 "comparison_operator"
14617                         [(match_operand 1 "register_operand" "f")
14618                          (match_operand 2 "nonimmediate_operand" "fm")])
14619           (label_ref (match_operand 3 "" ""))
14620           (pc)))
14621    (clobber (reg:CCFP FPSR_REG))
14622    (clobber (reg:CCFP FLAGS_REG))
14623    (clobber (match_scratch:HI 4 "=a"))]
14624   "TARGET_80387
14625    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14626    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14627    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14628    && SELECT_CC_MODE (GET_CODE (operands[0]),
14629                       operands[1], operands[2]) == CCFPmode
14630    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14631   "#")
14632
14633 (define_insn "*fp_jcc_4_387"
14634   [(set (pc)
14635         (if_then_else (match_operator 0 "comparison_operator"
14636                         [(match_operand 1 "register_operand" "f")
14637                          (match_operand 2 "nonimmediate_operand" "fm")])
14638           (pc)
14639           (label_ref (match_operand 3 "" ""))))
14640    (clobber (reg:CCFP FPSR_REG))
14641    (clobber (reg:CCFP FLAGS_REG))
14642    (clobber (match_scratch:HI 4 "=a"))]
14643   "TARGET_80387
14644    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14645    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14646    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14647    && SELECT_CC_MODE (GET_CODE (operands[0]),
14648                       operands[1], operands[2]) == CCFPmode
14649    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14650   "#")
14651
14652 (define_insn "*fp_jcc_5_387"
14653   [(set (pc)
14654         (if_then_else (match_operator 0 "comparison_operator"
14655                         [(match_operand 1 "register_operand" "f")
14656                          (match_operand 2 "register_operand" "f")])
14657           (label_ref (match_operand 3 "" ""))
14658           (pc)))
14659    (clobber (reg:CCFP FPSR_REG))
14660    (clobber (reg:CCFP FLAGS_REG))
14661    (clobber (match_scratch:HI 4 "=a"))]
14662   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14663    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14664    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14665   "#")
14666
14667 (define_insn "*fp_jcc_6_387"
14668   [(set (pc)
14669         (if_then_else (match_operator 0 "comparison_operator"
14670                         [(match_operand 1 "register_operand" "f")
14671                          (match_operand 2 "register_operand" "f")])
14672           (pc)
14673           (label_ref (match_operand 3 "" ""))))
14674    (clobber (reg:CCFP FPSR_REG))
14675    (clobber (reg:CCFP FLAGS_REG))
14676    (clobber (match_scratch:HI 4 "=a"))]
14677   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14678    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14679    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14680   "#")
14681
14682 (define_insn "*fp_jcc_7_387"
14683   [(set (pc)
14684         (if_then_else (match_operator 0 "comparison_operator"
14685                         [(match_operand 1 "register_operand" "f")
14686                          (match_operand 2 "const0_operand" "")])
14687           (label_ref (match_operand 3 "" ""))
14688           (pc)))
14689    (clobber (reg:CCFP FPSR_REG))
14690    (clobber (reg:CCFP FLAGS_REG))
14691    (clobber (match_scratch:HI 4 "=a"))]
14692   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14693    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14694    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14695    && SELECT_CC_MODE (GET_CODE (operands[0]),
14696                       operands[1], operands[2]) == CCFPmode
14697    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14698   "#")
14699
14700 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14701 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14702 ;; with a precedence over other operators and is always put in the first
14703 ;; place. Swap condition and operands to match ficom instruction.
14704
14705 (define_insn "*fp_jcc_8<mode>_387"
14706   [(set (pc)
14707         (if_then_else (match_operator 0 "comparison_operator"
14708                         [(match_operator 1 "float_operator"
14709                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14710                            (match_operand 3 "register_operand" "f,f")])
14711           (label_ref (match_operand 4 "" ""))
14712           (pc)))
14713    (clobber (reg:CCFP FPSR_REG))
14714    (clobber (reg:CCFP FLAGS_REG))
14715    (clobber (match_scratch:HI 5 "=a,a"))]
14716   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14717    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14718    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14719    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14720    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14721    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14722   "#")
14723
14724 (define_split
14725   [(set (pc)
14726         (if_then_else (match_operator 0 "comparison_operator"
14727                         [(match_operand 1 "register_operand" "")
14728                          (match_operand 2 "nonimmediate_operand" "")])
14729           (match_operand 3 "" "")
14730           (match_operand 4 "" "")))
14731    (clobber (reg:CCFP FPSR_REG))
14732    (clobber (reg:CCFP FLAGS_REG))]
14733   "reload_completed"
14734   [(const_int 0)]
14735 {
14736   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14737                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14738   DONE;
14739 })
14740
14741 (define_split
14742   [(set (pc)
14743         (if_then_else (match_operator 0 "comparison_operator"
14744                         [(match_operand 1 "register_operand" "")
14745                          (match_operand 2 "general_operand" "")])
14746           (match_operand 3 "" "")
14747           (match_operand 4 "" "")))
14748    (clobber (reg:CCFP FPSR_REG))
14749    (clobber (reg:CCFP FLAGS_REG))
14750    (clobber (match_scratch:HI 5 "=a"))]
14751   "reload_completed"
14752   [(const_int 0)]
14753 {
14754   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14755                         operands[3], operands[4], operands[5], NULL_RTX);
14756   DONE;
14757 })
14758
14759 (define_split
14760   [(set (pc)
14761         (if_then_else (match_operator 0 "comparison_operator"
14762                         [(match_operator 1 "float_operator"
14763                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14764                            (match_operand 3 "register_operand" "")])
14765           (match_operand 4 "" "")
14766           (match_operand 5 "" "")))
14767    (clobber (reg:CCFP FPSR_REG))
14768    (clobber (reg:CCFP FLAGS_REG))
14769    (clobber (match_scratch:HI 6 "=a"))]
14770   "reload_completed"
14771   [(const_int 0)]
14772 {
14773   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14774   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14775                         operands[3], operands[7],
14776                         operands[4], operands[5], operands[6], NULL_RTX);
14777   DONE;
14778 })
14779
14780 ;; %%% Kill this when reload knows how to do it.
14781 (define_split
14782   [(set (pc)
14783         (if_then_else (match_operator 0 "comparison_operator"
14784                         [(match_operator 1 "float_operator"
14785                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14786                            (match_operand 3 "register_operand" "")])
14787           (match_operand 4 "" "")
14788           (match_operand 5 "" "")))
14789    (clobber (reg:CCFP FPSR_REG))
14790    (clobber (reg:CCFP FLAGS_REG))
14791    (clobber (match_scratch:HI 6 "=a"))]
14792   "reload_completed"
14793   [(const_int 0)]
14794 {
14795   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14796   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14797   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14798                         operands[3], operands[7],
14799                         operands[4], operands[5], operands[6], operands[2]);
14800   DONE;
14801 })
14802 \f
14803 ;; Unconditional and other jump instructions
14804
14805 (define_insn "jump"
14806   [(set (pc)
14807         (label_ref (match_operand 0 "" "")))]
14808   ""
14809   "jmp\t%l0"
14810   [(set_attr "type" "ibr")
14811    (set (attr "length")
14812            (if_then_else (and (ge (minus (match_dup 0) (pc))
14813                                   (const_int -126))
14814                               (lt (minus (match_dup 0) (pc))
14815                                   (const_int 128)))
14816              (const_int 2)
14817              (const_int 5)))
14818    (set_attr "modrm" "0")])
14819
14820 (define_expand "indirect_jump"
14821   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14822   ""
14823   "")
14824
14825 (define_insn "*indirect_jump"
14826   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14827   ""
14828   "jmp\t%A0"
14829   [(set_attr "type" "ibr")
14830    (set_attr "length_immediate" "0")])
14831
14832 (define_expand "tablejump"
14833   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14834               (use (label_ref (match_operand 1 "" "")))])]
14835   ""
14836 {
14837   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14838      relative.  Convert the relative address to an absolute address.  */
14839   if (flag_pic)
14840     {
14841       rtx op0, op1;
14842       enum rtx_code code;
14843
14844       /* We can't use @GOTOFF for text labels on VxWorks;
14845          see gotoff_operand.  */
14846       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14847         {
14848           code = PLUS;
14849           op0 = operands[0];
14850           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14851         }
14852       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14853         {
14854           code = PLUS;
14855           op0 = operands[0];
14856           op1 = pic_offset_table_rtx;
14857         }
14858       else
14859         {
14860           code = MINUS;
14861           op0 = pic_offset_table_rtx;
14862           op1 = operands[0];
14863         }
14864
14865       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14866                                          OPTAB_DIRECT);
14867     }
14868 })
14869
14870 (define_insn "*tablejump_1"
14871   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14872    (use (label_ref (match_operand 1 "" "")))]
14873   ""
14874   "jmp\t%A0"
14875   [(set_attr "type" "ibr")
14876    (set_attr "length_immediate" "0")])
14877 \f
14878 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14879
14880 (define_peephole2
14881   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14882    (set (match_operand:QI 1 "register_operand" "")
14883         (match_operator:QI 2 "ix86_comparison_operator"
14884           [(reg FLAGS_REG) (const_int 0)]))
14885    (set (match_operand 3 "q_regs_operand" "")
14886         (zero_extend (match_dup 1)))]
14887   "(peep2_reg_dead_p (3, operands[1])
14888     || operands_match_p (operands[1], operands[3]))
14889    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14890   [(set (match_dup 4) (match_dup 0))
14891    (set (strict_low_part (match_dup 5))
14892         (match_dup 2))]
14893 {
14894   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14895   operands[5] = gen_lowpart (QImode, operands[3]);
14896   ix86_expand_clear (operands[3]);
14897 })
14898
14899 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14900
14901 (define_peephole2
14902   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14903    (set (match_operand:QI 1 "register_operand" "")
14904         (match_operator:QI 2 "ix86_comparison_operator"
14905           [(reg FLAGS_REG) (const_int 0)]))
14906    (parallel [(set (match_operand 3 "q_regs_operand" "")
14907                    (zero_extend (match_dup 1)))
14908               (clobber (reg:CC FLAGS_REG))])]
14909   "(peep2_reg_dead_p (3, operands[1])
14910     || operands_match_p (operands[1], operands[3]))
14911    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14912   [(set (match_dup 4) (match_dup 0))
14913    (set (strict_low_part (match_dup 5))
14914         (match_dup 2))]
14915 {
14916   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14917   operands[5] = gen_lowpart (QImode, operands[3]);
14918   ix86_expand_clear (operands[3]);
14919 })
14920 \f
14921 ;; Call instructions.
14922
14923 ;; The predicates normally associated with named expanders are not properly
14924 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14925 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14926
14927 ;; Call subroutine returning no value.
14928
14929 (define_expand "call_pop"
14930   [(parallel [(call (match_operand:QI 0 "" "")
14931                     (match_operand:SI 1 "" ""))
14932               (set (reg:SI SP_REG)
14933                    (plus:SI (reg:SI SP_REG)
14934                             (match_operand:SI 3 "" "")))])]
14935   "!TARGET_64BIT"
14936 {
14937   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14938   DONE;
14939 })
14940
14941 (define_insn "*call_pop_0"
14942   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14943          (match_operand:SI 1 "" ""))
14944    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14945                             (match_operand:SI 2 "immediate_operand" "")))]
14946   "!TARGET_64BIT"
14947 {
14948   if (SIBLING_CALL_P (insn))
14949     return "jmp\t%P0";
14950   else
14951     return "call\t%P0";
14952 }
14953   [(set_attr "type" "call")])
14954
14955 (define_insn "*call_pop_1"
14956   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14957          (match_operand:SI 1 "" ""))
14958    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14959                             (match_operand:SI 2 "immediate_operand" "i")))]
14960   "!TARGET_64BIT"
14961 {
14962   if (constant_call_address_operand (operands[0], Pmode))
14963     {
14964       if (SIBLING_CALL_P (insn))
14965         return "jmp\t%P0";
14966       else
14967         return "call\t%P0";
14968     }
14969   if (SIBLING_CALL_P (insn))
14970     return "jmp\t%A0";
14971   else
14972     return "call\t%A0";
14973 }
14974   [(set_attr "type" "call")])
14975
14976 (define_expand "call"
14977   [(call (match_operand:QI 0 "" "")
14978          (match_operand 1 "" ""))
14979    (use (match_operand 2 "" ""))]
14980   ""
14981 {
14982   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14983   DONE;
14984 })
14985
14986 (define_expand "sibcall"
14987   [(call (match_operand:QI 0 "" "")
14988          (match_operand 1 "" ""))
14989    (use (match_operand 2 "" ""))]
14990   ""
14991 {
14992   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14993   DONE;
14994 })
14995
14996 (define_insn "*call_0"
14997   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14998          (match_operand 1 "" ""))]
14999   ""
15000 {
15001   if (SIBLING_CALL_P (insn))
15002     return "jmp\t%P0";
15003   else
15004     return "call\t%P0";
15005 }
15006   [(set_attr "type" "call")])
15007
15008 (define_insn "*call_1"
15009   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15010          (match_operand 1 "" ""))]
15011   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15012 {
15013   if (constant_call_address_operand (operands[0], Pmode))
15014     return "call\t%P0";
15015   return "call\t%A0";
15016 }
15017   [(set_attr "type" "call")])
15018
15019 (define_insn "*sibcall_1"
15020   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15021          (match_operand 1 "" ""))]
15022   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15023 {
15024   if (constant_call_address_operand (operands[0], Pmode))
15025     return "jmp\t%P0";
15026   return "jmp\t%A0";
15027 }
15028   [(set_attr "type" "call")])
15029
15030 (define_insn "*call_1_rex64"
15031   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15032          (match_operand 1 "" ""))]
15033   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15034    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15035 {
15036   if (constant_call_address_operand (operands[0], Pmode))
15037     return "call\t%P0";
15038   return "call\t%A0";
15039 }
15040   [(set_attr "type" "call")])
15041
15042 (define_insn "*call_1_rex64_ms_sysv"
15043   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15044          (match_operand 1 "" ""))
15045    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15046    (clobber (reg:TI 27))
15047    (clobber (reg:TI 28))
15048    (clobber (reg:TI 45))
15049    (clobber (reg:TI 46))
15050    (clobber (reg:TI 47))
15051    (clobber (reg:TI 48))
15052    (clobber (reg:TI 49))
15053    (clobber (reg:TI 50))
15054    (clobber (reg:TI 51))
15055    (clobber (reg:TI 52))
15056    (clobber (reg:DI SI_REG))
15057    (clobber (reg:DI DI_REG))]
15058   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15059 {
15060   if (constant_call_address_operand (operands[0], Pmode))
15061     return "call\t%P0";
15062   return "call\t%A0";
15063 }
15064   [(set_attr "type" "call")])
15065
15066 (define_insn "*call_1_rex64_large"
15067   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15068          (match_operand 1 "" ""))]
15069   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15070   "call\t%A0"
15071   [(set_attr "type" "call")])
15072
15073 (define_insn "*sibcall_1_rex64"
15074   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15075          (match_operand 1 "" ""))]
15076   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15077   "jmp\t%P0"
15078   [(set_attr "type" "call")])
15079
15080 (define_insn "*sibcall_1_rex64_v"
15081   [(call (mem:QI (reg:DI R11_REG))
15082          (match_operand 0 "" ""))]
15083   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15084   "jmp\t{*%%}r11"
15085   [(set_attr "type" "call")])
15086
15087
15088 ;; Call subroutine, returning value in operand 0
15089
15090 (define_expand "call_value_pop"
15091   [(parallel [(set (match_operand 0 "" "")
15092                    (call (match_operand:QI 1 "" "")
15093                          (match_operand:SI 2 "" "")))
15094               (set (reg:SI SP_REG)
15095                    (plus:SI (reg:SI SP_REG)
15096                             (match_operand:SI 4 "" "")))])]
15097   "!TARGET_64BIT"
15098 {
15099   ix86_expand_call (operands[0], operands[1], operands[2],
15100                     operands[3], operands[4], 0);
15101   DONE;
15102 })
15103
15104 (define_expand "call_value"
15105   [(set (match_operand 0 "" "")
15106         (call (match_operand:QI 1 "" "")
15107               (match_operand:SI 2 "" "")))
15108    (use (match_operand:SI 3 "" ""))]
15109   ;; Operand 2 not used on the i386.
15110   ""
15111 {
15112   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15113   DONE;
15114 })
15115
15116 (define_expand "sibcall_value"
15117   [(set (match_operand 0 "" "")
15118         (call (match_operand:QI 1 "" "")
15119               (match_operand:SI 2 "" "")))
15120    (use (match_operand:SI 3 "" ""))]
15121   ;; Operand 2 not used on the i386.
15122   ""
15123 {
15124   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15125   DONE;
15126 })
15127
15128 ;; Call subroutine returning any type.
15129
15130 (define_expand "untyped_call"
15131   [(parallel [(call (match_operand 0 "" "")
15132                     (const_int 0))
15133               (match_operand 1 "" "")
15134               (match_operand 2 "" "")])]
15135   ""
15136 {
15137   int i;
15138
15139   /* In order to give reg-stack an easier job in validating two
15140      coprocessor registers as containing a possible return value,
15141      simply pretend the untyped call returns a complex long double
15142      value.  */
15143
15144   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15145                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15146                     operands[0], const0_rtx,
15147                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15148                                                       : X64_SSE_REGPARM_MAX)
15149                              - 1),
15150                     NULL, 0);
15151
15152   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15153     {
15154       rtx set = XVECEXP (operands[2], 0, i);
15155       emit_move_insn (SET_DEST (set), SET_SRC (set));
15156     }
15157
15158   /* The optimizer does not know that the call sets the function value
15159      registers we stored in the result block.  We avoid problems by
15160      claiming that all hard registers are used and clobbered at this
15161      point.  */
15162   emit_insn (gen_blockage ());
15163
15164   DONE;
15165 })
15166 \f
15167 ;; Prologue and epilogue instructions
15168
15169 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15170 ;; all of memory.  This blocks insns from being moved across this point.
15171
15172 (define_insn "blockage"
15173   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15174   ""
15175   ""
15176   [(set_attr "length" "0")])
15177
15178 ;; As USE insns aren't meaningful after reload, this is used instead
15179 ;; to prevent deleting instructions setting registers for PIC code
15180 (define_insn "prologue_use"
15181   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15182   ""
15183   ""
15184   [(set_attr "length" "0")])
15185
15186 ;; Insn emitted into the body of a function to return from a function.
15187 ;; This is only done if the function's epilogue is known to be simple.
15188 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15189
15190 (define_expand "return"
15191   [(return)]
15192   "ix86_can_use_return_insn_p ()"
15193 {
15194   if (crtl->args.pops_args)
15195     {
15196       rtx popc = GEN_INT (crtl->args.pops_args);
15197       emit_jump_insn (gen_return_pop_internal (popc));
15198       DONE;
15199     }
15200 })
15201
15202 (define_insn "return_internal"
15203   [(return)]
15204   "reload_completed"
15205   "ret"
15206   [(set_attr "length" "1")
15207    (set_attr "length_immediate" "0")
15208    (set_attr "modrm" "0")])
15209
15210 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15211 ;; instruction Athlon and K8 have.
15212
15213 (define_insn "return_internal_long"
15214   [(return)
15215    (unspec [(const_int 0)] UNSPEC_REP)]
15216   "reload_completed"
15217   "rep\;ret"
15218   [(set_attr "length" "1")
15219    (set_attr "length_immediate" "0")
15220    (set_attr "prefix_rep" "1")
15221    (set_attr "modrm" "0")])
15222
15223 (define_insn "return_pop_internal"
15224   [(return)
15225    (use (match_operand:SI 0 "const_int_operand" ""))]
15226   "reload_completed"
15227   "ret\t%0"
15228   [(set_attr "length" "3")
15229    (set_attr "length_immediate" "2")
15230    (set_attr "modrm" "0")])
15231
15232 (define_insn "return_indirect_internal"
15233   [(return)
15234    (use (match_operand:SI 0 "register_operand" "r"))]
15235   "reload_completed"
15236   "jmp\t%A0"
15237   [(set_attr "type" "ibr")
15238    (set_attr "length_immediate" "0")])
15239
15240 (define_insn "nop"
15241   [(const_int 0)]
15242   ""
15243   "nop"
15244   [(set_attr "length" "1")
15245    (set_attr "length_immediate" "0")
15246    (set_attr "modrm" "0")])
15247
15248 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15249 ;; branch prediction penalty for the third jump in a 16-byte
15250 ;; block on K8.
15251
15252 (define_insn "align"
15253   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15254   ""
15255 {
15256 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15257   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15258 #else
15259   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15260      The align insn is used to avoid 3 jump instructions in the row to improve
15261      branch prediction and the benefits hardly outweigh the cost of extra 8
15262      nops on the average inserted by full alignment pseudo operation.  */
15263 #endif
15264   return "";
15265 }
15266   [(set_attr "length" "16")])
15267
15268 (define_expand "prologue"
15269   [(const_int 0)]
15270   ""
15271   "ix86_expand_prologue (); DONE;")
15272
15273 (define_insn "set_got"
15274   [(set (match_operand:SI 0 "register_operand" "=r")
15275         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15276    (clobber (reg:CC FLAGS_REG))]
15277   "!TARGET_64BIT"
15278   { return output_set_got (operands[0], NULL_RTX); }
15279   [(set_attr "type" "multi")
15280    (set_attr "length" "12")])
15281
15282 (define_insn "set_got_labelled"
15283   [(set (match_operand:SI 0 "register_operand" "=r")
15284         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15285          UNSPEC_SET_GOT))
15286    (clobber (reg:CC FLAGS_REG))]
15287   "!TARGET_64BIT"
15288   { return output_set_got (operands[0], operands[1]); }
15289   [(set_attr "type" "multi")
15290    (set_attr "length" "12")])
15291
15292 (define_insn "set_got_rex64"
15293   [(set (match_operand:DI 0 "register_operand" "=r")
15294         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15295   "TARGET_64BIT"
15296   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15297   [(set_attr "type" "lea")
15298    (set_attr "length" "6")])
15299
15300 (define_insn "set_rip_rex64"
15301   [(set (match_operand:DI 0 "register_operand" "=r")
15302         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15303   "TARGET_64BIT"
15304   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15305   [(set_attr "type" "lea")
15306    (set_attr "length" "6")])
15307
15308 (define_insn "set_got_offset_rex64"
15309   [(set (match_operand:DI 0 "register_operand" "=r")
15310         (unspec:DI
15311           [(label_ref (match_operand 1 "" ""))]
15312           UNSPEC_SET_GOT_OFFSET))]
15313   "TARGET_64BIT"
15314   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15315   [(set_attr "type" "imov")
15316    (set_attr "length" "11")])
15317
15318 (define_expand "epilogue"
15319   [(const_int 0)]
15320   ""
15321   "ix86_expand_epilogue (1); DONE;")
15322
15323 (define_expand "sibcall_epilogue"
15324   [(const_int 0)]
15325   ""
15326   "ix86_expand_epilogue (0); DONE;")
15327
15328 (define_expand "eh_return"
15329   [(use (match_operand 0 "register_operand" ""))]
15330   ""
15331 {
15332   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15333
15334   /* Tricky bit: we write the address of the handler to which we will
15335      be returning into someone else's stack frame, one word below the
15336      stack address we wish to restore.  */
15337   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15338   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15339   tmp = gen_rtx_MEM (Pmode, tmp);
15340   emit_move_insn (tmp, ra);
15341
15342   if (Pmode == SImode)
15343     emit_jump_insn (gen_eh_return_si (sa));
15344   else
15345     emit_jump_insn (gen_eh_return_di (sa));
15346   emit_barrier ();
15347   DONE;
15348 })
15349
15350 (define_insn_and_split "eh_return_<mode>"
15351   [(set (pc)
15352         (unspec [(match_operand:P 0 "register_operand" "c")]
15353                  UNSPEC_EH_RETURN))]
15354   ""
15355   "#"
15356   "reload_completed"
15357   [(const_int 0)]
15358   "ix86_expand_epilogue (2); DONE;")
15359
15360 (define_insn "leave"
15361   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15362    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15363    (clobber (mem:BLK (scratch)))]
15364   "!TARGET_64BIT"
15365   "leave"
15366   [(set_attr "type" "leave")])
15367
15368 (define_insn "leave_rex64"
15369   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15370    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15371    (clobber (mem:BLK (scratch)))]
15372   "TARGET_64BIT"
15373   "leave"
15374   [(set_attr "type" "leave")])
15375 \f
15376 (define_expand "ffssi2"
15377   [(parallel
15378      [(set (match_operand:SI 0 "register_operand" "")
15379            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15380       (clobber (match_scratch:SI 2 ""))
15381       (clobber (reg:CC FLAGS_REG))])]
15382   ""
15383 {
15384   if (TARGET_CMOVE)
15385     {
15386       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15387       DONE;
15388     }
15389 })
15390
15391 (define_expand "ffs_cmove"
15392   [(set (match_dup 2) (const_int -1))
15393    (parallel [(set (reg:CCZ FLAGS_REG)
15394                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15395                                 (const_int 0)))
15396               (set (match_operand:SI 0 "register_operand" "")
15397                    (ctz:SI (match_dup 1)))])
15398    (set (match_dup 0) (if_then_else:SI
15399                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15400                         (match_dup 2)
15401                         (match_dup 0)))
15402    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15403               (clobber (reg:CC FLAGS_REG))])]
15404   "TARGET_CMOVE"
15405   "operands[2] = gen_reg_rtx (SImode);")
15406
15407 (define_insn_and_split "*ffs_no_cmove"
15408   [(set (match_operand:SI 0 "register_operand" "=r")
15409         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15410    (clobber (match_scratch:SI 2 "=&q"))
15411    (clobber (reg:CC FLAGS_REG))]
15412   "!TARGET_CMOVE"
15413   "#"
15414   "&& reload_completed"
15415   [(parallel [(set (reg:CCZ FLAGS_REG)
15416                    (compare:CCZ (match_dup 1) (const_int 0)))
15417               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15418    (set (strict_low_part (match_dup 3))
15419         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15420    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15421               (clobber (reg:CC FLAGS_REG))])
15422    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15423               (clobber (reg:CC FLAGS_REG))])
15424    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15425               (clobber (reg:CC FLAGS_REG))])]
15426 {
15427   operands[3] = gen_lowpart (QImode, operands[2]);
15428   ix86_expand_clear (operands[2]);
15429 })
15430
15431 (define_insn "*ffssi_1"
15432   [(set (reg:CCZ FLAGS_REG)
15433         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15434                      (const_int 0)))
15435    (set (match_operand:SI 0 "register_operand" "=r")
15436         (ctz:SI (match_dup 1)))]
15437   ""
15438   "bsf{l}\t{%1, %0|%0, %1}"
15439   [(set_attr "prefix_0f" "1")])
15440
15441 (define_expand "ffsdi2"
15442   [(set (match_dup 2) (const_int -1))
15443    (parallel [(set (reg:CCZ FLAGS_REG)
15444                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15445                                 (const_int 0)))
15446               (set (match_operand:DI 0 "register_operand" "")
15447                    (ctz:DI (match_dup 1)))])
15448    (set (match_dup 0) (if_then_else:DI
15449                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15450                         (match_dup 2)
15451                         (match_dup 0)))
15452    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15453               (clobber (reg:CC FLAGS_REG))])]
15454   "TARGET_64BIT"
15455   "operands[2] = gen_reg_rtx (DImode);")
15456
15457 (define_insn "*ffsdi_1"
15458   [(set (reg:CCZ FLAGS_REG)
15459         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15460                      (const_int 0)))
15461    (set (match_operand:DI 0 "register_operand" "=r")
15462         (ctz:DI (match_dup 1)))]
15463   "TARGET_64BIT"
15464   "bsf{q}\t{%1, %0|%0, %1}"
15465   [(set_attr "prefix_0f" "1")])
15466
15467 (define_insn "ctzsi2"
15468   [(set (match_operand:SI 0 "register_operand" "=r")
15469         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15470    (clobber (reg:CC FLAGS_REG))]
15471   ""
15472   "bsf{l}\t{%1, %0|%0, %1}"
15473   [(set_attr "prefix_0f" "1")])
15474
15475 (define_insn "ctzdi2"
15476   [(set (match_operand:DI 0 "register_operand" "=r")
15477         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15478    (clobber (reg:CC FLAGS_REG))]
15479   "TARGET_64BIT"
15480   "bsf{q}\t{%1, %0|%0, %1}"
15481   [(set_attr "prefix_0f" "1")])
15482
15483 (define_expand "clzsi2"
15484   [(parallel
15485      [(set (match_operand:SI 0 "register_operand" "")
15486            (minus:SI (const_int 31)
15487                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15488       (clobber (reg:CC FLAGS_REG))])
15489    (parallel
15490      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15491       (clobber (reg:CC FLAGS_REG))])]
15492   ""
15493 {
15494   if (TARGET_ABM)
15495     {
15496       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15497       DONE;
15498     }
15499 })
15500
15501 (define_insn "clzsi2_abm"
15502   [(set (match_operand:SI 0 "register_operand" "=r")
15503         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15504    (clobber (reg:CC FLAGS_REG))]
15505   "TARGET_ABM"
15506   "lzcnt{l}\t{%1, %0|%0, %1}"
15507   [(set_attr "prefix_rep" "1")
15508    (set_attr "type" "bitmanip")
15509    (set_attr "mode" "SI")])
15510
15511 (define_insn "*bsr"
15512   [(set (match_operand:SI 0 "register_operand" "=r")
15513         (minus:SI (const_int 31)
15514                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15515    (clobber (reg:CC FLAGS_REG))]
15516   ""
15517   "bsr{l}\t{%1, %0|%0, %1}"
15518   [(set_attr "prefix_0f" "1")
15519    (set_attr "mode" "SI")])
15520
15521 (define_insn "popcount<mode>2"
15522   [(set (match_operand:SWI248 0 "register_operand" "=r")
15523         (popcount:SWI248
15524           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15525    (clobber (reg:CC FLAGS_REG))]
15526   "TARGET_POPCNT"
15527 {
15528 #if TARGET_MACHO
15529   return "popcnt\t{%1, %0|%0, %1}";
15530 #else
15531   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15532 #endif
15533 }
15534   [(set_attr "prefix_rep" "1")
15535    (set_attr "type" "bitmanip")
15536    (set_attr "mode" "<MODE>")])
15537
15538 (define_insn "*popcount<mode>2_cmp"
15539   [(set (reg FLAGS_REG)
15540         (compare
15541           (popcount:SWI248
15542             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15543           (const_int 0)))
15544    (set (match_operand:SWI248 0 "register_operand" "=r")
15545         (popcount:SWI248 (match_dup 1)))]
15546   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15547 {
15548 #if TARGET_MACHO
15549   return "popcnt\t{%1, %0|%0, %1}";
15550 #else
15551   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15552 #endif
15553 }
15554   [(set_attr "prefix_rep" "1")
15555    (set_attr "type" "bitmanip")
15556    (set_attr "mode" "<MODE>")])
15557
15558 (define_insn "*popcountsi2_cmp_zext"
15559   [(set (reg FLAGS_REG)
15560         (compare
15561           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15562           (const_int 0)))
15563    (set (match_operand:DI 0 "register_operand" "=r")
15564         (zero_extend:DI(popcount:SI (match_dup 1))))]
15565   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15566 {
15567 #if TARGET_MACHO
15568   return "popcnt\t{%1, %0|%0, %1}";
15569 #else
15570   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15571 #endif
15572 }
15573   [(set_attr "prefix_rep" "1")
15574    (set_attr "type" "bitmanip")
15575    (set_attr "mode" "SI")])
15576
15577 (define_expand "bswapsi2"
15578   [(set (match_operand:SI 0 "register_operand" "")
15579         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15580   ""
15581 {
15582   if (!TARGET_BSWAP)
15583     {
15584       rtx x = operands[0];
15585
15586       emit_move_insn (x, operands[1]);
15587       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15588       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15589       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15590       DONE;
15591     }
15592 })
15593
15594 (define_insn "*bswapsi_1"
15595   [(set (match_operand:SI 0 "register_operand" "=r")
15596         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15597   "TARGET_BSWAP"
15598   "bswap\t%0"
15599   [(set_attr "prefix_0f" "1")
15600    (set_attr "length" "2")])
15601
15602 (define_insn "*bswaphi_lowpart_1"
15603   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15604         (bswap:HI (match_dup 0)))
15605    (clobber (reg:CC FLAGS_REG))]
15606   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15607   "@
15608     xchg{b}\t{%h0, %b0|%b0, %h0}
15609     rol{w}\t{$8, %0|%0, 8}"
15610   [(set_attr "length" "2,4")
15611    (set_attr "mode" "QI,HI")])
15612
15613 (define_insn "bswaphi_lowpart"
15614   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15615         (bswap:HI (match_dup 0)))
15616    (clobber (reg:CC FLAGS_REG))]
15617   ""
15618   "rol{w}\t{$8, %0|%0, 8}"
15619   [(set_attr "length" "4")
15620    (set_attr "mode" "HI")])
15621
15622 (define_insn "bswapdi2"
15623   [(set (match_operand:DI 0 "register_operand" "=r")
15624         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15625   "TARGET_64BIT"
15626   "bswap\t%0"
15627   [(set_attr "prefix_0f" "1")
15628    (set_attr "length" "3")])
15629
15630 (define_expand "clzdi2"
15631   [(parallel
15632      [(set (match_operand:DI 0 "register_operand" "")
15633            (minus:DI (const_int 63)
15634                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15635       (clobber (reg:CC FLAGS_REG))])
15636    (parallel
15637      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15638       (clobber (reg:CC FLAGS_REG))])]
15639   "TARGET_64BIT"
15640 {
15641   if (TARGET_ABM)
15642     {
15643       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15644       DONE;
15645     }
15646 })
15647
15648 (define_insn "clzdi2_abm"
15649   [(set (match_operand:DI 0 "register_operand" "=r")
15650         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15651    (clobber (reg:CC FLAGS_REG))]
15652   "TARGET_64BIT && TARGET_ABM"
15653   "lzcnt{q}\t{%1, %0|%0, %1}"
15654   [(set_attr "prefix_rep" "1")
15655    (set_attr "type" "bitmanip")
15656    (set_attr "mode" "DI")])
15657
15658 (define_insn "*bsr_rex64"
15659   [(set (match_operand:DI 0 "register_operand" "=r")
15660         (minus:DI (const_int 63)
15661                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15662    (clobber (reg:CC FLAGS_REG))]
15663   "TARGET_64BIT"
15664   "bsr{q}\t{%1, %0|%0, %1}"
15665   [(set_attr "prefix_0f" "1")
15666    (set_attr "mode" "DI")])
15667
15668 (define_expand "clzhi2"
15669   [(parallel
15670      [(set (match_operand:HI 0 "register_operand" "")
15671            (minus:HI (const_int 15)
15672                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15673       (clobber (reg:CC FLAGS_REG))])
15674    (parallel
15675      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15676       (clobber (reg:CC FLAGS_REG))])]
15677   ""
15678 {
15679   if (TARGET_ABM)
15680     {
15681       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15682       DONE;
15683     }
15684 })
15685
15686 (define_insn "clzhi2_abm"
15687   [(set (match_operand:HI 0 "register_operand" "=r")
15688         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15689    (clobber (reg:CC FLAGS_REG))]
15690   "TARGET_ABM"
15691   "lzcnt{w}\t{%1, %0|%0, %1}"
15692   [(set_attr "prefix_rep" "1")
15693    (set_attr "type" "bitmanip")
15694    (set_attr "mode" "HI")])
15695
15696 (define_insn "*bsrhi"
15697   [(set (match_operand:HI 0 "register_operand" "=r")
15698         (minus:HI (const_int 15)
15699                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15700    (clobber (reg:CC FLAGS_REG))]
15701   ""
15702   "bsr{w}\t{%1, %0|%0, %1}"
15703   [(set_attr "prefix_0f" "1")
15704    (set_attr "mode" "HI")])
15705
15706 (define_expand "paritydi2"
15707   [(set (match_operand:DI 0 "register_operand" "")
15708         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15709   "! TARGET_POPCNT"
15710 {
15711   rtx scratch = gen_reg_rtx (QImode);
15712   rtx cond;
15713
15714   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15715                                 NULL_RTX, operands[1]));
15716
15717   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15718                          gen_rtx_REG (CCmode, FLAGS_REG),
15719                          const0_rtx);
15720   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15721
15722   if (TARGET_64BIT)
15723     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15724   else
15725     {
15726       rtx tmp = gen_reg_rtx (SImode);
15727
15728       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15729       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15730     }
15731   DONE;
15732 })
15733
15734 (define_insn_and_split "paritydi2_cmp"
15735   [(set (reg:CC FLAGS_REG)
15736         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15737    (clobber (match_scratch:DI 0 "=r"))
15738    (clobber (match_scratch:SI 1 "=&r"))
15739    (clobber (match_scratch:HI 2 "=Q"))]
15740   "! TARGET_POPCNT"
15741   "#"
15742   "&& reload_completed"
15743   [(parallel
15744      [(set (match_dup 1)
15745            (xor:SI (match_dup 1) (match_dup 4)))
15746       (clobber (reg:CC FLAGS_REG))])
15747    (parallel
15748      [(set (reg:CC FLAGS_REG)
15749            (parity:CC (match_dup 1)))
15750       (clobber (match_dup 1))
15751       (clobber (match_dup 2))])]
15752 {
15753   operands[4] = gen_lowpart (SImode, operands[3]);
15754
15755   if (TARGET_64BIT)
15756     {
15757       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15758       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15759     }
15760   else
15761     operands[1] = gen_highpart (SImode, operands[3]);
15762 })
15763
15764 (define_expand "paritysi2"
15765   [(set (match_operand:SI 0 "register_operand" "")
15766         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15767   "! TARGET_POPCNT"
15768 {
15769   rtx scratch = gen_reg_rtx (QImode);
15770   rtx cond;
15771
15772   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15773
15774   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15775                          gen_rtx_REG (CCmode, FLAGS_REG),
15776                          const0_rtx);
15777   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15778
15779   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15780   DONE;
15781 })
15782
15783 (define_insn_and_split "paritysi2_cmp"
15784   [(set (reg:CC FLAGS_REG)
15785         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15786    (clobber (match_scratch:SI 0 "=r"))
15787    (clobber (match_scratch:HI 1 "=&Q"))]
15788   "! TARGET_POPCNT"
15789   "#"
15790   "&& reload_completed"
15791   [(parallel
15792      [(set (match_dup 1)
15793            (xor:HI (match_dup 1) (match_dup 3)))
15794       (clobber (reg:CC FLAGS_REG))])
15795    (parallel
15796      [(set (reg:CC FLAGS_REG)
15797            (parity:CC (match_dup 1)))
15798       (clobber (match_dup 1))])]
15799 {
15800   operands[3] = gen_lowpart (HImode, operands[2]);
15801
15802   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15803   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15804 })
15805
15806 (define_insn "*parityhi2_cmp"
15807   [(set (reg:CC FLAGS_REG)
15808         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15809    (clobber (match_scratch:HI 0 "=Q"))]
15810   "! TARGET_POPCNT"
15811   "xor{b}\t{%h0, %b0|%b0, %h0}"
15812   [(set_attr "length" "2")
15813    (set_attr "mode" "HI")])
15814
15815 (define_insn "*parityqi2_cmp"
15816   [(set (reg:CC FLAGS_REG)
15817         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15818   "! TARGET_POPCNT"
15819   "test{b}\t%0, %0"
15820   [(set_attr "length" "2")
15821    (set_attr "mode" "QI")])
15822 \f
15823 ;; Thread-local storage patterns for ELF.
15824 ;;
15825 ;; Note that these code sequences must appear exactly as shown
15826 ;; in order to allow linker relaxation.
15827
15828 (define_insn "*tls_global_dynamic_32_gnu"
15829   [(set (match_operand:SI 0 "register_operand" "=a")
15830         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15831                     (match_operand:SI 2 "tls_symbolic_operand" "")
15832                     (match_operand:SI 3 "call_insn_operand" "")]
15833                     UNSPEC_TLS_GD))
15834    (clobber (match_scratch:SI 4 "=d"))
15835    (clobber (match_scratch:SI 5 "=c"))
15836    (clobber (reg:CC FLAGS_REG))]
15837   "!TARGET_64BIT && TARGET_GNU_TLS"
15838   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15839   [(set_attr "type" "multi")
15840    (set_attr "length" "12")])
15841
15842 (define_insn "*tls_global_dynamic_32_sun"
15843   [(set (match_operand:SI 0 "register_operand" "=a")
15844         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15845                     (match_operand:SI 2 "tls_symbolic_operand" "")
15846                     (match_operand:SI 3 "call_insn_operand" "")]
15847                     UNSPEC_TLS_GD))
15848    (clobber (match_scratch:SI 4 "=d"))
15849    (clobber (match_scratch:SI 5 "=c"))
15850    (clobber (reg:CC FLAGS_REG))]
15851   "!TARGET_64BIT && TARGET_SUN_TLS"
15852   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15853         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15854   [(set_attr "type" "multi")
15855    (set_attr "length" "14")])
15856
15857 (define_expand "tls_global_dynamic_32"
15858   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15859                    (unspec:SI
15860                     [(match_dup 2)
15861                      (match_operand:SI 1 "tls_symbolic_operand" "")
15862                      (match_dup 3)]
15863                     UNSPEC_TLS_GD))
15864               (clobber (match_scratch:SI 4 ""))
15865               (clobber (match_scratch:SI 5 ""))
15866               (clobber (reg:CC FLAGS_REG))])]
15867   ""
15868 {
15869   if (flag_pic)
15870     operands[2] = pic_offset_table_rtx;
15871   else
15872     {
15873       operands[2] = gen_reg_rtx (Pmode);
15874       emit_insn (gen_set_got (operands[2]));
15875     }
15876   if (TARGET_GNU2_TLS)
15877     {
15878        emit_insn (gen_tls_dynamic_gnu2_32
15879                   (operands[0], operands[1], operands[2]));
15880        DONE;
15881     }
15882   operands[3] = ix86_tls_get_addr ();
15883 })
15884
15885 (define_insn "*tls_global_dynamic_64"
15886   [(set (match_operand:DI 0 "register_operand" "=a")
15887         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15888                  (match_operand:DI 3 "" "")))
15889    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15890               UNSPEC_TLS_GD)]
15891   "TARGET_64BIT"
15892   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15893   [(set_attr "type" "multi")
15894    (set_attr "length" "16")])
15895
15896 (define_expand "tls_global_dynamic_64"
15897   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15898                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15899               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15900                          UNSPEC_TLS_GD)])]
15901   ""
15902 {
15903   if (TARGET_GNU2_TLS)
15904     {
15905        emit_insn (gen_tls_dynamic_gnu2_64
15906                   (operands[0], operands[1]));
15907        DONE;
15908     }
15909   operands[2] = ix86_tls_get_addr ();
15910 })
15911
15912 (define_insn "*tls_local_dynamic_base_32_gnu"
15913   [(set (match_operand:SI 0 "register_operand" "=a")
15914         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15915                     (match_operand:SI 2 "call_insn_operand" "")]
15916                    UNSPEC_TLS_LD_BASE))
15917    (clobber (match_scratch:SI 3 "=d"))
15918    (clobber (match_scratch:SI 4 "=c"))
15919    (clobber (reg:CC FLAGS_REG))]
15920   "!TARGET_64BIT && TARGET_GNU_TLS"
15921   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15922   [(set_attr "type" "multi")
15923    (set_attr "length" "11")])
15924
15925 (define_insn "*tls_local_dynamic_base_32_sun"
15926   [(set (match_operand:SI 0 "register_operand" "=a")
15927         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15928                     (match_operand:SI 2 "call_insn_operand" "")]
15929                    UNSPEC_TLS_LD_BASE))
15930    (clobber (match_scratch:SI 3 "=d"))
15931    (clobber (match_scratch:SI 4 "=c"))
15932    (clobber (reg:CC FLAGS_REG))]
15933   "!TARGET_64BIT && TARGET_SUN_TLS"
15934   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15935         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15936   [(set_attr "type" "multi")
15937    (set_attr "length" "13")])
15938
15939 (define_expand "tls_local_dynamic_base_32"
15940   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15941                    (unspec:SI [(match_dup 1) (match_dup 2)]
15942                               UNSPEC_TLS_LD_BASE))
15943               (clobber (match_scratch:SI 3 ""))
15944               (clobber (match_scratch:SI 4 ""))
15945               (clobber (reg:CC FLAGS_REG))])]
15946   ""
15947 {
15948   if (flag_pic)
15949     operands[1] = pic_offset_table_rtx;
15950   else
15951     {
15952       operands[1] = gen_reg_rtx (Pmode);
15953       emit_insn (gen_set_got (operands[1]));
15954     }
15955   if (TARGET_GNU2_TLS)
15956     {
15957        emit_insn (gen_tls_dynamic_gnu2_32
15958                   (operands[0], ix86_tls_module_base (), operands[1]));
15959        DONE;
15960     }
15961   operands[2] = ix86_tls_get_addr ();
15962 })
15963
15964 (define_insn "*tls_local_dynamic_base_64"
15965   [(set (match_operand:DI 0 "register_operand" "=a")
15966         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15967                  (match_operand:DI 2 "" "")))
15968    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15969   "TARGET_64BIT"
15970   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15971   [(set_attr "type" "multi")
15972    (set_attr "length" "12")])
15973
15974 (define_expand "tls_local_dynamic_base_64"
15975   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15976                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15977               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15978   ""
15979 {
15980   if (TARGET_GNU2_TLS)
15981     {
15982        emit_insn (gen_tls_dynamic_gnu2_64
15983                   (operands[0], ix86_tls_module_base ()));
15984        DONE;
15985     }
15986   operands[1] = ix86_tls_get_addr ();
15987 })
15988
15989 ;; Local dynamic of a single variable is a lose.  Show combine how
15990 ;; to convert that back to global dynamic.
15991
15992 (define_insn_and_split "*tls_local_dynamic_32_once"
15993   [(set (match_operand:SI 0 "register_operand" "=a")
15994         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15995                              (match_operand:SI 2 "call_insn_operand" "")]
15996                             UNSPEC_TLS_LD_BASE)
15997                  (const:SI (unspec:SI
15998                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15999                             UNSPEC_DTPOFF))))
16000    (clobber (match_scratch:SI 4 "=d"))
16001    (clobber (match_scratch:SI 5 "=c"))
16002    (clobber (reg:CC FLAGS_REG))]
16003   ""
16004   "#"
16005   ""
16006   [(parallel [(set (match_dup 0)
16007                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16008                               UNSPEC_TLS_GD))
16009               (clobber (match_dup 4))
16010               (clobber (match_dup 5))
16011               (clobber (reg:CC FLAGS_REG))])]
16012   "")
16013
16014 ;; Load and add the thread base pointer from %gs:0.
16015
16016 (define_insn "*load_tp_si"
16017   [(set (match_operand:SI 0 "register_operand" "=r")
16018         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16019   "!TARGET_64BIT"
16020   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16021   [(set_attr "type" "imov")
16022    (set_attr "modrm" "0")
16023    (set_attr "length" "7")
16024    (set_attr "memory" "load")
16025    (set_attr "imm_disp" "false")])
16026
16027 (define_insn "*add_tp_si"
16028   [(set (match_operand:SI 0 "register_operand" "=r")
16029         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16030                  (match_operand:SI 1 "register_operand" "0")))
16031    (clobber (reg:CC FLAGS_REG))]
16032   "!TARGET_64BIT"
16033   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16034   [(set_attr "type" "alu")
16035    (set_attr "modrm" "0")
16036    (set_attr "length" "7")
16037    (set_attr "memory" "load")
16038    (set_attr "imm_disp" "false")])
16039
16040 (define_insn "*load_tp_di"
16041   [(set (match_operand:DI 0 "register_operand" "=r")
16042         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16043   "TARGET_64BIT"
16044   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16045   [(set_attr "type" "imov")
16046    (set_attr "modrm" "0")
16047    (set_attr "length" "7")
16048    (set_attr "memory" "load")
16049    (set_attr "imm_disp" "false")])
16050
16051 (define_insn "*add_tp_di"
16052   [(set (match_operand:DI 0 "register_operand" "=r")
16053         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16054                  (match_operand:DI 1 "register_operand" "0")))
16055    (clobber (reg:CC FLAGS_REG))]
16056   "TARGET_64BIT"
16057   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16058   [(set_attr "type" "alu")
16059    (set_attr "modrm" "0")
16060    (set_attr "length" "7")
16061    (set_attr "memory" "load")
16062    (set_attr "imm_disp" "false")])
16063
16064 ;; GNU2 TLS patterns can be split.
16065
16066 (define_expand "tls_dynamic_gnu2_32"
16067   [(set (match_dup 3)
16068         (plus:SI (match_operand:SI 2 "register_operand" "")
16069                  (const:SI
16070                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16071                              UNSPEC_TLSDESC))))
16072    (parallel
16073     [(set (match_operand:SI 0 "register_operand" "")
16074           (unspec:SI [(match_dup 1) (match_dup 3)
16075                       (match_dup 2) (reg:SI SP_REG)]
16076                       UNSPEC_TLSDESC))
16077      (clobber (reg:CC FLAGS_REG))])]
16078   "!TARGET_64BIT && TARGET_GNU2_TLS"
16079 {
16080   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16081   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16082 })
16083
16084 (define_insn "*tls_dynamic_lea_32"
16085   [(set (match_operand:SI 0 "register_operand" "=r")
16086         (plus:SI (match_operand:SI 1 "register_operand" "b")
16087                  (const:SI
16088                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16089                               UNSPEC_TLSDESC))))]
16090   "!TARGET_64BIT && TARGET_GNU2_TLS"
16091   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16092   [(set_attr "type" "lea")
16093    (set_attr "mode" "SI")
16094    (set_attr "length" "6")
16095    (set_attr "length_address" "4")])
16096
16097 (define_insn "*tls_dynamic_call_32"
16098   [(set (match_operand:SI 0 "register_operand" "=a")
16099         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16100                     (match_operand:SI 2 "register_operand" "0")
16101                     ;; we have to make sure %ebx still points to the GOT
16102                     (match_operand:SI 3 "register_operand" "b")
16103                     (reg:SI SP_REG)]
16104                    UNSPEC_TLSDESC))
16105    (clobber (reg:CC FLAGS_REG))]
16106   "!TARGET_64BIT && TARGET_GNU2_TLS"
16107   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16108   [(set_attr "type" "call")
16109    (set_attr "length" "2")
16110    (set_attr "length_address" "0")])
16111
16112 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16113   [(set (match_operand:SI 0 "register_operand" "=&a")
16114         (plus:SI
16115          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16116                      (match_operand:SI 4 "" "")
16117                      (match_operand:SI 2 "register_operand" "b")
16118                      (reg:SI SP_REG)]
16119                     UNSPEC_TLSDESC)
16120          (const:SI (unspec:SI
16121                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16122                     UNSPEC_DTPOFF))))
16123    (clobber (reg:CC FLAGS_REG))]
16124   "!TARGET_64BIT && TARGET_GNU2_TLS"
16125   "#"
16126   ""
16127   [(set (match_dup 0) (match_dup 5))]
16128 {
16129   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16130   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16131 })
16132
16133 (define_expand "tls_dynamic_gnu2_64"
16134   [(set (match_dup 2)
16135         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16136                    UNSPEC_TLSDESC))
16137    (parallel
16138     [(set (match_operand:DI 0 "register_operand" "")
16139           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16140                      UNSPEC_TLSDESC))
16141      (clobber (reg:CC FLAGS_REG))])]
16142   "TARGET_64BIT && TARGET_GNU2_TLS"
16143 {
16144   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16145   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16146 })
16147
16148 (define_insn "*tls_dynamic_lea_64"
16149   [(set (match_operand:DI 0 "register_operand" "=r")
16150         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16151                    UNSPEC_TLSDESC))]
16152   "TARGET_64BIT && TARGET_GNU2_TLS"
16153   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16154   [(set_attr "type" "lea")
16155    (set_attr "mode" "DI")
16156    (set_attr "length" "7")
16157    (set_attr "length_address" "4")])
16158
16159 (define_insn "*tls_dynamic_call_64"
16160   [(set (match_operand:DI 0 "register_operand" "=a")
16161         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16162                     (match_operand:DI 2 "register_operand" "0")
16163                     (reg:DI SP_REG)]
16164                    UNSPEC_TLSDESC))
16165    (clobber (reg:CC FLAGS_REG))]
16166   "TARGET_64BIT && TARGET_GNU2_TLS"
16167   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16168   [(set_attr "type" "call")
16169    (set_attr "length" "2")
16170    (set_attr "length_address" "0")])
16171
16172 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16173   [(set (match_operand:DI 0 "register_operand" "=&a")
16174         (plus:DI
16175          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16176                      (match_operand:DI 3 "" "")
16177                      (reg:DI SP_REG)]
16178                     UNSPEC_TLSDESC)
16179          (const:DI (unspec:DI
16180                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16181                     UNSPEC_DTPOFF))))
16182    (clobber (reg:CC FLAGS_REG))]
16183   "TARGET_64BIT && TARGET_GNU2_TLS"
16184   "#"
16185   ""
16186   [(set (match_dup 0) (match_dup 4))]
16187 {
16188   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16189   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16190 })
16191
16192 ;;
16193 \f
16194 ;; These patterns match the binary 387 instructions for addM3, subM3,
16195 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16196 ;; SFmode.  The first is the normal insn, the second the same insn but
16197 ;; with one operand a conversion, and the third the same insn but with
16198 ;; the other operand a conversion.  The conversion may be SFmode or
16199 ;; SImode if the target mode DFmode, but only SImode if the target mode
16200 ;; is SFmode.
16201
16202 ;; Gcc is slightly more smart about handling normal two address instructions
16203 ;; so use special patterns for add and mull.
16204
16205 (define_insn "*fop_<mode>_comm_mixed_avx"
16206   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16207         (match_operator:MODEF 3 "binary_fp_operator"
16208           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16209            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16210   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16211    && COMMUTATIVE_ARITH_P (operands[3])
16212    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16213   "* return output_387_binary_op (insn, operands);"
16214   [(set (attr "type")
16215         (if_then_else (eq_attr "alternative" "1")
16216            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16217               (const_string "ssemul")
16218               (const_string "sseadd"))
16219            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16220               (const_string "fmul")
16221               (const_string "fop"))))
16222    (set_attr "prefix" "orig,maybe_vex")
16223    (set_attr "mode" "<MODE>")])
16224
16225 (define_insn "*fop_<mode>_comm_mixed"
16226   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16227         (match_operator:MODEF 3 "binary_fp_operator"
16228           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16229            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16230   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16231    && COMMUTATIVE_ARITH_P (operands[3])
16232    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16233   "* return output_387_binary_op (insn, operands);"
16234   [(set (attr "type")
16235         (if_then_else (eq_attr "alternative" "1")
16236            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16237               (const_string "ssemul")
16238               (const_string "sseadd"))
16239            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16240               (const_string "fmul")
16241               (const_string "fop"))))
16242    (set_attr "mode" "<MODE>")])
16243
16244 (define_insn "*fop_<mode>_comm_avx"
16245   [(set (match_operand:MODEF 0 "register_operand" "=x")
16246         (match_operator:MODEF 3 "binary_fp_operator"
16247           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16248            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16249   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16250    && COMMUTATIVE_ARITH_P (operands[3])
16251    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16252   "* return output_387_binary_op (insn, operands);"
16253   [(set (attr "type")
16254         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16255            (const_string "ssemul")
16256            (const_string "sseadd")))
16257    (set_attr "prefix" "vex")
16258    (set_attr "mode" "<MODE>")])
16259
16260 (define_insn "*fop_<mode>_comm_sse"
16261   [(set (match_operand:MODEF 0 "register_operand" "=x")
16262         (match_operator:MODEF 3 "binary_fp_operator"
16263           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16264            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16265   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16266    && COMMUTATIVE_ARITH_P (operands[3])
16267    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16268   "* return output_387_binary_op (insn, operands);"
16269   [(set (attr "type")
16270         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271            (const_string "ssemul")
16272            (const_string "sseadd")))
16273    (set_attr "mode" "<MODE>")])
16274
16275 (define_insn "*fop_<mode>_comm_i387"
16276   [(set (match_operand:MODEF 0 "register_operand" "=f")
16277         (match_operator:MODEF 3 "binary_fp_operator"
16278           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16279            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16280   "TARGET_80387
16281    && COMMUTATIVE_ARITH_P (operands[3])
16282    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16283   "* return output_387_binary_op (insn, operands);"
16284   [(set (attr "type")
16285         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16286            (const_string "fmul")
16287            (const_string "fop")))
16288    (set_attr "mode" "<MODE>")])
16289
16290 (define_insn "*fop_<mode>_1_mixed_avx"
16291   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16292         (match_operator:MODEF 3 "binary_fp_operator"
16293           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16294            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16295   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16296    && !COMMUTATIVE_ARITH_P (operands[3])
16297    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16298   "* return output_387_binary_op (insn, operands);"
16299   [(set (attr "type")
16300         (cond [(and (eq_attr "alternative" "2")
16301                     (match_operand:MODEF 3 "mult_operator" ""))
16302                  (const_string "ssemul")
16303                (and (eq_attr "alternative" "2")
16304                     (match_operand:MODEF 3 "div_operator" ""))
16305                  (const_string "ssediv")
16306                (eq_attr "alternative" "2")
16307                  (const_string "sseadd")
16308                (match_operand:MODEF 3 "mult_operator" "")
16309                  (const_string "fmul")
16310                (match_operand:MODEF 3 "div_operator" "")
16311                  (const_string "fdiv")
16312               ]
16313               (const_string "fop")))
16314    (set_attr "prefix" "orig,orig,maybe_vex")
16315    (set_attr "mode" "<MODE>")])
16316
16317 (define_insn "*fop_<mode>_1_mixed"
16318   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16319         (match_operator:MODEF 3 "binary_fp_operator"
16320           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16321            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16322   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16323    && !COMMUTATIVE_ARITH_P (operands[3])
16324    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16325   "* return output_387_binary_op (insn, operands);"
16326   [(set (attr "type")
16327         (cond [(and (eq_attr "alternative" "2")
16328                     (match_operand:MODEF 3 "mult_operator" ""))
16329                  (const_string "ssemul")
16330                (and (eq_attr "alternative" "2")
16331                     (match_operand:MODEF 3 "div_operator" ""))
16332                  (const_string "ssediv")
16333                (eq_attr "alternative" "2")
16334                  (const_string "sseadd")
16335                (match_operand:MODEF 3 "mult_operator" "")
16336                  (const_string "fmul")
16337                (match_operand:MODEF 3 "div_operator" "")
16338                  (const_string "fdiv")
16339               ]
16340               (const_string "fop")))
16341    (set_attr "mode" "<MODE>")])
16342
16343 (define_insn "*rcpsf2_sse"
16344   [(set (match_operand:SF 0 "register_operand" "=x")
16345         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16346                    UNSPEC_RCP))]
16347   "TARGET_SSE_MATH"
16348   "%vrcpss\t{%1, %d0|%d0, %1}"
16349   [(set_attr "type" "sse")
16350    (set_attr "prefix" "maybe_vex")
16351    (set_attr "mode" "SF")])
16352
16353 (define_insn "*fop_<mode>_1_avx"
16354   [(set (match_operand:MODEF 0 "register_operand" "=x")
16355         (match_operator:MODEF 3 "binary_fp_operator"
16356           [(match_operand:MODEF 1 "register_operand" "x")
16357            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16358   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16359    && !COMMUTATIVE_ARITH_P (operands[3])"
16360   "* return output_387_binary_op (insn, operands);"
16361   [(set (attr "type")
16362         (cond [(match_operand:MODEF 3 "mult_operator" "")
16363                  (const_string "ssemul")
16364                (match_operand:MODEF 3 "div_operator" "")
16365                  (const_string "ssediv")
16366               ]
16367               (const_string "sseadd")))
16368    (set_attr "prefix" "vex")
16369    (set_attr "mode" "<MODE>")])
16370
16371 (define_insn "*fop_<mode>_1_sse"
16372   [(set (match_operand:MODEF 0 "register_operand" "=x")
16373         (match_operator:MODEF 3 "binary_fp_operator"
16374           [(match_operand:MODEF 1 "register_operand" "0")
16375            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16376   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16377    && !COMMUTATIVE_ARITH_P (operands[3])"
16378   "* return output_387_binary_op (insn, operands);"
16379   [(set (attr "type")
16380         (cond [(match_operand:MODEF 3 "mult_operator" "")
16381                  (const_string "ssemul")
16382                (match_operand:MODEF 3 "div_operator" "")
16383                  (const_string "ssediv")
16384               ]
16385               (const_string "sseadd")))
16386    (set_attr "mode" "<MODE>")])
16387
16388 ;; This pattern is not fully shadowed by the pattern above.
16389 (define_insn "*fop_<mode>_1_i387"
16390   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16391         (match_operator:MODEF 3 "binary_fp_operator"
16392           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16393            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16394   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16395    && !COMMUTATIVE_ARITH_P (operands[3])
16396    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16397   "* return output_387_binary_op (insn, operands);"
16398   [(set (attr "type")
16399         (cond [(match_operand:MODEF 3 "mult_operator" "")
16400                  (const_string "fmul")
16401                (match_operand:MODEF 3 "div_operator" "")
16402                  (const_string "fdiv")
16403               ]
16404               (const_string "fop")))
16405    (set_attr "mode" "<MODE>")])
16406
16407 ;; ??? Add SSE splitters for these!
16408 (define_insn "*fop_<MODEF:mode>_2_i387"
16409   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16410         (match_operator:MODEF 3 "binary_fp_operator"
16411           [(float:MODEF
16412              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16413            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16414   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16415    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16416   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16417   [(set (attr "type")
16418         (cond [(match_operand:MODEF 3 "mult_operator" "")
16419                  (const_string "fmul")
16420                (match_operand:MODEF 3 "div_operator" "")
16421                  (const_string "fdiv")
16422               ]
16423               (const_string "fop")))
16424    (set_attr "fp_int_src" "true")
16425    (set_attr "mode" "<X87MODEI12:MODE>")])
16426
16427 (define_insn "*fop_<MODEF:mode>_3_i387"
16428   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16429         (match_operator:MODEF 3 "binary_fp_operator"
16430           [(match_operand:MODEF 1 "register_operand" "0,0")
16431            (float:MODEF
16432              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16433   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16434    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16435   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16436   [(set (attr "type")
16437         (cond [(match_operand:MODEF 3 "mult_operator" "")
16438                  (const_string "fmul")
16439                (match_operand:MODEF 3 "div_operator" "")
16440                  (const_string "fdiv")
16441               ]
16442               (const_string "fop")))
16443    (set_attr "fp_int_src" "true")
16444    (set_attr "mode" "<MODE>")])
16445
16446 (define_insn "*fop_df_4_i387"
16447   [(set (match_operand:DF 0 "register_operand" "=f,f")
16448         (match_operator:DF 3 "binary_fp_operator"
16449            [(float_extend:DF
16450              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16451             (match_operand:DF 2 "register_operand" "0,f")]))]
16452   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16453    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16454   "* return output_387_binary_op (insn, operands);"
16455   [(set (attr "type")
16456         (cond [(match_operand:DF 3 "mult_operator" "")
16457                  (const_string "fmul")
16458                (match_operand:DF 3 "div_operator" "")
16459                  (const_string "fdiv")
16460               ]
16461               (const_string "fop")))
16462    (set_attr "mode" "SF")])
16463
16464 (define_insn "*fop_df_5_i387"
16465   [(set (match_operand:DF 0 "register_operand" "=f,f")
16466         (match_operator:DF 3 "binary_fp_operator"
16467           [(match_operand:DF 1 "register_operand" "0,f")
16468            (float_extend:DF
16469             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16470   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16471   "* return output_387_binary_op (insn, operands);"
16472   [(set (attr "type")
16473         (cond [(match_operand:DF 3 "mult_operator" "")
16474                  (const_string "fmul")
16475                (match_operand:DF 3 "div_operator" "")
16476                  (const_string "fdiv")
16477               ]
16478               (const_string "fop")))
16479    (set_attr "mode" "SF")])
16480
16481 (define_insn "*fop_df_6_i387"
16482   [(set (match_operand:DF 0 "register_operand" "=f,f")
16483         (match_operator:DF 3 "binary_fp_operator"
16484           [(float_extend:DF
16485             (match_operand:SF 1 "register_operand" "0,f"))
16486            (float_extend:DF
16487             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16488   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16489   "* return output_387_binary_op (insn, operands);"
16490   [(set (attr "type")
16491         (cond [(match_operand:DF 3 "mult_operator" "")
16492                  (const_string "fmul")
16493                (match_operand:DF 3 "div_operator" "")
16494                  (const_string "fdiv")
16495               ]
16496               (const_string "fop")))
16497    (set_attr "mode" "SF")])
16498
16499 (define_insn "*fop_xf_comm_i387"
16500   [(set (match_operand:XF 0 "register_operand" "=f")
16501         (match_operator:XF 3 "binary_fp_operator"
16502                         [(match_operand:XF 1 "register_operand" "%0")
16503                          (match_operand:XF 2 "register_operand" "f")]))]
16504   "TARGET_80387
16505    && COMMUTATIVE_ARITH_P (operands[3])"
16506   "* return output_387_binary_op (insn, operands);"
16507   [(set (attr "type")
16508         (if_then_else (match_operand:XF 3 "mult_operator" "")
16509            (const_string "fmul")
16510            (const_string "fop")))
16511    (set_attr "mode" "XF")])
16512
16513 (define_insn "*fop_xf_1_i387"
16514   [(set (match_operand:XF 0 "register_operand" "=f,f")
16515         (match_operator:XF 3 "binary_fp_operator"
16516                         [(match_operand:XF 1 "register_operand" "0,f")
16517                          (match_operand:XF 2 "register_operand" "f,0")]))]
16518   "TARGET_80387
16519    && !COMMUTATIVE_ARITH_P (operands[3])"
16520   "* return output_387_binary_op (insn, operands);"
16521   [(set (attr "type")
16522         (cond [(match_operand:XF 3 "mult_operator" "")
16523                  (const_string "fmul")
16524                (match_operand:XF 3 "div_operator" "")
16525                  (const_string "fdiv")
16526               ]
16527               (const_string "fop")))
16528    (set_attr "mode" "XF")])
16529
16530 (define_insn "*fop_xf_2_i387"
16531   [(set (match_operand:XF 0 "register_operand" "=f,f")
16532         (match_operator:XF 3 "binary_fp_operator"
16533           [(float:XF
16534              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16535            (match_operand:XF 2 "register_operand" "0,0")]))]
16536   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16537   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16538   [(set (attr "type")
16539         (cond [(match_operand:XF 3 "mult_operator" "")
16540                  (const_string "fmul")
16541                (match_operand:XF 3 "div_operator" "")
16542                  (const_string "fdiv")
16543               ]
16544               (const_string "fop")))
16545    (set_attr "fp_int_src" "true")
16546    (set_attr "mode" "<MODE>")])
16547
16548 (define_insn "*fop_xf_3_i387"
16549   [(set (match_operand:XF 0 "register_operand" "=f,f")
16550         (match_operator:XF 3 "binary_fp_operator"
16551           [(match_operand:XF 1 "register_operand" "0,0")
16552            (float:XF
16553              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16554   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16555   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16556   [(set (attr "type")
16557         (cond [(match_operand:XF 3 "mult_operator" "")
16558                  (const_string "fmul")
16559                (match_operand:XF 3 "div_operator" "")
16560                  (const_string "fdiv")
16561               ]
16562               (const_string "fop")))
16563    (set_attr "fp_int_src" "true")
16564    (set_attr "mode" "<MODE>")])
16565
16566 (define_insn "*fop_xf_4_i387"
16567   [(set (match_operand:XF 0 "register_operand" "=f,f")
16568         (match_operator:XF 3 "binary_fp_operator"
16569            [(float_extend:XF
16570               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16571             (match_operand:XF 2 "register_operand" "0,f")]))]
16572   "TARGET_80387"
16573   "* return output_387_binary_op (insn, operands);"
16574   [(set (attr "type")
16575         (cond [(match_operand:XF 3 "mult_operator" "")
16576                  (const_string "fmul")
16577                (match_operand:XF 3 "div_operator" "")
16578                  (const_string "fdiv")
16579               ]
16580               (const_string "fop")))
16581    (set_attr "mode" "<MODE>")])
16582
16583 (define_insn "*fop_xf_5_i387"
16584   [(set (match_operand:XF 0 "register_operand" "=f,f")
16585         (match_operator:XF 3 "binary_fp_operator"
16586           [(match_operand:XF 1 "register_operand" "0,f")
16587            (float_extend:XF
16588              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16589   "TARGET_80387"
16590   "* return output_387_binary_op (insn, operands);"
16591   [(set (attr "type")
16592         (cond [(match_operand:XF 3 "mult_operator" "")
16593                  (const_string "fmul")
16594                (match_operand:XF 3 "div_operator" "")
16595                  (const_string "fdiv")
16596               ]
16597               (const_string "fop")))
16598    (set_attr "mode" "<MODE>")])
16599
16600 (define_insn "*fop_xf_6_i387"
16601   [(set (match_operand:XF 0 "register_operand" "=f,f")
16602         (match_operator:XF 3 "binary_fp_operator"
16603           [(float_extend:XF
16604              (match_operand:MODEF 1 "register_operand" "0,f"))
16605            (float_extend:XF
16606              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16607   "TARGET_80387"
16608   "* return output_387_binary_op (insn, operands);"
16609   [(set (attr "type")
16610         (cond [(match_operand:XF 3 "mult_operator" "")
16611                  (const_string "fmul")
16612                (match_operand:XF 3 "div_operator" "")
16613                  (const_string "fdiv")
16614               ]
16615               (const_string "fop")))
16616    (set_attr "mode" "<MODE>")])
16617
16618 (define_split
16619   [(set (match_operand 0 "register_operand" "")
16620         (match_operator 3 "binary_fp_operator"
16621            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16622             (match_operand 2 "register_operand" "")]))]
16623   "reload_completed
16624    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16625   [(const_int 0)]
16626 {
16627   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16628   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16629   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16630                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16631                                           GET_MODE (operands[3]),
16632                                           operands[4],
16633                                           operands[2])));
16634   ix86_free_from_memory (GET_MODE (operands[1]));
16635   DONE;
16636 })
16637
16638 (define_split
16639   [(set (match_operand 0 "register_operand" "")
16640         (match_operator 3 "binary_fp_operator"
16641            [(match_operand 1 "register_operand" "")
16642             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16643   "reload_completed
16644    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16645   [(const_int 0)]
16646 {
16647   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16648   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16649   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16650                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16651                                           GET_MODE (operands[3]),
16652                                           operands[1],
16653                                           operands[4])));
16654   ix86_free_from_memory (GET_MODE (operands[2]));
16655   DONE;
16656 })
16657 \f
16658 ;; FPU special functions.
16659
16660 ;; This pattern implements a no-op XFmode truncation for
16661 ;; all fancy i386 XFmode math functions.
16662
16663 (define_insn "truncxf<mode>2_i387_noop_unspec"
16664   [(set (match_operand:MODEF 0 "register_operand" "=f")
16665         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16666         UNSPEC_TRUNC_NOOP))]
16667   "TARGET_USE_FANCY_MATH_387"
16668   "* return output_387_reg_move (insn, operands);"
16669   [(set_attr "type" "fmov")
16670    (set_attr "mode" "<MODE>")])
16671
16672 (define_insn "sqrtxf2"
16673   [(set (match_operand:XF 0 "register_operand" "=f")
16674         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16675   "TARGET_USE_FANCY_MATH_387"
16676   "fsqrt"
16677   [(set_attr "type" "fpspc")
16678    (set_attr "mode" "XF")
16679    (set_attr "athlon_decode" "direct")
16680    (set_attr "amdfam10_decode" "direct")])
16681
16682 (define_insn "sqrt_extend<mode>xf2_i387"
16683   [(set (match_operand:XF 0 "register_operand" "=f")
16684         (sqrt:XF
16685           (float_extend:XF
16686             (match_operand:MODEF 1 "register_operand" "0"))))]
16687   "TARGET_USE_FANCY_MATH_387"
16688   "fsqrt"
16689   [(set_attr "type" "fpspc")
16690    (set_attr "mode" "XF")
16691    (set_attr "athlon_decode" "direct")
16692    (set_attr "amdfam10_decode" "direct")])
16693
16694 (define_insn "*rsqrtsf2_sse"
16695   [(set (match_operand:SF 0 "register_operand" "=x")
16696         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16697                    UNSPEC_RSQRT))]
16698   "TARGET_SSE_MATH"
16699   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16700   [(set_attr "type" "sse")
16701    (set_attr "prefix" "maybe_vex")
16702    (set_attr "mode" "SF")])
16703
16704 (define_expand "rsqrtsf2"
16705   [(set (match_operand:SF 0 "register_operand" "")
16706         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16707                    UNSPEC_RSQRT))]
16708   "TARGET_SSE_MATH"
16709 {
16710   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16711   DONE;
16712 })
16713
16714 (define_insn "*sqrt<mode>2_sse"
16715   [(set (match_operand:MODEF 0 "register_operand" "=x")
16716         (sqrt:MODEF
16717           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16718   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16719   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16720   [(set_attr "type" "sse")
16721    (set_attr "prefix" "maybe_vex")
16722    (set_attr "mode" "<MODE>")
16723    (set_attr "athlon_decode" "*")
16724    (set_attr "amdfam10_decode" "*")])
16725
16726 (define_expand "sqrt<mode>2"
16727   [(set (match_operand:MODEF 0 "register_operand" "")
16728         (sqrt:MODEF
16729           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16730   "TARGET_USE_FANCY_MATH_387
16731    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16732 {
16733   if (<MODE>mode == SFmode
16734       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16735       && flag_finite_math_only && !flag_trapping_math
16736       && flag_unsafe_math_optimizations)
16737     {
16738       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16739       DONE;
16740     }
16741
16742   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16743     {
16744       rtx op0 = gen_reg_rtx (XFmode);
16745       rtx op1 = force_reg (<MODE>mode, operands[1]);
16746
16747       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16748       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16749       DONE;
16750    }
16751 })
16752
16753 (define_insn "fpremxf4_i387"
16754   [(set (match_operand:XF 0 "register_operand" "=f")
16755         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16756                     (match_operand:XF 3 "register_operand" "1")]
16757                    UNSPEC_FPREM_F))
16758    (set (match_operand:XF 1 "register_operand" "=u")
16759         (unspec:XF [(match_dup 2) (match_dup 3)]
16760                    UNSPEC_FPREM_U))
16761    (set (reg:CCFP FPSR_REG)
16762         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16763                      UNSPEC_C2_FLAG))]
16764   "TARGET_USE_FANCY_MATH_387"
16765   "fprem"
16766   [(set_attr "type" "fpspc")
16767    (set_attr "mode" "XF")])
16768
16769 (define_expand "fmodxf3"
16770   [(use (match_operand:XF 0 "register_operand" ""))
16771    (use (match_operand:XF 1 "general_operand" ""))
16772    (use (match_operand:XF 2 "general_operand" ""))]
16773   "TARGET_USE_FANCY_MATH_387"
16774 {
16775   rtx label = gen_label_rtx ();
16776
16777   rtx op1 = gen_reg_rtx (XFmode);
16778   rtx op2 = gen_reg_rtx (XFmode);
16779
16780   emit_move_insn (op2, operands[2]);
16781   emit_move_insn (op1, operands[1]);
16782
16783   emit_label (label);
16784   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16785   ix86_emit_fp_unordered_jump (label);
16786   LABEL_NUSES (label) = 1;
16787
16788   emit_move_insn (operands[0], op1);
16789   DONE;
16790 })
16791
16792 (define_expand "fmod<mode>3"
16793   [(use (match_operand:MODEF 0 "register_operand" ""))
16794    (use (match_operand:MODEF 1 "general_operand" ""))
16795    (use (match_operand:MODEF 2 "general_operand" ""))]
16796   "TARGET_USE_FANCY_MATH_387"
16797 {
16798   rtx label = gen_label_rtx ();
16799
16800   rtx op1 = gen_reg_rtx (XFmode);
16801   rtx op2 = gen_reg_rtx (XFmode);
16802
16803   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16804   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16805
16806   emit_label (label);
16807   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16808   ix86_emit_fp_unordered_jump (label);
16809   LABEL_NUSES (label) = 1;
16810
16811   /* Truncate the result properly for strict SSE math.  */
16812   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16813       && !TARGET_MIX_SSE_I387)
16814     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16815   else
16816     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16817
16818   DONE;
16819 })
16820
16821 (define_insn "fprem1xf4_i387"
16822   [(set (match_operand:XF 0 "register_operand" "=f")
16823         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16824                     (match_operand:XF 3 "register_operand" "1")]
16825                    UNSPEC_FPREM1_F))
16826    (set (match_operand:XF 1 "register_operand" "=u")
16827         (unspec:XF [(match_dup 2) (match_dup 3)]
16828                    UNSPEC_FPREM1_U))
16829    (set (reg:CCFP FPSR_REG)
16830         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16831                      UNSPEC_C2_FLAG))]
16832   "TARGET_USE_FANCY_MATH_387"
16833   "fprem1"
16834   [(set_attr "type" "fpspc")
16835    (set_attr "mode" "XF")])
16836
16837 (define_expand "remainderxf3"
16838   [(use (match_operand:XF 0 "register_operand" ""))
16839    (use (match_operand:XF 1 "general_operand" ""))
16840    (use (match_operand:XF 2 "general_operand" ""))]
16841   "TARGET_USE_FANCY_MATH_387"
16842 {
16843   rtx label = gen_label_rtx ();
16844
16845   rtx op1 = gen_reg_rtx (XFmode);
16846   rtx op2 = gen_reg_rtx (XFmode);
16847
16848   emit_move_insn (op2, operands[2]);
16849   emit_move_insn (op1, operands[1]);
16850
16851   emit_label (label);
16852   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16853   ix86_emit_fp_unordered_jump (label);
16854   LABEL_NUSES (label) = 1;
16855
16856   emit_move_insn (operands[0], op1);
16857   DONE;
16858 })
16859
16860 (define_expand "remainder<mode>3"
16861   [(use (match_operand:MODEF 0 "register_operand" ""))
16862    (use (match_operand:MODEF 1 "general_operand" ""))
16863    (use (match_operand:MODEF 2 "general_operand" ""))]
16864   "TARGET_USE_FANCY_MATH_387"
16865 {
16866   rtx label = gen_label_rtx ();
16867
16868   rtx op1 = gen_reg_rtx (XFmode);
16869   rtx op2 = gen_reg_rtx (XFmode);
16870
16871   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16872   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16873
16874   emit_label (label);
16875
16876   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16877   ix86_emit_fp_unordered_jump (label);
16878   LABEL_NUSES (label) = 1;
16879
16880   /* Truncate the result properly for strict SSE math.  */
16881   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16882       && !TARGET_MIX_SSE_I387)
16883     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16884   else
16885     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16886
16887   DONE;
16888 })
16889
16890 (define_insn "*sinxf2_i387"
16891   [(set (match_operand:XF 0 "register_operand" "=f")
16892         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16893   "TARGET_USE_FANCY_MATH_387
16894    && flag_unsafe_math_optimizations"
16895   "fsin"
16896   [(set_attr "type" "fpspc")
16897    (set_attr "mode" "XF")])
16898
16899 (define_insn "*sin_extend<mode>xf2_i387"
16900   [(set (match_operand:XF 0 "register_operand" "=f")
16901         (unspec:XF [(float_extend:XF
16902                       (match_operand:MODEF 1 "register_operand" "0"))]
16903                    UNSPEC_SIN))]
16904   "TARGET_USE_FANCY_MATH_387
16905    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16906        || TARGET_MIX_SSE_I387)
16907    && flag_unsafe_math_optimizations"
16908   "fsin"
16909   [(set_attr "type" "fpspc")
16910    (set_attr "mode" "XF")])
16911
16912 (define_insn "*cosxf2_i387"
16913   [(set (match_operand:XF 0 "register_operand" "=f")
16914         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16915   "TARGET_USE_FANCY_MATH_387
16916    && flag_unsafe_math_optimizations"
16917   "fcos"
16918   [(set_attr "type" "fpspc")
16919    (set_attr "mode" "XF")])
16920
16921 (define_insn "*cos_extend<mode>xf2_i387"
16922   [(set (match_operand:XF 0 "register_operand" "=f")
16923         (unspec:XF [(float_extend:XF
16924                       (match_operand:MODEF 1 "register_operand" "0"))]
16925                    UNSPEC_COS))]
16926   "TARGET_USE_FANCY_MATH_387
16927    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16928        || TARGET_MIX_SSE_I387)
16929    && flag_unsafe_math_optimizations"
16930   "fcos"
16931   [(set_attr "type" "fpspc")
16932    (set_attr "mode" "XF")])
16933
16934 ;; When sincos pattern is defined, sin and cos builtin functions will be
16935 ;; expanded to sincos pattern with one of its outputs left unused.
16936 ;; CSE pass will figure out if two sincos patterns can be combined,
16937 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16938 ;; depending on the unused output.
16939
16940 (define_insn "sincosxf3"
16941   [(set (match_operand:XF 0 "register_operand" "=f")
16942         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16943                    UNSPEC_SINCOS_COS))
16944    (set (match_operand:XF 1 "register_operand" "=u")
16945         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16946   "TARGET_USE_FANCY_MATH_387
16947    && flag_unsafe_math_optimizations"
16948   "fsincos"
16949   [(set_attr "type" "fpspc")
16950    (set_attr "mode" "XF")])
16951
16952 (define_split
16953   [(set (match_operand:XF 0 "register_operand" "")
16954         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16955                    UNSPEC_SINCOS_COS))
16956    (set (match_operand:XF 1 "register_operand" "")
16957         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16958   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16959    && !(reload_completed || reload_in_progress)"
16960   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16961   "")
16962
16963 (define_split
16964   [(set (match_operand:XF 0 "register_operand" "")
16965         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16966                    UNSPEC_SINCOS_COS))
16967    (set (match_operand:XF 1 "register_operand" "")
16968         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16969   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16970    && !(reload_completed || reload_in_progress)"
16971   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16972   "")
16973
16974 (define_insn "sincos_extend<mode>xf3_i387"
16975   [(set (match_operand:XF 0 "register_operand" "=f")
16976         (unspec:XF [(float_extend:XF
16977                       (match_operand:MODEF 2 "register_operand" "0"))]
16978                    UNSPEC_SINCOS_COS))
16979    (set (match_operand:XF 1 "register_operand" "=u")
16980         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16981   "TARGET_USE_FANCY_MATH_387
16982    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16983        || TARGET_MIX_SSE_I387)
16984    && flag_unsafe_math_optimizations"
16985   "fsincos"
16986   [(set_attr "type" "fpspc")
16987    (set_attr "mode" "XF")])
16988
16989 (define_split
16990   [(set (match_operand:XF 0 "register_operand" "")
16991         (unspec:XF [(float_extend:XF
16992                       (match_operand:MODEF 2 "register_operand" ""))]
16993                    UNSPEC_SINCOS_COS))
16994    (set (match_operand:XF 1 "register_operand" "")
16995         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16996   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16997    && !(reload_completed || reload_in_progress)"
16998   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16999   "")
17000
17001 (define_split
17002   [(set (match_operand:XF 0 "register_operand" "")
17003         (unspec:XF [(float_extend:XF
17004                       (match_operand:MODEF 2 "register_operand" ""))]
17005                    UNSPEC_SINCOS_COS))
17006    (set (match_operand:XF 1 "register_operand" "")
17007         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17008   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17009    && !(reload_completed || reload_in_progress)"
17010   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17011   "")
17012
17013 (define_expand "sincos<mode>3"
17014   [(use (match_operand:MODEF 0 "register_operand" ""))
17015    (use (match_operand:MODEF 1 "register_operand" ""))
17016    (use (match_operand:MODEF 2 "register_operand" ""))]
17017   "TARGET_USE_FANCY_MATH_387
17018    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17019        || TARGET_MIX_SSE_I387)
17020    && flag_unsafe_math_optimizations"
17021 {
17022   rtx op0 = gen_reg_rtx (XFmode);
17023   rtx op1 = gen_reg_rtx (XFmode);
17024
17025   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17026   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17027   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17028   DONE;
17029 })
17030
17031 (define_insn "fptanxf4_i387"
17032   [(set (match_operand:XF 0 "register_operand" "=f")
17033         (match_operand:XF 3 "const_double_operand" "F"))
17034    (set (match_operand:XF 1 "register_operand" "=u")
17035         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17036                    UNSPEC_TAN))]
17037   "TARGET_USE_FANCY_MATH_387
17038    && flag_unsafe_math_optimizations
17039    && standard_80387_constant_p (operands[3]) == 2"
17040   "fptan"
17041   [(set_attr "type" "fpspc")
17042    (set_attr "mode" "XF")])
17043
17044 (define_insn "fptan_extend<mode>xf4_i387"
17045   [(set (match_operand:MODEF 0 "register_operand" "=f")
17046         (match_operand:MODEF 3 "const_double_operand" "F"))
17047    (set (match_operand:XF 1 "register_operand" "=u")
17048         (unspec:XF [(float_extend:XF
17049                       (match_operand:MODEF 2 "register_operand" "0"))]
17050                    UNSPEC_TAN))]
17051   "TARGET_USE_FANCY_MATH_387
17052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053        || TARGET_MIX_SSE_I387)
17054    && flag_unsafe_math_optimizations
17055    && standard_80387_constant_p (operands[3]) == 2"
17056   "fptan"
17057   [(set_attr "type" "fpspc")
17058    (set_attr "mode" "XF")])
17059
17060 (define_expand "tanxf2"
17061   [(use (match_operand:XF 0 "register_operand" ""))
17062    (use (match_operand:XF 1 "register_operand" ""))]
17063   "TARGET_USE_FANCY_MATH_387
17064    && flag_unsafe_math_optimizations"
17065 {
17066   rtx one = gen_reg_rtx (XFmode);
17067   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17068
17069   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17070   DONE;
17071 })
17072
17073 (define_expand "tan<mode>2"
17074   [(use (match_operand:MODEF 0 "register_operand" ""))
17075    (use (match_operand:MODEF 1 "register_operand" ""))]
17076   "TARGET_USE_FANCY_MATH_387
17077    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17078        || TARGET_MIX_SSE_I387)
17079    && flag_unsafe_math_optimizations"
17080 {
17081   rtx op0 = gen_reg_rtx (XFmode);
17082
17083   rtx one = gen_reg_rtx (<MODE>mode);
17084   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17085
17086   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17087                                              operands[1], op2));
17088   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17089   DONE;
17090 })
17091
17092 (define_insn "*fpatanxf3_i387"
17093   [(set (match_operand:XF 0 "register_operand" "=f")
17094         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17095                     (match_operand:XF 2 "register_operand" "u")]
17096                    UNSPEC_FPATAN))
17097    (clobber (match_scratch:XF 3 "=2"))]
17098   "TARGET_USE_FANCY_MATH_387
17099    && flag_unsafe_math_optimizations"
17100   "fpatan"
17101   [(set_attr "type" "fpspc")
17102    (set_attr "mode" "XF")])
17103
17104 (define_insn "fpatan_extend<mode>xf3_i387"
17105   [(set (match_operand:XF 0 "register_operand" "=f")
17106         (unspec:XF [(float_extend:XF
17107                       (match_operand:MODEF 1 "register_operand" "0"))
17108                     (float_extend:XF
17109                       (match_operand:MODEF 2 "register_operand" "u"))]
17110                    UNSPEC_FPATAN))
17111    (clobber (match_scratch:XF 3 "=2"))]
17112   "TARGET_USE_FANCY_MATH_387
17113    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17114        || TARGET_MIX_SSE_I387)
17115    && flag_unsafe_math_optimizations"
17116   "fpatan"
17117   [(set_attr "type" "fpspc")
17118    (set_attr "mode" "XF")])
17119
17120 (define_expand "atan2xf3"
17121   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17122                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17123                                (match_operand:XF 1 "register_operand" "")]
17124                               UNSPEC_FPATAN))
17125               (clobber (match_scratch:XF 3 ""))])]
17126   "TARGET_USE_FANCY_MATH_387
17127    && flag_unsafe_math_optimizations"
17128   "")
17129
17130 (define_expand "atan2<mode>3"
17131   [(use (match_operand:MODEF 0 "register_operand" ""))
17132    (use (match_operand:MODEF 1 "register_operand" ""))
17133    (use (match_operand:MODEF 2 "register_operand" ""))]
17134   "TARGET_USE_FANCY_MATH_387
17135    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17136        || TARGET_MIX_SSE_I387)
17137    && flag_unsafe_math_optimizations"
17138 {
17139   rtx op0 = gen_reg_rtx (XFmode);
17140
17141   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17142   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17143   DONE;
17144 })
17145
17146 (define_expand "atanxf2"
17147   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17148                    (unspec:XF [(match_dup 2)
17149                                (match_operand:XF 1 "register_operand" "")]
17150                               UNSPEC_FPATAN))
17151               (clobber (match_scratch:XF 3 ""))])]
17152   "TARGET_USE_FANCY_MATH_387
17153    && flag_unsafe_math_optimizations"
17154 {
17155   operands[2] = gen_reg_rtx (XFmode);
17156   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17157 })
17158
17159 (define_expand "atan<mode>2"
17160   [(use (match_operand:MODEF 0 "register_operand" ""))
17161    (use (match_operand:MODEF 1 "register_operand" ""))]
17162   "TARGET_USE_FANCY_MATH_387
17163    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17164        || TARGET_MIX_SSE_I387)
17165    && flag_unsafe_math_optimizations"
17166 {
17167   rtx op0 = gen_reg_rtx (XFmode);
17168
17169   rtx op2 = gen_reg_rtx (<MODE>mode);
17170   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17171
17172   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17173   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17174   DONE;
17175 })
17176
17177 (define_expand "asinxf2"
17178   [(set (match_dup 2)
17179         (mult:XF (match_operand:XF 1 "register_operand" "")
17180                  (match_dup 1)))
17181    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17182    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17183    (parallel [(set (match_operand:XF 0 "register_operand" "")
17184                    (unspec:XF [(match_dup 5) (match_dup 1)]
17185                               UNSPEC_FPATAN))
17186               (clobber (match_scratch:XF 6 ""))])]
17187   "TARGET_USE_FANCY_MATH_387
17188    && flag_unsafe_math_optimizations"
17189 {
17190   int i;
17191
17192   if (optimize_insn_for_size_p ())
17193     FAIL;
17194
17195   for (i = 2; i < 6; i++)
17196     operands[i] = gen_reg_rtx (XFmode);
17197
17198   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17199 })
17200
17201 (define_expand "asin<mode>2"
17202   [(use (match_operand:MODEF 0 "register_operand" ""))
17203    (use (match_operand:MODEF 1 "general_operand" ""))]
17204  "TARGET_USE_FANCY_MATH_387
17205    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17206        || TARGET_MIX_SSE_I387)
17207    && flag_unsafe_math_optimizations"
17208 {
17209   rtx op0 = gen_reg_rtx (XFmode);
17210   rtx op1 = gen_reg_rtx (XFmode);
17211
17212   if (optimize_insn_for_size_p ())
17213     FAIL;
17214
17215   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17216   emit_insn (gen_asinxf2 (op0, op1));
17217   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17218   DONE;
17219 })
17220
17221 (define_expand "acosxf2"
17222   [(set (match_dup 2)
17223         (mult:XF (match_operand:XF 1 "register_operand" "")
17224                  (match_dup 1)))
17225    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17226    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17227    (parallel [(set (match_operand:XF 0 "register_operand" "")
17228                    (unspec:XF [(match_dup 1) (match_dup 5)]
17229                               UNSPEC_FPATAN))
17230               (clobber (match_scratch:XF 6 ""))])]
17231   "TARGET_USE_FANCY_MATH_387
17232    && flag_unsafe_math_optimizations"
17233 {
17234   int i;
17235
17236   if (optimize_insn_for_size_p ())
17237     FAIL;
17238
17239   for (i = 2; i < 6; i++)
17240     operands[i] = gen_reg_rtx (XFmode);
17241
17242   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17243 })
17244
17245 (define_expand "acos<mode>2"
17246   [(use (match_operand:MODEF 0 "register_operand" ""))
17247    (use (match_operand:MODEF 1 "general_operand" ""))]
17248  "TARGET_USE_FANCY_MATH_387
17249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17250        || TARGET_MIX_SSE_I387)
17251    && flag_unsafe_math_optimizations"
17252 {
17253   rtx op0 = gen_reg_rtx (XFmode);
17254   rtx op1 = gen_reg_rtx (XFmode);
17255
17256   if (optimize_insn_for_size_p ())
17257     FAIL;
17258
17259   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17260   emit_insn (gen_acosxf2 (op0, op1));
17261   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17262   DONE;
17263 })
17264
17265 (define_insn "fyl2xxf3_i387"
17266   [(set (match_operand:XF 0 "register_operand" "=f")
17267         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17268                     (match_operand:XF 2 "register_operand" "u")]
17269                    UNSPEC_FYL2X))
17270    (clobber (match_scratch:XF 3 "=2"))]
17271   "TARGET_USE_FANCY_MATH_387
17272    && flag_unsafe_math_optimizations"
17273   "fyl2x"
17274   [(set_attr "type" "fpspc")
17275    (set_attr "mode" "XF")])
17276
17277 (define_insn "fyl2x_extend<mode>xf3_i387"
17278   [(set (match_operand:XF 0 "register_operand" "=f")
17279         (unspec:XF [(float_extend:XF
17280                       (match_operand:MODEF 1 "register_operand" "0"))
17281                     (match_operand:XF 2 "register_operand" "u")]
17282                    UNSPEC_FYL2X))
17283    (clobber (match_scratch:XF 3 "=2"))]
17284   "TARGET_USE_FANCY_MATH_387
17285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17286        || TARGET_MIX_SSE_I387)
17287    && flag_unsafe_math_optimizations"
17288   "fyl2x"
17289   [(set_attr "type" "fpspc")
17290    (set_attr "mode" "XF")])
17291
17292 (define_expand "logxf2"
17293   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17294                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17295                                (match_dup 2)] UNSPEC_FYL2X))
17296               (clobber (match_scratch:XF 3 ""))])]
17297   "TARGET_USE_FANCY_MATH_387
17298    && flag_unsafe_math_optimizations"
17299 {
17300   operands[2] = gen_reg_rtx (XFmode);
17301   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17302 })
17303
17304 (define_expand "log<mode>2"
17305   [(use (match_operand:MODEF 0 "register_operand" ""))
17306    (use (match_operand:MODEF 1 "register_operand" ""))]
17307   "TARGET_USE_FANCY_MATH_387
17308    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17309        || TARGET_MIX_SSE_I387)
17310    && flag_unsafe_math_optimizations"
17311 {
17312   rtx op0 = gen_reg_rtx (XFmode);
17313
17314   rtx op2 = gen_reg_rtx (XFmode);
17315   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17316
17317   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17318   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17319   DONE;
17320 })
17321
17322 (define_expand "log10xf2"
17323   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17324                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17325                                (match_dup 2)] UNSPEC_FYL2X))
17326               (clobber (match_scratch:XF 3 ""))])]
17327   "TARGET_USE_FANCY_MATH_387
17328    && flag_unsafe_math_optimizations"
17329 {
17330   operands[2] = gen_reg_rtx (XFmode);
17331   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17332 })
17333
17334 (define_expand "log10<mode>2"
17335   [(use (match_operand:MODEF 0 "register_operand" ""))
17336    (use (match_operand:MODEF 1 "register_operand" ""))]
17337   "TARGET_USE_FANCY_MATH_387
17338    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17339        || TARGET_MIX_SSE_I387)
17340    && flag_unsafe_math_optimizations"
17341 {
17342   rtx op0 = gen_reg_rtx (XFmode);
17343
17344   rtx op2 = gen_reg_rtx (XFmode);
17345   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17346
17347   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17348   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17349   DONE;
17350 })
17351
17352 (define_expand "log2xf2"
17353   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17354                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17355                                (match_dup 2)] UNSPEC_FYL2X))
17356               (clobber (match_scratch:XF 3 ""))])]
17357   "TARGET_USE_FANCY_MATH_387
17358    && flag_unsafe_math_optimizations"
17359 {
17360   operands[2] = gen_reg_rtx (XFmode);
17361   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17362 })
17363
17364 (define_expand "log2<mode>2"
17365   [(use (match_operand:MODEF 0 "register_operand" ""))
17366    (use (match_operand:MODEF 1 "register_operand" ""))]
17367   "TARGET_USE_FANCY_MATH_387
17368    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17369        || TARGET_MIX_SSE_I387)
17370    && flag_unsafe_math_optimizations"
17371 {
17372   rtx op0 = gen_reg_rtx (XFmode);
17373
17374   rtx op2 = gen_reg_rtx (XFmode);
17375   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17376
17377   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17378   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17379   DONE;
17380 })
17381
17382 (define_insn "fyl2xp1xf3_i387"
17383   [(set (match_operand:XF 0 "register_operand" "=f")
17384         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17385                     (match_operand:XF 2 "register_operand" "u")]
17386                    UNSPEC_FYL2XP1))
17387    (clobber (match_scratch:XF 3 "=2"))]
17388   "TARGET_USE_FANCY_MATH_387
17389    && flag_unsafe_math_optimizations"
17390   "fyl2xp1"
17391   [(set_attr "type" "fpspc")
17392    (set_attr "mode" "XF")])
17393
17394 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17395   [(set (match_operand:XF 0 "register_operand" "=f")
17396         (unspec:XF [(float_extend:XF
17397                       (match_operand:MODEF 1 "register_operand" "0"))
17398                     (match_operand:XF 2 "register_operand" "u")]
17399                    UNSPEC_FYL2XP1))
17400    (clobber (match_scratch:XF 3 "=2"))]
17401   "TARGET_USE_FANCY_MATH_387
17402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403        || TARGET_MIX_SSE_I387)
17404    && flag_unsafe_math_optimizations"
17405   "fyl2xp1"
17406   [(set_attr "type" "fpspc")
17407    (set_attr "mode" "XF")])
17408
17409 (define_expand "log1pxf2"
17410   [(use (match_operand:XF 0 "register_operand" ""))
17411    (use (match_operand:XF 1 "register_operand" ""))]
17412   "TARGET_USE_FANCY_MATH_387
17413    && flag_unsafe_math_optimizations"
17414 {
17415   if (optimize_insn_for_size_p ())
17416     FAIL;
17417
17418   ix86_emit_i387_log1p (operands[0], operands[1]);
17419   DONE;
17420 })
17421
17422 (define_expand "log1p<mode>2"
17423   [(use (match_operand:MODEF 0 "register_operand" ""))
17424    (use (match_operand:MODEF 1 "register_operand" ""))]
17425   "TARGET_USE_FANCY_MATH_387
17426    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17427        || TARGET_MIX_SSE_I387)
17428    && flag_unsafe_math_optimizations"
17429 {
17430   rtx op0;
17431
17432   if (optimize_insn_for_size_p ())
17433     FAIL;
17434
17435   op0 = gen_reg_rtx (XFmode);
17436
17437   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17438
17439   ix86_emit_i387_log1p (op0, operands[1]);
17440   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17441   DONE;
17442 })
17443
17444 (define_insn "fxtractxf3_i387"
17445   [(set (match_operand:XF 0 "register_operand" "=f")
17446         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17447                    UNSPEC_XTRACT_FRACT))
17448    (set (match_operand:XF 1 "register_operand" "=u")
17449         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17450   "TARGET_USE_FANCY_MATH_387
17451    && flag_unsafe_math_optimizations"
17452   "fxtract"
17453   [(set_attr "type" "fpspc")
17454    (set_attr "mode" "XF")])
17455
17456 (define_insn "fxtract_extend<mode>xf3_i387"
17457   [(set (match_operand:XF 0 "register_operand" "=f")
17458         (unspec:XF [(float_extend:XF
17459                       (match_operand:MODEF 2 "register_operand" "0"))]
17460                    UNSPEC_XTRACT_FRACT))
17461    (set (match_operand:XF 1 "register_operand" "=u")
17462         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17463   "TARGET_USE_FANCY_MATH_387
17464    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17465        || TARGET_MIX_SSE_I387)
17466    && flag_unsafe_math_optimizations"
17467   "fxtract"
17468   [(set_attr "type" "fpspc")
17469    (set_attr "mode" "XF")])
17470
17471 (define_expand "logbxf2"
17472   [(parallel [(set (match_dup 2)
17473                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17474                               UNSPEC_XTRACT_FRACT))
17475               (set (match_operand:XF 0 "register_operand" "")
17476                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17477   "TARGET_USE_FANCY_MATH_387
17478    && flag_unsafe_math_optimizations"
17479 {
17480   operands[2] = gen_reg_rtx (XFmode);
17481 })
17482
17483 (define_expand "logb<mode>2"
17484   [(use (match_operand:MODEF 0 "register_operand" ""))
17485    (use (match_operand:MODEF 1 "register_operand" ""))]
17486   "TARGET_USE_FANCY_MATH_387
17487    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17488        || TARGET_MIX_SSE_I387)
17489    && flag_unsafe_math_optimizations"
17490 {
17491   rtx op0 = gen_reg_rtx (XFmode);
17492   rtx op1 = gen_reg_rtx (XFmode);
17493
17494   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17495   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17496   DONE;
17497 })
17498
17499 (define_expand "ilogbxf2"
17500   [(use (match_operand:SI 0 "register_operand" ""))
17501    (use (match_operand:XF 1 "register_operand" ""))]
17502   "TARGET_USE_FANCY_MATH_387
17503    && flag_unsafe_math_optimizations"
17504 {
17505   rtx op0, op1;
17506
17507   if (optimize_insn_for_size_p ())
17508     FAIL;
17509
17510   op0 = gen_reg_rtx (XFmode);
17511   op1 = gen_reg_rtx (XFmode);
17512
17513   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17514   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17515   DONE;
17516 })
17517
17518 (define_expand "ilogb<mode>2"
17519   [(use (match_operand:SI 0 "register_operand" ""))
17520    (use (match_operand:MODEF 1 "register_operand" ""))]
17521   "TARGET_USE_FANCY_MATH_387
17522    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17523        || TARGET_MIX_SSE_I387)
17524    && flag_unsafe_math_optimizations"
17525 {
17526   rtx op0, op1;
17527
17528   if (optimize_insn_for_size_p ())
17529     FAIL;
17530
17531   op0 = gen_reg_rtx (XFmode);
17532   op1 = gen_reg_rtx (XFmode);
17533
17534   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17535   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17536   DONE;
17537 })
17538
17539 (define_insn "*f2xm1xf2_i387"
17540   [(set (match_operand:XF 0 "register_operand" "=f")
17541         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17542                    UNSPEC_F2XM1))]
17543   "TARGET_USE_FANCY_MATH_387
17544    && flag_unsafe_math_optimizations"
17545   "f2xm1"
17546   [(set_attr "type" "fpspc")
17547    (set_attr "mode" "XF")])
17548
17549 (define_insn "*fscalexf4_i387"
17550   [(set (match_operand:XF 0 "register_operand" "=f")
17551         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17552                     (match_operand:XF 3 "register_operand" "1")]
17553                    UNSPEC_FSCALE_FRACT))
17554    (set (match_operand:XF 1 "register_operand" "=u")
17555         (unspec:XF [(match_dup 2) (match_dup 3)]
17556                    UNSPEC_FSCALE_EXP))]
17557   "TARGET_USE_FANCY_MATH_387
17558    && flag_unsafe_math_optimizations"
17559   "fscale"
17560   [(set_attr "type" "fpspc")
17561    (set_attr "mode" "XF")])
17562
17563 (define_expand "expNcorexf3"
17564   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17565                                (match_operand:XF 2 "register_operand" "")))
17566    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17567    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17568    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17569    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17570    (parallel [(set (match_operand:XF 0 "register_operand" "")
17571                    (unspec:XF [(match_dup 8) (match_dup 4)]
17572                               UNSPEC_FSCALE_FRACT))
17573               (set (match_dup 9)
17574                    (unspec:XF [(match_dup 8) (match_dup 4)]
17575                               UNSPEC_FSCALE_EXP))])]
17576   "TARGET_USE_FANCY_MATH_387
17577    && flag_unsafe_math_optimizations"
17578 {
17579   int i;
17580
17581   if (optimize_insn_for_size_p ())
17582     FAIL;
17583
17584   for (i = 3; i < 10; i++)
17585     operands[i] = gen_reg_rtx (XFmode);
17586
17587   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17588 })
17589
17590 (define_expand "expxf2"
17591   [(use (match_operand:XF 0 "register_operand" ""))
17592    (use (match_operand:XF 1 "register_operand" ""))]
17593   "TARGET_USE_FANCY_MATH_387
17594    && flag_unsafe_math_optimizations"
17595 {
17596   rtx op2;
17597
17598   if (optimize_insn_for_size_p ())
17599     FAIL;
17600
17601   op2 = gen_reg_rtx (XFmode);
17602   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17603
17604   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17605   DONE;
17606 })
17607
17608 (define_expand "exp<mode>2"
17609   [(use (match_operand:MODEF 0 "register_operand" ""))
17610    (use (match_operand:MODEF 1 "general_operand" ""))]
17611  "TARGET_USE_FANCY_MATH_387
17612    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17613        || TARGET_MIX_SSE_I387)
17614    && flag_unsafe_math_optimizations"
17615 {
17616   rtx op0, op1;
17617
17618   if (optimize_insn_for_size_p ())
17619     FAIL;
17620
17621   op0 = gen_reg_rtx (XFmode);
17622   op1 = gen_reg_rtx (XFmode);
17623
17624   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17625   emit_insn (gen_expxf2 (op0, op1));
17626   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17627   DONE;
17628 })
17629
17630 (define_expand "exp10xf2"
17631   [(use (match_operand:XF 0 "register_operand" ""))
17632    (use (match_operand:XF 1 "register_operand" ""))]
17633   "TARGET_USE_FANCY_MATH_387
17634    && flag_unsafe_math_optimizations"
17635 {
17636   rtx op2;
17637
17638   if (optimize_insn_for_size_p ())
17639     FAIL;
17640
17641   op2 = gen_reg_rtx (XFmode);
17642   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17643
17644   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17645   DONE;
17646 })
17647
17648 (define_expand "exp10<mode>2"
17649   [(use (match_operand:MODEF 0 "register_operand" ""))
17650    (use (match_operand:MODEF 1 "general_operand" ""))]
17651  "TARGET_USE_FANCY_MATH_387
17652    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17653        || TARGET_MIX_SSE_I387)
17654    && flag_unsafe_math_optimizations"
17655 {
17656   rtx op0, op1;
17657
17658   if (optimize_insn_for_size_p ())
17659     FAIL;
17660
17661   op0 = gen_reg_rtx (XFmode);
17662   op1 = gen_reg_rtx (XFmode);
17663
17664   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17665   emit_insn (gen_exp10xf2 (op0, op1));
17666   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17667   DONE;
17668 })
17669
17670 (define_expand "exp2xf2"
17671   [(use (match_operand:XF 0 "register_operand" ""))
17672    (use (match_operand:XF 1 "register_operand" ""))]
17673   "TARGET_USE_FANCY_MATH_387
17674    && flag_unsafe_math_optimizations"
17675 {
17676   rtx op2;
17677
17678   if (optimize_insn_for_size_p ())
17679     FAIL;
17680
17681   op2 = gen_reg_rtx (XFmode);
17682   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17683
17684   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17685   DONE;
17686 })
17687
17688 (define_expand "exp2<mode>2"
17689   [(use (match_operand:MODEF 0 "register_operand" ""))
17690    (use (match_operand:MODEF 1 "general_operand" ""))]
17691  "TARGET_USE_FANCY_MATH_387
17692    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17693        || TARGET_MIX_SSE_I387)
17694    && flag_unsafe_math_optimizations"
17695 {
17696   rtx op0, op1;
17697
17698   if (optimize_insn_for_size_p ())
17699     FAIL;
17700
17701   op0 = gen_reg_rtx (XFmode);
17702   op1 = gen_reg_rtx (XFmode);
17703
17704   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17705   emit_insn (gen_exp2xf2 (op0, op1));
17706   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17707   DONE;
17708 })
17709
17710 (define_expand "expm1xf2"
17711   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17712                                (match_dup 2)))
17713    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17714    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17715    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17716    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17717    (parallel [(set (match_dup 7)
17718                    (unspec:XF [(match_dup 6) (match_dup 4)]
17719                               UNSPEC_FSCALE_FRACT))
17720               (set (match_dup 8)
17721                    (unspec:XF [(match_dup 6) (match_dup 4)]
17722                               UNSPEC_FSCALE_EXP))])
17723    (parallel [(set (match_dup 10)
17724                    (unspec:XF [(match_dup 9) (match_dup 8)]
17725                               UNSPEC_FSCALE_FRACT))
17726               (set (match_dup 11)
17727                    (unspec:XF [(match_dup 9) (match_dup 8)]
17728                               UNSPEC_FSCALE_EXP))])
17729    (set (match_dup 12) (minus:XF (match_dup 10)
17730                                  (float_extend:XF (match_dup 13))))
17731    (set (match_operand:XF 0 "register_operand" "")
17732         (plus:XF (match_dup 12) (match_dup 7)))]
17733   "TARGET_USE_FANCY_MATH_387
17734    && flag_unsafe_math_optimizations"
17735 {
17736   int i;
17737
17738   if (optimize_insn_for_size_p ())
17739     FAIL;
17740
17741   for (i = 2; i < 13; i++)
17742     operands[i] = gen_reg_rtx (XFmode);
17743
17744   operands[13]
17745     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17746
17747   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17748 })
17749
17750 (define_expand "expm1<mode>2"
17751   [(use (match_operand:MODEF 0 "register_operand" ""))
17752    (use (match_operand:MODEF 1 "general_operand" ""))]
17753  "TARGET_USE_FANCY_MATH_387
17754    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17755        || TARGET_MIX_SSE_I387)
17756    && flag_unsafe_math_optimizations"
17757 {
17758   rtx op0, op1;
17759
17760   if (optimize_insn_for_size_p ())
17761     FAIL;
17762
17763   op0 = gen_reg_rtx (XFmode);
17764   op1 = gen_reg_rtx (XFmode);
17765
17766   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17767   emit_insn (gen_expm1xf2 (op0, op1));
17768   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17769   DONE;
17770 })
17771
17772 (define_expand "ldexpxf3"
17773   [(set (match_dup 3)
17774         (float:XF (match_operand:SI 2 "register_operand" "")))
17775    (parallel [(set (match_operand:XF 0 " register_operand" "")
17776                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17777                                (match_dup 3)]
17778                               UNSPEC_FSCALE_FRACT))
17779               (set (match_dup 4)
17780                    (unspec:XF [(match_dup 1) (match_dup 3)]
17781                               UNSPEC_FSCALE_EXP))])]
17782   "TARGET_USE_FANCY_MATH_387
17783    && flag_unsafe_math_optimizations"
17784 {
17785   if (optimize_insn_for_size_p ())
17786     FAIL;
17787
17788   operands[3] = gen_reg_rtx (XFmode);
17789   operands[4] = gen_reg_rtx (XFmode);
17790 })
17791
17792 (define_expand "ldexp<mode>3"
17793   [(use (match_operand:MODEF 0 "register_operand" ""))
17794    (use (match_operand:MODEF 1 "general_operand" ""))
17795    (use (match_operand:SI 2 "register_operand" ""))]
17796  "TARGET_USE_FANCY_MATH_387
17797    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17798        || TARGET_MIX_SSE_I387)
17799    && flag_unsafe_math_optimizations"
17800 {
17801   rtx op0, op1;
17802
17803   if (optimize_insn_for_size_p ())
17804     FAIL;
17805
17806   op0 = gen_reg_rtx (XFmode);
17807   op1 = gen_reg_rtx (XFmode);
17808
17809   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17810   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17811   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17812   DONE;
17813 })
17814
17815 (define_expand "scalbxf3"
17816   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17817                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17818                                (match_operand:XF 2 "register_operand" "")]
17819                               UNSPEC_FSCALE_FRACT))
17820               (set (match_dup 3)
17821                    (unspec:XF [(match_dup 1) (match_dup 2)]
17822                               UNSPEC_FSCALE_EXP))])]
17823   "TARGET_USE_FANCY_MATH_387
17824    && flag_unsafe_math_optimizations"
17825 {
17826   if (optimize_insn_for_size_p ())
17827     FAIL;
17828
17829   operands[3] = gen_reg_rtx (XFmode);
17830 })
17831
17832 (define_expand "scalb<mode>3"
17833   [(use (match_operand:MODEF 0 "register_operand" ""))
17834    (use (match_operand:MODEF 1 "general_operand" ""))
17835    (use (match_operand:MODEF 2 "register_operand" ""))]
17836  "TARGET_USE_FANCY_MATH_387
17837    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17838        || TARGET_MIX_SSE_I387)
17839    && flag_unsafe_math_optimizations"
17840 {
17841   rtx op0, op1, op2;
17842
17843   if (optimize_insn_for_size_p ())
17844     FAIL;
17845
17846   op0 = gen_reg_rtx (XFmode);
17847   op1 = gen_reg_rtx (XFmode);
17848   op2 = gen_reg_rtx (XFmode);
17849
17850   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17851   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17852   emit_insn (gen_scalbxf3 (op0, op1, op2));
17853   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17854   DONE;
17855 })
17856 \f
17857
17858 (define_insn "sse4_1_round<mode>2"
17859   [(set (match_operand:MODEF 0 "register_operand" "=x")
17860         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17861                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17862                       UNSPEC_ROUND))]
17863   "TARGET_ROUND"
17864   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17865   [(set_attr "type" "ssecvt")
17866    (set_attr "prefix_extra" "1")
17867    (set_attr "prefix" "maybe_vex")
17868    (set_attr "mode" "<MODE>")])
17869
17870 (define_insn "rintxf2"
17871   [(set (match_operand:XF 0 "register_operand" "=f")
17872         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17873                    UNSPEC_FRNDINT))]
17874   "TARGET_USE_FANCY_MATH_387
17875    && flag_unsafe_math_optimizations"
17876   "frndint"
17877   [(set_attr "type" "fpspc")
17878    (set_attr "mode" "XF")])
17879
17880 (define_expand "rint<mode>2"
17881   [(use (match_operand:MODEF 0 "register_operand" ""))
17882    (use (match_operand:MODEF 1 "register_operand" ""))]
17883   "(TARGET_USE_FANCY_MATH_387
17884     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17885         || TARGET_MIX_SSE_I387)
17886     && flag_unsafe_math_optimizations)
17887    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17888        && !flag_trapping_math)"
17889 {
17890   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17891       && !flag_trapping_math)
17892     {
17893       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17894         FAIL;
17895       if (TARGET_ROUND)
17896         emit_insn (gen_sse4_1_round<mode>2
17897                    (operands[0], operands[1], GEN_INT (0x04)));
17898       else
17899         ix86_expand_rint (operand0, operand1);
17900     }
17901   else
17902     {
17903       rtx op0 = gen_reg_rtx (XFmode);
17904       rtx op1 = gen_reg_rtx (XFmode);
17905
17906       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17907       emit_insn (gen_rintxf2 (op0, op1));
17908
17909       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17910     }
17911   DONE;
17912 })
17913
17914 (define_expand "round<mode>2"
17915   [(match_operand:MODEF 0 "register_operand" "")
17916    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17917   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17918    && !flag_trapping_math && !flag_rounding_math"
17919 {
17920   if (optimize_insn_for_size_p ())
17921     FAIL;
17922   if (TARGET_64BIT || (<MODE>mode != DFmode))
17923     ix86_expand_round (operand0, operand1);
17924   else
17925     ix86_expand_rounddf_32 (operand0, operand1);
17926   DONE;
17927 })
17928
17929 (define_insn_and_split "*fistdi2_1"
17930   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17931         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17932                    UNSPEC_FIST))]
17933   "TARGET_USE_FANCY_MATH_387
17934    && !(reload_completed || reload_in_progress)"
17935   "#"
17936   "&& 1"
17937   [(const_int 0)]
17938 {
17939   if (memory_operand (operands[0], VOIDmode))
17940     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17941   else
17942     {
17943       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17944       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17945                                          operands[2]));
17946     }
17947   DONE;
17948 }
17949   [(set_attr "type" "fpspc")
17950    (set_attr "mode" "DI")])
17951
17952 (define_insn "fistdi2"
17953   [(set (match_operand:DI 0 "memory_operand" "=m")
17954         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17955                    UNSPEC_FIST))
17956    (clobber (match_scratch:XF 2 "=&1f"))]
17957   "TARGET_USE_FANCY_MATH_387"
17958   "* return output_fix_trunc (insn, operands, 0);"
17959   [(set_attr "type" "fpspc")
17960    (set_attr "mode" "DI")])
17961
17962 (define_insn "fistdi2_with_temp"
17963   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17964         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17965                    UNSPEC_FIST))
17966    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17967    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17968   "TARGET_USE_FANCY_MATH_387"
17969   "#"
17970   [(set_attr "type" "fpspc")
17971    (set_attr "mode" "DI")])
17972
17973 (define_split
17974   [(set (match_operand:DI 0 "register_operand" "")
17975         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17976                    UNSPEC_FIST))
17977    (clobber (match_operand:DI 2 "memory_operand" ""))
17978    (clobber (match_scratch 3 ""))]
17979   "reload_completed"
17980   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17981               (clobber (match_dup 3))])
17982    (set (match_dup 0) (match_dup 2))]
17983   "")
17984
17985 (define_split
17986   [(set (match_operand:DI 0 "memory_operand" "")
17987         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17988                    UNSPEC_FIST))
17989    (clobber (match_operand:DI 2 "memory_operand" ""))
17990    (clobber (match_scratch 3 ""))]
17991   "reload_completed"
17992   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17993               (clobber (match_dup 3))])]
17994   "")
17995
17996 (define_insn_and_split "*fist<mode>2_1"
17997   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17998         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17999                            UNSPEC_FIST))]
18000   "TARGET_USE_FANCY_MATH_387
18001    && !(reload_completed || reload_in_progress)"
18002   "#"
18003   "&& 1"
18004   [(const_int 0)]
18005 {
18006   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18007   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18008                                         operands[2]));
18009   DONE;
18010 }
18011   [(set_attr "type" "fpspc")
18012    (set_attr "mode" "<MODE>")])
18013
18014 (define_insn "fist<mode>2"
18015   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18016         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18017                            UNSPEC_FIST))]
18018   "TARGET_USE_FANCY_MATH_387"
18019   "* return output_fix_trunc (insn, operands, 0);"
18020   [(set_attr "type" "fpspc")
18021    (set_attr "mode" "<MODE>")])
18022
18023 (define_insn "fist<mode>2_with_temp"
18024   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18025         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18026                            UNSPEC_FIST))
18027    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18028   "TARGET_USE_FANCY_MATH_387"
18029   "#"
18030   [(set_attr "type" "fpspc")
18031    (set_attr "mode" "<MODE>")])
18032
18033 (define_split
18034   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18035         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18036                            UNSPEC_FIST))
18037    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18038   "reload_completed"
18039   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18040    (set (match_dup 0) (match_dup 2))]
18041   "")
18042
18043 (define_split
18044   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18045         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18046                            UNSPEC_FIST))
18047    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18048   "reload_completed"
18049   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18050   "")
18051
18052 (define_expand "lrintxf<mode>2"
18053   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18054      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18055                       UNSPEC_FIST))]
18056   "TARGET_USE_FANCY_MATH_387"
18057   "")
18058
18059 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18060   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18061      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18062                         UNSPEC_FIX_NOTRUNC))]
18063   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18064    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18065   "")
18066
18067 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18068   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18069    (match_operand:MODEF 1 "register_operand" "")]
18070   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18071    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18072    && !flag_trapping_math && !flag_rounding_math"
18073 {
18074   if (optimize_insn_for_size_p ())
18075     FAIL;
18076   ix86_expand_lround (operand0, operand1);
18077   DONE;
18078 })
18079
18080 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18081 (define_insn_and_split "frndintxf2_floor"
18082   [(set (match_operand:XF 0 "register_operand" "")
18083         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18084          UNSPEC_FRNDINT_FLOOR))
18085    (clobber (reg:CC FLAGS_REG))]
18086   "TARGET_USE_FANCY_MATH_387
18087    && flag_unsafe_math_optimizations
18088    && !(reload_completed || reload_in_progress)"
18089   "#"
18090   "&& 1"
18091   [(const_int 0)]
18092 {
18093   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18094
18095   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18096   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18097
18098   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18099                                         operands[2], operands[3]));
18100   DONE;
18101 }
18102   [(set_attr "type" "frndint")
18103    (set_attr "i387_cw" "floor")
18104    (set_attr "mode" "XF")])
18105
18106 (define_insn "frndintxf2_floor_i387"
18107   [(set (match_operand:XF 0 "register_operand" "=f")
18108         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18109          UNSPEC_FRNDINT_FLOOR))
18110    (use (match_operand:HI 2 "memory_operand" "m"))
18111    (use (match_operand:HI 3 "memory_operand" "m"))]
18112   "TARGET_USE_FANCY_MATH_387
18113    && flag_unsafe_math_optimizations"
18114   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18115   [(set_attr "type" "frndint")
18116    (set_attr "i387_cw" "floor")
18117    (set_attr "mode" "XF")])
18118
18119 (define_expand "floorxf2"
18120   [(use (match_operand:XF 0 "register_operand" ""))
18121    (use (match_operand:XF 1 "register_operand" ""))]
18122   "TARGET_USE_FANCY_MATH_387
18123    && flag_unsafe_math_optimizations"
18124 {
18125   if (optimize_insn_for_size_p ())
18126     FAIL;
18127   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18128   DONE;
18129 })
18130
18131 (define_expand "floor<mode>2"
18132   [(use (match_operand:MODEF 0 "register_operand" ""))
18133    (use (match_operand:MODEF 1 "register_operand" ""))]
18134   "(TARGET_USE_FANCY_MATH_387
18135     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18136         || TARGET_MIX_SSE_I387)
18137     && flag_unsafe_math_optimizations)
18138    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18139        && !flag_trapping_math)"
18140 {
18141   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18142       && !flag_trapping_math
18143       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18144     {
18145       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18146         FAIL;
18147       if (TARGET_ROUND)
18148         emit_insn (gen_sse4_1_round<mode>2
18149                    (operands[0], operands[1], GEN_INT (0x01)));
18150       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18151         ix86_expand_floorceil (operand0, operand1, true);
18152       else
18153         ix86_expand_floorceildf_32 (operand0, operand1, true);
18154     }
18155   else
18156     {
18157       rtx op0, op1;
18158
18159       if (optimize_insn_for_size_p ())
18160         FAIL;
18161
18162       op0 = gen_reg_rtx (XFmode);
18163       op1 = gen_reg_rtx (XFmode);
18164       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18165       emit_insn (gen_frndintxf2_floor (op0, op1));
18166
18167       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18168     }
18169   DONE;
18170 })
18171
18172 (define_insn_and_split "*fist<mode>2_floor_1"
18173   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18174         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18175          UNSPEC_FIST_FLOOR))
18176    (clobber (reg:CC FLAGS_REG))]
18177   "TARGET_USE_FANCY_MATH_387
18178    && flag_unsafe_math_optimizations
18179    && !(reload_completed || reload_in_progress)"
18180   "#"
18181   "&& 1"
18182   [(const_int 0)]
18183 {
18184   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18185
18186   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18187   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18188   if (memory_operand (operands[0], VOIDmode))
18189     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18190                                       operands[2], operands[3]));
18191   else
18192     {
18193       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18194       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18195                                                   operands[2], operands[3],
18196                                                   operands[4]));
18197     }
18198   DONE;
18199 }
18200   [(set_attr "type" "fistp")
18201    (set_attr "i387_cw" "floor")
18202    (set_attr "mode" "<MODE>")])
18203
18204 (define_insn "fistdi2_floor"
18205   [(set (match_operand:DI 0 "memory_operand" "=m")
18206         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18207          UNSPEC_FIST_FLOOR))
18208    (use (match_operand:HI 2 "memory_operand" "m"))
18209    (use (match_operand:HI 3 "memory_operand" "m"))
18210    (clobber (match_scratch:XF 4 "=&1f"))]
18211   "TARGET_USE_FANCY_MATH_387
18212    && flag_unsafe_math_optimizations"
18213   "* return output_fix_trunc (insn, operands, 0);"
18214   [(set_attr "type" "fistp")
18215    (set_attr "i387_cw" "floor")
18216    (set_attr "mode" "DI")])
18217
18218 (define_insn "fistdi2_floor_with_temp"
18219   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18220         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18221          UNSPEC_FIST_FLOOR))
18222    (use (match_operand:HI 2 "memory_operand" "m,m"))
18223    (use (match_operand:HI 3 "memory_operand" "m,m"))
18224    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18225    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18226   "TARGET_USE_FANCY_MATH_387
18227    && flag_unsafe_math_optimizations"
18228   "#"
18229   [(set_attr "type" "fistp")
18230    (set_attr "i387_cw" "floor")
18231    (set_attr "mode" "DI")])
18232
18233 (define_split
18234   [(set (match_operand:DI 0 "register_operand" "")
18235         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18236          UNSPEC_FIST_FLOOR))
18237    (use (match_operand:HI 2 "memory_operand" ""))
18238    (use (match_operand:HI 3 "memory_operand" ""))
18239    (clobber (match_operand:DI 4 "memory_operand" ""))
18240    (clobber (match_scratch 5 ""))]
18241   "reload_completed"
18242   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18243               (use (match_dup 2))
18244               (use (match_dup 3))
18245               (clobber (match_dup 5))])
18246    (set (match_dup 0) (match_dup 4))]
18247   "")
18248
18249 (define_split
18250   [(set (match_operand:DI 0 "memory_operand" "")
18251         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18252          UNSPEC_FIST_FLOOR))
18253    (use (match_operand:HI 2 "memory_operand" ""))
18254    (use (match_operand:HI 3 "memory_operand" ""))
18255    (clobber (match_operand:DI 4 "memory_operand" ""))
18256    (clobber (match_scratch 5 ""))]
18257   "reload_completed"
18258   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18259               (use (match_dup 2))
18260               (use (match_dup 3))
18261               (clobber (match_dup 5))])]
18262   "")
18263
18264 (define_insn "fist<mode>2_floor"
18265   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18266         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18267          UNSPEC_FIST_FLOOR))
18268    (use (match_operand:HI 2 "memory_operand" "m"))
18269    (use (match_operand:HI 3 "memory_operand" "m"))]
18270   "TARGET_USE_FANCY_MATH_387
18271    && flag_unsafe_math_optimizations"
18272   "* return output_fix_trunc (insn, operands, 0);"
18273   [(set_attr "type" "fistp")
18274    (set_attr "i387_cw" "floor")
18275    (set_attr "mode" "<MODE>")])
18276
18277 (define_insn "fist<mode>2_floor_with_temp"
18278   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18279         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18280          UNSPEC_FIST_FLOOR))
18281    (use (match_operand:HI 2 "memory_operand" "m,m"))
18282    (use (match_operand:HI 3 "memory_operand" "m,m"))
18283    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18284   "TARGET_USE_FANCY_MATH_387
18285    && flag_unsafe_math_optimizations"
18286   "#"
18287   [(set_attr "type" "fistp")
18288    (set_attr "i387_cw" "floor")
18289    (set_attr "mode" "<MODE>")])
18290
18291 (define_split
18292   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18293         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18294          UNSPEC_FIST_FLOOR))
18295    (use (match_operand:HI 2 "memory_operand" ""))
18296    (use (match_operand:HI 3 "memory_operand" ""))
18297    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18298   "reload_completed"
18299   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18300                                   UNSPEC_FIST_FLOOR))
18301               (use (match_dup 2))
18302               (use (match_dup 3))])
18303    (set (match_dup 0) (match_dup 4))]
18304   "")
18305
18306 (define_split
18307   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18308         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18309          UNSPEC_FIST_FLOOR))
18310    (use (match_operand:HI 2 "memory_operand" ""))
18311    (use (match_operand:HI 3 "memory_operand" ""))
18312    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18313   "reload_completed"
18314   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18315                                   UNSPEC_FIST_FLOOR))
18316               (use (match_dup 2))
18317               (use (match_dup 3))])]
18318   "")
18319
18320 (define_expand "lfloorxf<mode>2"
18321   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18322                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18323                     UNSPEC_FIST_FLOOR))
18324               (clobber (reg:CC FLAGS_REG))])]
18325   "TARGET_USE_FANCY_MATH_387
18326    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18327    && flag_unsafe_math_optimizations"
18328   "")
18329
18330 (define_expand "lfloor<mode>di2"
18331   [(match_operand:DI 0 "nonimmediate_operand" "")
18332    (match_operand:MODEF 1 "register_operand" "")]
18333   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18334    && !flag_trapping_math"
18335 {
18336   if (optimize_insn_for_size_p ())
18337     FAIL;
18338   ix86_expand_lfloorceil (operand0, operand1, true);
18339   DONE;
18340 })
18341
18342 (define_expand "lfloor<mode>si2"
18343   [(match_operand:SI 0 "nonimmediate_operand" "")
18344    (match_operand:MODEF 1 "register_operand" "")]
18345   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18346    && !flag_trapping_math"
18347 {
18348   if (optimize_insn_for_size_p () && TARGET_64BIT)
18349     FAIL;
18350   ix86_expand_lfloorceil (operand0, operand1, true);
18351   DONE;
18352 })
18353
18354 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18355 (define_insn_and_split "frndintxf2_ceil"
18356   [(set (match_operand:XF 0 "register_operand" "")
18357         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18358          UNSPEC_FRNDINT_CEIL))
18359    (clobber (reg:CC FLAGS_REG))]
18360   "TARGET_USE_FANCY_MATH_387
18361    && flag_unsafe_math_optimizations
18362    && !(reload_completed || reload_in_progress)"
18363   "#"
18364   "&& 1"
18365   [(const_int 0)]
18366 {
18367   ix86_optimize_mode_switching[I387_CEIL] = 1;
18368
18369   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18370   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18371
18372   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18373                                        operands[2], operands[3]));
18374   DONE;
18375 }
18376   [(set_attr "type" "frndint")
18377    (set_attr "i387_cw" "ceil")
18378    (set_attr "mode" "XF")])
18379
18380 (define_insn "frndintxf2_ceil_i387"
18381   [(set (match_operand:XF 0 "register_operand" "=f")
18382         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18383          UNSPEC_FRNDINT_CEIL))
18384    (use (match_operand:HI 2 "memory_operand" "m"))
18385    (use (match_operand:HI 3 "memory_operand" "m"))]
18386   "TARGET_USE_FANCY_MATH_387
18387    && flag_unsafe_math_optimizations"
18388   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18389   [(set_attr "type" "frndint")
18390    (set_attr "i387_cw" "ceil")
18391    (set_attr "mode" "XF")])
18392
18393 (define_expand "ceilxf2"
18394   [(use (match_operand:XF 0 "register_operand" ""))
18395    (use (match_operand:XF 1 "register_operand" ""))]
18396   "TARGET_USE_FANCY_MATH_387
18397    && flag_unsafe_math_optimizations"
18398 {
18399   if (optimize_insn_for_size_p ())
18400     FAIL;
18401   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18402   DONE;
18403 })
18404
18405 (define_expand "ceil<mode>2"
18406   [(use (match_operand:MODEF 0 "register_operand" ""))
18407    (use (match_operand:MODEF 1 "register_operand" ""))]
18408   "(TARGET_USE_FANCY_MATH_387
18409     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18410         || TARGET_MIX_SSE_I387)
18411     && flag_unsafe_math_optimizations)
18412    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18413        && !flag_trapping_math)"
18414 {
18415   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18416       && !flag_trapping_math
18417       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18418     {
18419       if (TARGET_ROUND)
18420         emit_insn (gen_sse4_1_round<mode>2
18421                    (operands[0], operands[1], GEN_INT (0x02)));
18422       else if (optimize_insn_for_size_p ())
18423         FAIL;
18424       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18425         ix86_expand_floorceil (operand0, operand1, false);
18426       else
18427         ix86_expand_floorceildf_32 (operand0, operand1, false);
18428     }
18429   else
18430     {
18431       rtx op0, op1;
18432
18433       if (optimize_insn_for_size_p ())
18434         FAIL;
18435
18436       op0 = gen_reg_rtx (XFmode);
18437       op1 = gen_reg_rtx (XFmode);
18438       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18439       emit_insn (gen_frndintxf2_ceil (op0, op1));
18440
18441       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18442     }
18443   DONE;
18444 })
18445
18446 (define_insn_and_split "*fist<mode>2_ceil_1"
18447   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18448         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18449          UNSPEC_FIST_CEIL))
18450    (clobber (reg:CC FLAGS_REG))]
18451   "TARGET_USE_FANCY_MATH_387
18452    && flag_unsafe_math_optimizations
18453    && !(reload_completed || reload_in_progress)"
18454   "#"
18455   "&& 1"
18456   [(const_int 0)]
18457 {
18458   ix86_optimize_mode_switching[I387_CEIL] = 1;
18459
18460   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18461   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18462   if (memory_operand (operands[0], VOIDmode))
18463     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18464                                      operands[2], operands[3]));
18465   else
18466     {
18467       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18468       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18469                                                  operands[2], operands[3],
18470                                                  operands[4]));
18471     }
18472   DONE;
18473 }
18474   [(set_attr "type" "fistp")
18475    (set_attr "i387_cw" "ceil")
18476    (set_attr "mode" "<MODE>")])
18477
18478 (define_insn "fistdi2_ceil"
18479   [(set (match_operand:DI 0 "memory_operand" "=m")
18480         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18481          UNSPEC_FIST_CEIL))
18482    (use (match_operand:HI 2 "memory_operand" "m"))
18483    (use (match_operand:HI 3 "memory_operand" "m"))
18484    (clobber (match_scratch:XF 4 "=&1f"))]
18485   "TARGET_USE_FANCY_MATH_387
18486    && flag_unsafe_math_optimizations"
18487   "* return output_fix_trunc (insn, operands, 0);"
18488   [(set_attr "type" "fistp")
18489    (set_attr "i387_cw" "ceil")
18490    (set_attr "mode" "DI")])
18491
18492 (define_insn "fistdi2_ceil_with_temp"
18493   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18494         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18495          UNSPEC_FIST_CEIL))
18496    (use (match_operand:HI 2 "memory_operand" "m,m"))
18497    (use (match_operand:HI 3 "memory_operand" "m,m"))
18498    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18499    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18500   "TARGET_USE_FANCY_MATH_387
18501    && flag_unsafe_math_optimizations"
18502   "#"
18503   [(set_attr "type" "fistp")
18504    (set_attr "i387_cw" "ceil")
18505    (set_attr "mode" "DI")])
18506
18507 (define_split
18508   [(set (match_operand:DI 0 "register_operand" "")
18509         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18510          UNSPEC_FIST_CEIL))
18511    (use (match_operand:HI 2 "memory_operand" ""))
18512    (use (match_operand:HI 3 "memory_operand" ""))
18513    (clobber (match_operand:DI 4 "memory_operand" ""))
18514    (clobber (match_scratch 5 ""))]
18515   "reload_completed"
18516   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18517               (use (match_dup 2))
18518               (use (match_dup 3))
18519               (clobber (match_dup 5))])
18520    (set (match_dup 0) (match_dup 4))]
18521   "")
18522
18523 (define_split
18524   [(set (match_operand:DI 0 "memory_operand" "")
18525         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18526          UNSPEC_FIST_CEIL))
18527    (use (match_operand:HI 2 "memory_operand" ""))
18528    (use (match_operand:HI 3 "memory_operand" ""))
18529    (clobber (match_operand:DI 4 "memory_operand" ""))
18530    (clobber (match_scratch 5 ""))]
18531   "reload_completed"
18532   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18533               (use (match_dup 2))
18534               (use (match_dup 3))
18535               (clobber (match_dup 5))])]
18536   "")
18537
18538 (define_insn "fist<mode>2_ceil"
18539   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18540         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18541          UNSPEC_FIST_CEIL))
18542    (use (match_operand:HI 2 "memory_operand" "m"))
18543    (use (match_operand:HI 3 "memory_operand" "m"))]
18544   "TARGET_USE_FANCY_MATH_387
18545    && flag_unsafe_math_optimizations"
18546   "* return output_fix_trunc (insn, operands, 0);"
18547   [(set_attr "type" "fistp")
18548    (set_attr "i387_cw" "ceil")
18549    (set_attr "mode" "<MODE>")])
18550
18551 (define_insn "fist<mode>2_ceil_with_temp"
18552   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18553         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18554          UNSPEC_FIST_CEIL))
18555    (use (match_operand:HI 2 "memory_operand" "m,m"))
18556    (use (match_operand:HI 3 "memory_operand" "m,m"))
18557    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18558   "TARGET_USE_FANCY_MATH_387
18559    && flag_unsafe_math_optimizations"
18560   "#"
18561   [(set_attr "type" "fistp")
18562    (set_attr "i387_cw" "ceil")
18563    (set_attr "mode" "<MODE>")])
18564
18565 (define_split
18566   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18567         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18568          UNSPEC_FIST_CEIL))
18569    (use (match_operand:HI 2 "memory_operand" ""))
18570    (use (match_operand:HI 3 "memory_operand" ""))
18571    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18572   "reload_completed"
18573   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18574                                   UNSPEC_FIST_CEIL))
18575               (use (match_dup 2))
18576               (use (match_dup 3))])
18577    (set (match_dup 0) (match_dup 4))]
18578   "")
18579
18580 (define_split
18581   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18582         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18583          UNSPEC_FIST_CEIL))
18584    (use (match_operand:HI 2 "memory_operand" ""))
18585    (use (match_operand:HI 3 "memory_operand" ""))
18586    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18587   "reload_completed"
18588   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18589                                   UNSPEC_FIST_CEIL))
18590               (use (match_dup 2))
18591               (use (match_dup 3))])]
18592   "")
18593
18594 (define_expand "lceilxf<mode>2"
18595   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18596                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18597                     UNSPEC_FIST_CEIL))
18598               (clobber (reg:CC FLAGS_REG))])]
18599   "TARGET_USE_FANCY_MATH_387
18600    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18601    && flag_unsafe_math_optimizations"
18602   "")
18603
18604 (define_expand "lceil<mode>di2"
18605   [(match_operand:DI 0 "nonimmediate_operand" "")
18606    (match_operand:MODEF 1 "register_operand" "")]
18607   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18608    && !flag_trapping_math"
18609 {
18610   ix86_expand_lfloorceil (operand0, operand1, false);
18611   DONE;
18612 })
18613
18614 (define_expand "lceil<mode>si2"
18615   [(match_operand:SI 0 "nonimmediate_operand" "")
18616    (match_operand:MODEF 1 "register_operand" "")]
18617   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18618    && !flag_trapping_math"
18619 {
18620   ix86_expand_lfloorceil (operand0, operand1, false);
18621   DONE;
18622 })
18623
18624 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18625 (define_insn_and_split "frndintxf2_trunc"
18626   [(set (match_operand:XF 0 "register_operand" "")
18627         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18628          UNSPEC_FRNDINT_TRUNC))
18629    (clobber (reg:CC FLAGS_REG))]
18630   "TARGET_USE_FANCY_MATH_387
18631    && flag_unsafe_math_optimizations
18632    && !(reload_completed || reload_in_progress)"
18633   "#"
18634   "&& 1"
18635   [(const_int 0)]
18636 {
18637   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18638
18639   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18640   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18641
18642   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18643                                         operands[2], operands[3]));
18644   DONE;
18645 }
18646   [(set_attr "type" "frndint")
18647    (set_attr "i387_cw" "trunc")
18648    (set_attr "mode" "XF")])
18649
18650 (define_insn "frndintxf2_trunc_i387"
18651   [(set (match_operand:XF 0 "register_operand" "=f")
18652         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18653          UNSPEC_FRNDINT_TRUNC))
18654    (use (match_operand:HI 2 "memory_operand" "m"))
18655    (use (match_operand:HI 3 "memory_operand" "m"))]
18656   "TARGET_USE_FANCY_MATH_387
18657    && flag_unsafe_math_optimizations"
18658   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18659   [(set_attr "type" "frndint")
18660    (set_attr "i387_cw" "trunc")
18661    (set_attr "mode" "XF")])
18662
18663 (define_expand "btruncxf2"
18664   [(use (match_operand:XF 0 "register_operand" ""))
18665    (use (match_operand:XF 1 "register_operand" ""))]
18666   "TARGET_USE_FANCY_MATH_387
18667    && flag_unsafe_math_optimizations"
18668 {
18669   if (optimize_insn_for_size_p ())
18670     FAIL;
18671   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18672   DONE;
18673 })
18674
18675 (define_expand "btrunc<mode>2"
18676   [(use (match_operand:MODEF 0 "register_operand" ""))
18677    (use (match_operand:MODEF 1 "register_operand" ""))]
18678   "(TARGET_USE_FANCY_MATH_387
18679     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18680         || TARGET_MIX_SSE_I387)
18681     && flag_unsafe_math_optimizations)
18682    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18683        && !flag_trapping_math)"
18684 {
18685   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18686       && !flag_trapping_math
18687       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18688     {
18689       if (TARGET_ROUND)
18690         emit_insn (gen_sse4_1_round<mode>2
18691                    (operands[0], operands[1], GEN_INT (0x03)));
18692       else if (optimize_insn_for_size_p ())
18693         FAIL;
18694       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18695         ix86_expand_trunc (operand0, operand1);
18696       else
18697         ix86_expand_truncdf_32 (operand0, operand1);
18698     }
18699   else
18700     {
18701       rtx op0, op1;
18702
18703       if (optimize_insn_for_size_p ())
18704         FAIL;
18705
18706       op0 = gen_reg_rtx (XFmode);
18707       op1 = gen_reg_rtx (XFmode);
18708       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18709       emit_insn (gen_frndintxf2_trunc (op0, op1));
18710
18711       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18712     }
18713   DONE;
18714 })
18715
18716 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18717 (define_insn_and_split "frndintxf2_mask_pm"
18718   [(set (match_operand:XF 0 "register_operand" "")
18719         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18720          UNSPEC_FRNDINT_MASK_PM))
18721    (clobber (reg:CC FLAGS_REG))]
18722   "TARGET_USE_FANCY_MATH_387
18723    && flag_unsafe_math_optimizations
18724    && !(reload_completed || reload_in_progress)"
18725   "#"
18726   "&& 1"
18727   [(const_int 0)]
18728 {
18729   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18730
18731   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18732   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18733
18734   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18735                                           operands[2], operands[3]));
18736   DONE;
18737 }
18738   [(set_attr "type" "frndint")
18739    (set_attr "i387_cw" "mask_pm")
18740    (set_attr "mode" "XF")])
18741
18742 (define_insn "frndintxf2_mask_pm_i387"
18743   [(set (match_operand:XF 0 "register_operand" "=f")
18744         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18745          UNSPEC_FRNDINT_MASK_PM))
18746    (use (match_operand:HI 2 "memory_operand" "m"))
18747    (use (match_operand:HI 3 "memory_operand" "m"))]
18748   "TARGET_USE_FANCY_MATH_387
18749    && flag_unsafe_math_optimizations"
18750   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18751   [(set_attr "type" "frndint")
18752    (set_attr "i387_cw" "mask_pm")
18753    (set_attr "mode" "XF")])
18754
18755 (define_expand "nearbyintxf2"
18756   [(use (match_operand:XF 0 "register_operand" ""))
18757    (use (match_operand:XF 1 "register_operand" ""))]
18758   "TARGET_USE_FANCY_MATH_387
18759    && flag_unsafe_math_optimizations"
18760 {
18761   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18762
18763   DONE;
18764 })
18765
18766 (define_expand "nearbyint<mode>2"
18767   [(use (match_operand:MODEF 0 "register_operand" ""))
18768    (use (match_operand:MODEF 1 "register_operand" ""))]
18769   "TARGET_USE_FANCY_MATH_387
18770    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18771        || TARGET_MIX_SSE_I387)
18772    && flag_unsafe_math_optimizations"
18773 {
18774   rtx op0 = gen_reg_rtx (XFmode);
18775   rtx op1 = gen_reg_rtx (XFmode);
18776
18777   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18778   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18779
18780   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18781   DONE;
18782 })
18783
18784 (define_insn "fxam<mode>2_i387"
18785   [(set (match_operand:HI 0 "register_operand" "=a")
18786         (unspec:HI
18787           [(match_operand:X87MODEF 1 "register_operand" "f")]
18788           UNSPEC_FXAM))]
18789   "TARGET_USE_FANCY_MATH_387"
18790   "fxam\n\tfnstsw\t%0"
18791   [(set_attr "type" "multi")
18792    (set_attr "unit" "i387")
18793    (set_attr "mode" "<MODE>")])
18794
18795 (define_expand "isinf<mode>2"
18796   [(use (match_operand:SI 0 "register_operand" ""))
18797    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18798   "TARGET_USE_FANCY_MATH_387
18799    && TARGET_C99_FUNCTIONS
18800    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18801 {
18802   rtx mask = GEN_INT (0x45);
18803   rtx val = GEN_INT (0x05);
18804
18805   rtx cond;
18806
18807   rtx scratch = gen_reg_rtx (HImode);
18808   rtx res = gen_reg_rtx (QImode);
18809
18810   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18811   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18812   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18813   cond = gen_rtx_fmt_ee (EQ, QImode,
18814                          gen_rtx_REG (CCmode, FLAGS_REG),
18815                          const0_rtx);
18816   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18817   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18818   DONE;
18819 })
18820
18821 (define_expand "signbit<mode>2"
18822   [(use (match_operand:SI 0 "register_operand" ""))
18823    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18824   "TARGET_USE_FANCY_MATH_387
18825    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18826 {
18827   rtx mask = GEN_INT (0x0200);
18828
18829   rtx scratch = gen_reg_rtx (HImode);
18830
18831   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18832   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18833   DONE;
18834 })
18835 \f
18836 ;; Block operation instructions
18837
18838 (define_insn "cld"
18839   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18840   ""
18841   "cld"
18842   [(set_attr "length" "1")
18843    (set_attr "length_immediate" "0")
18844    (set_attr "modrm" "0")])
18845
18846 (define_expand "movmemsi"
18847   [(use (match_operand:BLK 0 "memory_operand" ""))
18848    (use (match_operand:BLK 1 "memory_operand" ""))
18849    (use (match_operand:SI 2 "nonmemory_operand" ""))
18850    (use (match_operand:SI 3 "const_int_operand" ""))
18851    (use (match_operand:SI 4 "const_int_operand" ""))
18852    (use (match_operand:SI 5 "const_int_operand" ""))]
18853   ""
18854 {
18855  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18856                          operands[4], operands[5]))
18857    DONE;
18858  else
18859    FAIL;
18860 })
18861
18862 (define_expand "movmemdi"
18863   [(use (match_operand:BLK 0 "memory_operand" ""))
18864    (use (match_operand:BLK 1 "memory_operand" ""))
18865    (use (match_operand:DI 2 "nonmemory_operand" ""))
18866    (use (match_operand:DI 3 "const_int_operand" ""))
18867    (use (match_operand:SI 4 "const_int_operand" ""))
18868    (use (match_operand:SI 5 "const_int_operand" ""))]
18869   "TARGET_64BIT"
18870 {
18871  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18872                          operands[4], operands[5]))
18873    DONE;
18874  else
18875    FAIL;
18876 })
18877
18878 ;; Most CPUs don't like single string operations
18879 ;; Handle this case here to simplify previous expander.
18880
18881 (define_expand "strmov"
18882   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18883    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18884    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18885               (clobber (reg:CC FLAGS_REG))])
18886    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18887               (clobber (reg:CC FLAGS_REG))])]
18888   ""
18889 {
18890   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18891
18892   /* If .md ever supports :P for Pmode, these can be directly
18893      in the pattern above.  */
18894   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18895   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18896
18897   /* Can't use this if the user has appropriated esi or edi.  */
18898   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18899       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18900     {
18901       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18902                                       operands[2], operands[3],
18903                                       operands[5], operands[6]));
18904       DONE;
18905     }
18906
18907   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18908 })
18909
18910 (define_expand "strmov_singleop"
18911   [(parallel [(set (match_operand 1 "memory_operand" "")
18912                    (match_operand 3 "memory_operand" ""))
18913               (set (match_operand 0 "register_operand" "")
18914                    (match_operand 4 "" ""))
18915               (set (match_operand 2 "register_operand" "")
18916                    (match_operand 5 "" ""))])]
18917   ""
18918   "ix86_current_function_needs_cld = 1;")
18919
18920 (define_insn "*strmovdi_rex_1"
18921   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18922         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18923    (set (match_operand:DI 0 "register_operand" "=D")
18924         (plus:DI (match_dup 2)
18925                  (const_int 8)))
18926    (set (match_operand:DI 1 "register_operand" "=S")
18927         (plus:DI (match_dup 3)
18928                  (const_int 8)))]
18929   "TARGET_64BIT"
18930   "movsq"
18931   [(set_attr "type" "str")
18932    (set_attr "mode" "DI")
18933    (set_attr "memory" "both")])
18934
18935 (define_insn "*strmovsi_1"
18936   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18937         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18938    (set (match_operand:SI 0 "register_operand" "=D")
18939         (plus:SI (match_dup 2)
18940                  (const_int 4)))
18941    (set (match_operand:SI 1 "register_operand" "=S")
18942         (plus:SI (match_dup 3)
18943                  (const_int 4)))]
18944   "!TARGET_64BIT"
18945   "movs{l|d}"
18946   [(set_attr "type" "str")
18947    (set_attr "mode" "SI")
18948    (set_attr "memory" "both")])
18949
18950 (define_insn "*strmovsi_rex_1"
18951   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18952         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18953    (set (match_operand:DI 0 "register_operand" "=D")
18954         (plus:DI (match_dup 2)
18955                  (const_int 4)))
18956    (set (match_operand:DI 1 "register_operand" "=S")
18957         (plus:DI (match_dup 3)
18958                  (const_int 4)))]
18959   "TARGET_64BIT"
18960   "movs{l|d}"
18961   [(set_attr "type" "str")
18962    (set_attr "mode" "SI")
18963    (set_attr "memory" "both")])
18964
18965 (define_insn "*strmovhi_1"
18966   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18967         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18968    (set (match_operand:SI 0 "register_operand" "=D")
18969         (plus:SI (match_dup 2)
18970                  (const_int 2)))
18971    (set (match_operand:SI 1 "register_operand" "=S")
18972         (plus:SI (match_dup 3)
18973                  (const_int 2)))]
18974   "!TARGET_64BIT"
18975   "movsw"
18976   [(set_attr "type" "str")
18977    (set_attr "memory" "both")
18978    (set_attr "mode" "HI")])
18979
18980 (define_insn "*strmovhi_rex_1"
18981   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18982         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18983    (set (match_operand:DI 0 "register_operand" "=D")
18984         (plus:DI (match_dup 2)
18985                  (const_int 2)))
18986    (set (match_operand:DI 1 "register_operand" "=S")
18987         (plus:DI (match_dup 3)
18988                  (const_int 2)))]
18989   "TARGET_64BIT"
18990   "movsw"
18991   [(set_attr "type" "str")
18992    (set_attr "memory" "both")
18993    (set_attr "mode" "HI")])
18994
18995 (define_insn "*strmovqi_1"
18996   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18997         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18998    (set (match_operand:SI 0 "register_operand" "=D")
18999         (plus:SI (match_dup 2)
19000                  (const_int 1)))
19001    (set (match_operand:SI 1 "register_operand" "=S")
19002         (plus:SI (match_dup 3)
19003                  (const_int 1)))]
19004   "!TARGET_64BIT"
19005   "movsb"
19006   [(set_attr "type" "str")
19007    (set_attr "memory" "both")
19008    (set_attr "mode" "QI")])
19009
19010 (define_insn "*strmovqi_rex_1"
19011   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19012         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19013    (set (match_operand:DI 0 "register_operand" "=D")
19014         (plus:DI (match_dup 2)
19015                  (const_int 1)))
19016    (set (match_operand:DI 1 "register_operand" "=S")
19017         (plus:DI (match_dup 3)
19018                  (const_int 1)))]
19019   "TARGET_64BIT"
19020   "movsb"
19021   [(set_attr "type" "str")
19022    (set_attr "memory" "both")
19023    (set_attr "mode" "QI")])
19024
19025 (define_expand "rep_mov"
19026   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19027               (set (match_operand 0 "register_operand" "")
19028                    (match_operand 5 "" ""))
19029               (set (match_operand 2 "register_operand" "")
19030                    (match_operand 6 "" ""))
19031               (set (match_operand 1 "memory_operand" "")
19032                    (match_operand 3 "memory_operand" ""))
19033               (use (match_dup 4))])]
19034   ""
19035   "ix86_current_function_needs_cld = 1;")
19036
19037 (define_insn "*rep_movdi_rex64"
19038   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19039    (set (match_operand:DI 0 "register_operand" "=D")
19040         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19041                             (const_int 3))
19042                  (match_operand:DI 3 "register_operand" "0")))
19043    (set (match_operand:DI 1 "register_operand" "=S")
19044         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19045                  (match_operand:DI 4 "register_operand" "1")))
19046    (set (mem:BLK (match_dup 3))
19047         (mem:BLK (match_dup 4)))
19048    (use (match_dup 5))]
19049   "TARGET_64BIT"
19050   "rep movsq"
19051   [(set_attr "type" "str")
19052    (set_attr "prefix_rep" "1")
19053    (set_attr "memory" "both")
19054    (set_attr "mode" "DI")])
19055
19056 (define_insn "*rep_movsi"
19057   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19058    (set (match_operand:SI 0 "register_operand" "=D")
19059         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19060                             (const_int 2))
19061                  (match_operand:SI 3 "register_operand" "0")))
19062    (set (match_operand:SI 1 "register_operand" "=S")
19063         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19064                  (match_operand:SI 4 "register_operand" "1")))
19065    (set (mem:BLK (match_dup 3))
19066         (mem:BLK (match_dup 4)))
19067    (use (match_dup 5))]
19068   "!TARGET_64BIT"
19069   "rep movs{l|d}"
19070   [(set_attr "type" "str")
19071    (set_attr "prefix_rep" "1")
19072    (set_attr "memory" "both")
19073    (set_attr "mode" "SI")])
19074
19075 (define_insn "*rep_movsi_rex64"
19076   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19077    (set (match_operand:DI 0 "register_operand" "=D")
19078         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19079                             (const_int 2))
19080                  (match_operand:DI 3 "register_operand" "0")))
19081    (set (match_operand:DI 1 "register_operand" "=S")
19082         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19083                  (match_operand:DI 4 "register_operand" "1")))
19084    (set (mem:BLK (match_dup 3))
19085         (mem:BLK (match_dup 4)))
19086    (use (match_dup 5))]
19087   "TARGET_64BIT"
19088   "rep movs{l|d}"
19089   [(set_attr "type" "str")
19090    (set_attr "prefix_rep" "1")
19091    (set_attr "memory" "both")
19092    (set_attr "mode" "SI")])
19093
19094 (define_insn "*rep_movqi"
19095   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19096    (set (match_operand:SI 0 "register_operand" "=D")
19097         (plus:SI (match_operand:SI 3 "register_operand" "0")
19098                  (match_operand:SI 5 "register_operand" "2")))
19099    (set (match_operand:SI 1 "register_operand" "=S")
19100         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19101    (set (mem:BLK (match_dup 3))
19102         (mem:BLK (match_dup 4)))
19103    (use (match_dup 5))]
19104   "!TARGET_64BIT"
19105   "rep movsb"
19106   [(set_attr "type" "str")
19107    (set_attr "prefix_rep" "1")
19108    (set_attr "memory" "both")
19109    (set_attr "mode" "SI")])
19110
19111 (define_insn "*rep_movqi_rex64"
19112   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19113    (set (match_operand:DI 0 "register_operand" "=D")
19114         (plus:DI (match_operand:DI 3 "register_operand" "0")
19115                  (match_operand:DI 5 "register_operand" "2")))
19116    (set (match_operand:DI 1 "register_operand" "=S")
19117         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19118    (set (mem:BLK (match_dup 3))
19119         (mem:BLK (match_dup 4)))
19120    (use (match_dup 5))]
19121   "TARGET_64BIT"
19122   "rep movsb"
19123   [(set_attr "type" "str")
19124    (set_attr "prefix_rep" "1")
19125    (set_attr "memory" "both")
19126    (set_attr "mode" "SI")])
19127
19128 (define_expand "setmemsi"
19129    [(use (match_operand:BLK 0 "memory_operand" ""))
19130     (use (match_operand:SI 1 "nonmemory_operand" ""))
19131     (use (match_operand 2 "const_int_operand" ""))
19132     (use (match_operand 3 "const_int_operand" ""))
19133     (use (match_operand:SI 4 "const_int_operand" ""))
19134     (use (match_operand:SI 5 "const_int_operand" ""))]
19135   ""
19136 {
19137  if (ix86_expand_setmem (operands[0], operands[1],
19138                          operands[2], operands[3],
19139                          operands[4], operands[5]))
19140    DONE;
19141  else
19142    FAIL;
19143 })
19144
19145 (define_expand "setmemdi"
19146    [(use (match_operand:BLK 0 "memory_operand" ""))
19147     (use (match_operand:DI 1 "nonmemory_operand" ""))
19148     (use (match_operand 2 "const_int_operand" ""))
19149     (use (match_operand 3 "const_int_operand" ""))
19150     (use (match_operand 4 "const_int_operand" ""))
19151     (use (match_operand 5 "const_int_operand" ""))]
19152   "TARGET_64BIT"
19153 {
19154  if (ix86_expand_setmem (operands[0], operands[1],
19155                          operands[2], operands[3],
19156                          operands[4], operands[5]))
19157    DONE;
19158  else
19159    FAIL;
19160 })
19161
19162 ;; Most CPUs don't like single string operations
19163 ;; Handle this case here to simplify previous expander.
19164
19165 (define_expand "strset"
19166   [(set (match_operand 1 "memory_operand" "")
19167         (match_operand 2 "register_operand" ""))
19168    (parallel [(set (match_operand 0 "register_operand" "")
19169                    (match_dup 3))
19170               (clobber (reg:CC FLAGS_REG))])]
19171   ""
19172 {
19173   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19174     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19175
19176   /* If .md ever supports :P for Pmode, this can be directly
19177      in the pattern above.  */
19178   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19179                               GEN_INT (GET_MODE_SIZE (GET_MODE
19180                                                       (operands[2]))));
19181   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19182     {
19183       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19184                                       operands[3]));
19185       DONE;
19186     }
19187 })
19188
19189 (define_expand "strset_singleop"
19190   [(parallel [(set (match_operand 1 "memory_operand" "")
19191                    (match_operand 2 "register_operand" ""))
19192               (set (match_operand 0 "register_operand" "")
19193                    (match_operand 3 "" ""))])]
19194   ""
19195   "ix86_current_function_needs_cld = 1;")
19196
19197 (define_insn "*strsetdi_rex_1"
19198   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19199         (match_operand:DI 2 "register_operand" "a"))
19200    (set (match_operand:DI 0 "register_operand" "=D")
19201         (plus:DI (match_dup 1)
19202                  (const_int 8)))]
19203   "TARGET_64BIT"
19204   "stosq"
19205   [(set_attr "type" "str")
19206    (set_attr "memory" "store")
19207    (set_attr "mode" "DI")])
19208
19209 (define_insn "*strsetsi_1"
19210   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19211         (match_operand:SI 2 "register_operand" "a"))
19212    (set (match_operand:SI 0 "register_operand" "=D")
19213         (plus:SI (match_dup 1)
19214                  (const_int 4)))]
19215   "!TARGET_64BIT"
19216   "stos{l|d}"
19217   [(set_attr "type" "str")
19218    (set_attr "memory" "store")
19219    (set_attr "mode" "SI")])
19220
19221 (define_insn "*strsetsi_rex_1"
19222   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19223         (match_operand:SI 2 "register_operand" "a"))
19224    (set (match_operand:DI 0 "register_operand" "=D")
19225         (plus:DI (match_dup 1)
19226                  (const_int 4)))]
19227   "TARGET_64BIT"
19228   "stos{l|d}"
19229   [(set_attr "type" "str")
19230    (set_attr "memory" "store")
19231    (set_attr "mode" "SI")])
19232
19233 (define_insn "*strsethi_1"
19234   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19235         (match_operand:HI 2 "register_operand" "a"))
19236    (set (match_operand:SI 0 "register_operand" "=D")
19237         (plus:SI (match_dup 1)
19238                  (const_int 2)))]
19239   "!TARGET_64BIT"
19240   "stosw"
19241   [(set_attr "type" "str")
19242    (set_attr "memory" "store")
19243    (set_attr "mode" "HI")])
19244
19245 (define_insn "*strsethi_rex_1"
19246   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19247         (match_operand:HI 2 "register_operand" "a"))
19248    (set (match_operand:DI 0 "register_operand" "=D")
19249         (plus:DI (match_dup 1)
19250                  (const_int 2)))]
19251   "TARGET_64BIT"
19252   "stosw"
19253   [(set_attr "type" "str")
19254    (set_attr "memory" "store")
19255    (set_attr "mode" "HI")])
19256
19257 (define_insn "*strsetqi_1"
19258   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19259         (match_operand:QI 2 "register_operand" "a"))
19260    (set (match_operand:SI 0 "register_operand" "=D")
19261         (plus:SI (match_dup 1)
19262                  (const_int 1)))]
19263   "!TARGET_64BIT"
19264   "stosb"
19265   [(set_attr "type" "str")
19266    (set_attr "memory" "store")
19267    (set_attr "mode" "QI")])
19268
19269 (define_insn "*strsetqi_rex_1"
19270   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19271         (match_operand:QI 2 "register_operand" "a"))
19272    (set (match_operand:DI 0 "register_operand" "=D")
19273         (plus:DI (match_dup 1)
19274                  (const_int 1)))]
19275   "TARGET_64BIT"
19276   "stosb"
19277   [(set_attr "type" "str")
19278    (set_attr "memory" "store")
19279    (set_attr "mode" "QI")])
19280
19281 (define_expand "rep_stos"
19282   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19283               (set (match_operand 0 "register_operand" "")
19284                    (match_operand 4 "" ""))
19285               (set (match_operand 2 "memory_operand" "") (const_int 0))
19286               (use (match_operand 3 "register_operand" ""))
19287               (use (match_dup 1))])]
19288   ""
19289   "ix86_current_function_needs_cld = 1;")
19290
19291 (define_insn "*rep_stosdi_rex64"
19292   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19293    (set (match_operand:DI 0 "register_operand" "=D")
19294         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19295                             (const_int 3))
19296                  (match_operand:DI 3 "register_operand" "0")))
19297    (set (mem:BLK (match_dup 3))
19298         (const_int 0))
19299    (use (match_operand:DI 2 "register_operand" "a"))
19300    (use (match_dup 4))]
19301   "TARGET_64BIT"
19302   "rep stosq"
19303   [(set_attr "type" "str")
19304    (set_attr "prefix_rep" "1")
19305    (set_attr "memory" "store")
19306    (set_attr "mode" "DI")])
19307
19308 (define_insn "*rep_stossi"
19309   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19310    (set (match_operand:SI 0 "register_operand" "=D")
19311         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19312                             (const_int 2))
19313                  (match_operand:SI 3 "register_operand" "0")))
19314    (set (mem:BLK (match_dup 3))
19315         (const_int 0))
19316    (use (match_operand:SI 2 "register_operand" "a"))
19317    (use (match_dup 4))]
19318   "!TARGET_64BIT"
19319   "rep stos{l|d}"
19320   [(set_attr "type" "str")
19321    (set_attr "prefix_rep" "1")
19322    (set_attr "memory" "store")
19323    (set_attr "mode" "SI")])
19324
19325 (define_insn "*rep_stossi_rex64"
19326   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19327    (set (match_operand:DI 0 "register_operand" "=D")
19328         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19329                             (const_int 2))
19330                  (match_operand:DI 3 "register_operand" "0")))
19331    (set (mem:BLK (match_dup 3))
19332         (const_int 0))
19333    (use (match_operand:SI 2 "register_operand" "a"))
19334    (use (match_dup 4))]
19335   "TARGET_64BIT"
19336   "rep stos{l|d}"
19337   [(set_attr "type" "str")
19338    (set_attr "prefix_rep" "1")
19339    (set_attr "memory" "store")
19340    (set_attr "mode" "SI")])
19341
19342 (define_insn "*rep_stosqi"
19343   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19344    (set (match_operand:SI 0 "register_operand" "=D")
19345         (plus:SI (match_operand:SI 3 "register_operand" "0")
19346                  (match_operand:SI 4 "register_operand" "1")))
19347    (set (mem:BLK (match_dup 3))
19348         (const_int 0))
19349    (use (match_operand:QI 2 "register_operand" "a"))
19350    (use (match_dup 4))]
19351   "!TARGET_64BIT"
19352   "rep stosb"
19353   [(set_attr "type" "str")
19354    (set_attr "prefix_rep" "1")
19355    (set_attr "memory" "store")
19356    (set_attr "mode" "QI")])
19357
19358 (define_insn "*rep_stosqi_rex64"
19359   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19360    (set (match_operand:DI 0 "register_operand" "=D")
19361         (plus:DI (match_operand:DI 3 "register_operand" "0")
19362                  (match_operand:DI 4 "register_operand" "1")))
19363    (set (mem:BLK (match_dup 3))
19364         (const_int 0))
19365    (use (match_operand:QI 2 "register_operand" "a"))
19366    (use (match_dup 4))]
19367   "TARGET_64BIT"
19368   "rep stosb"
19369   [(set_attr "type" "str")
19370    (set_attr "prefix_rep" "1")
19371    (set_attr "memory" "store")
19372    (set_attr "mode" "QI")])
19373
19374 (define_expand "cmpstrnsi"
19375   [(set (match_operand:SI 0 "register_operand" "")
19376         (compare:SI (match_operand:BLK 1 "general_operand" "")
19377                     (match_operand:BLK 2 "general_operand" "")))
19378    (use (match_operand 3 "general_operand" ""))
19379    (use (match_operand 4 "immediate_operand" ""))]
19380   ""
19381 {
19382   rtx addr1, addr2, out, outlow, count, countreg, align;
19383
19384   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19385     FAIL;
19386
19387   /* Can't use this if the user has appropriated esi or edi.  */
19388   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19389     FAIL;
19390
19391   out = operands[0];
19392   if (!REG_P (out))
19393     out = gen_reg_rtx (SImode);
19394
19395   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19396   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19397   if (addr1 != XEXP (operands[1], 0))
19398     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19399   if (addr2 != XEXP (operands[2], 0))
19400     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19401
19402   count = operands[3];
19403   countreg = ix86_zero_extend_to_Pmode (count);
19404
19405   /* %%% Iff we are testing strict equality, we can use known alignment
19406      to good advantage.  This may be possible with combine, particularly
19407      once cc0 is dead.  */
19408   align = operands[4];
19409
19410   if (CONST_INT_P (count))
19411     {
19412       if (INTVAL (count) == 0)
19413         {
19414           emit_move_insn (operands[0], const0_rtx);
19415           DONE;
19416         }
19417       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19418                                      operands[1], operands[2]));
19419     }
19420   else
19421     {
19422       if (TARGET_64BIT)
19423         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19424       else
19425         emit_insn (gen_cmpsi_1 (countreg, countreg));
19426       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19427                                   operands[1], operands[2]));
19428     }
19429
19430   outlow = gen_lowpart (QImode, out);
19431   emit_insn (gen_cmpintqi (outlow));
19432   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19433
19434   if (operands[0] != out)
19435     emit_move_insn (operands[0], out);
19436
19437   DONE;
19438 })
19439
19440 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19441
19442 (define_expand "cmpintqi"
19443   [(set (match_dup 1)
19444         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19445    (set (match_dup 2)
19446         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19447    (parallel [(set (match_operand:QI 0 "register_operand" "")
19448                    (minus:QI (match_dup 1)
19449                              (match_dup 2)))
19450               (clobber (reg:CC FLAGS_REG))])]
19451   ""
19452   "operands[1] = gen_reg_rtx (QImode);
19453    operands[2] = gen_reg_rtx (QImode);")
19454
19455 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19456 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19457
19458 (define_expand "cmpstrnqi_nz_1"
19459   [(parallel [(set (reg:CC FLAGS_REG)
19460                    (compare:CC (match_operand 4 "memory_operand" "")
19461                                (match_operand 5 "memory_operand" "")))
19462               (use (match_operand 2 "register_operand" ""))
19463               (use (match_operand:SI 3 "immediate_operand" ""))
19464               (clobber (match_operand 0 "register_operand" ""))
19465               (clobber (match_operand 1 "register_operand" ""))
19466               (clobber (match_dup 2))])]
19467   ""
19468   "ix86_current_function_needs_cld = 1;")
19469
19470 (define_insn "*cmpstrnqi_nz_1"
19471   [(set (reg:CC FLAGS_REG)
19472         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19473                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19474    (use (match_operand:SI 6 "register_operand" "2"))
19475    (use (match_operand:SI 3 "immediate_operand" "i"))
19476    (clobber (match_operand:SI 0 "register_operand" "=S"))
19477    (clobber (match_operand:SI 1 "register_operand" "=D"))
19478    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19479   "!TARGET_64BIT"
19480   "repz cmpsb"
19481   [(set_attr "type" "str")
19482    (set_attr "mode" "QI")
19483    (set_attr "prefix_rep" "1")])
19484
19485 (define_insn "*cmpstrnqi_nz_rex_1"
19486   [(set (reg:CC FLAGS_REG)
19487         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19488                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19489    (use (match_operand:DI 6 "register_operand" "2"))
19490    (use (match_operand:SI 3 "immediate_operand" "i"))
19491    (clobber (match_operand:DI 0 "register_operand" "=S"))
19492    (clobber (match_operand:DI 1 "register_operand" "=D"))
19493    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19494   "TARGET_64BIT"
19495   "repz cmpsb"
19496   [(set_attr "type" "str")
19497    (set_attr "mode" "QI")
19498    (set_attr "prefix_rep" "1")])
19499
19500 ;; The same, but the count is not known to not be zero.
19501
19502 (define_expand "cmpstrnqi_1"
19503   [(parallel [(set (reg:CC FLAGS_REG)
19504                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19505                                      (const_int 0))
19506                   (compare:CC (match_operand 4 "memory_operand" "")
19507                               (match_operand 5 "memory_operand" ""))
19508                   (const_int 0)))
19509               (use (match_operand:SI 3 "immediate_operand" ""))
19510               (use (reg:CC FLAGS_REG))
19511               (clobber (match_operand 0 "register_operand" ""))
19512               (clobber (match_operand 1 "register_operand" ""))
19513               (clobber (match_dup 2))])]
19514   ""
19515   "ix86_current_function_needs_cld = 1;")
19516
19517 (define_insn "*cmpstrnqi_1"
19518   [(set (reg:CC FLAGS_REG)
19519         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19520                              (const_int 0))
19521           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19522                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19523           (const_int 0)))
19524    (use (match_operand:SI 3 "immediate_operand" "i"))
19525    (use (reg:CC FLAGS_REG))
19526    (clobber (match_operand:SI 0 "register_operand" "=S"))
19527    (clobber (match_operand:SI 1 "register_operand" "=D"))
19528    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19529   "!TARGET_64BIT"
19530   "repz cmpsb"
19531   [(set_attr "type" "str")
19532    (set_attr "mode" "QI")
19533    (set_attr "prefix_rep" "1")])
19534
19535 (define_insn "*cmpstrnqi_rex_1"
19536   [(set (reg:CC FLAGS_REG)
19537         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19538                              (const_int 0))
19539           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19540                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19541           (const_int 0)))
19542    (use (match_operand:SI 3 "immediate_operand" "i"))
19543    (use (reg:CC FLAGS_REG))
19544    (clobber (match_operand:DI 0 "register_operand" "=S"))
19545    (clobber (match_operand:DI 1 "register_operand" "=D"))
19546    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19547   "TARGET_64BIT"
19548   "repz cmpsb"
19549   [(set_attr "type" "str")
19550    (set_attr "mode" "QI")
19551    (set_attr "prefix_rep" "1")])
19552
19553 (define_expand "strlensi"
19554   [(set (match_operand:SI 0 "register_operand" "")
19555         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19556                     (match_operand:QI 2 "immediate_operand" "")
19557                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19558   ""
19559 {
19560  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19561    DONE;
19562  else
19563    FAIL;
19564 })
19565
19566 (define_expand "strlendi"
19567   [(set (match_operand:DI 0 "register_operand" "")
19568         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19569                     (match_operand:QI 2 "immediate_operand" "")
19570                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19571   ""
19572 {
19573  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19574    DONE;
19575  else
19576    FAIL;
19577 })
19578
19579 (define_expand "strlenqi_1"
19580   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19581               (clobber (match_operand 1 "register_operand" ""))
19582               (clobber (reg:CC FLAGS_REG))])]
19583   ""
19584   "ix86_current_function_needs_cld = 1;")
19585
19586 (define_insn "*strlenqi_1"
19587   [(set (match_operand:SI 0 "register_operand" "=&c")
19588         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19589                     (match_operand:QI 2 "register_operand" "a")
19590                     (match_operand:SI 3 "immediate_operand" "i")
19591                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19592    (clobber (match_operand:SI 1 "register_operand" "=D"))
19593    (clobber (reg:CC FLAGS_REG))]
19594   "!TARGET_64BIT"
19595   "repnz scasb"
19596   [(set_attr "type" "str")
19597    (set_attr "mode" "QI")
19598    (set_attr "prefix_rep" "1")])
19599
19600 (define_insn "*strlenqi_rex_1"
19601   [(set (match_operand:DI 0 "register_operand" "=&c")
19602         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19603                     (match_operand:QI 2 "register_operand" "a")
19604                     (match_operand:DI 3 "immediate_operand" "i")
19605                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19606    (clobber (match_operand:DI 1 "register_operand" "=D"))
19607    (clobber (reg:CC FLAGS_REG))]
19608   "TARGET_64BIT"
19609   "repnz scasb"
19610   [(set_attr "type" "str")
19611    (set_attr "mode" "QI")
19612    (set_attr "prefix_rep" "1")])
19613
19614 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19615 ;; handled in combine, but it is not currently up to the task.
19616 ;; When used for their truth value, the cmpstrn* expanders generate
19617 ;; code like this:
19618 ;;
19619 ;;   repz cmpsb
19620 ;;   seta       %al
19621 ;;   setb       %dl
19622 ;;   cmpb       %al, %dl
19623 ;;   jcc        label
19624 ;;
19625 ;; The intermediate three instructions are unnecessary.
19626
19627 ;; This one handles cmpstrn*_nz_1...
19628 (define_peephole2
19629   [(parallel[
19630      (set (reg:CC FLAGS_REG)
19631           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19632                       (mem:BLK (match_operand 5 "register_operand" ""))))
19633      (use (match_operand 6 "register_operand" ""))
19634      (use (match_operand:SI 3 "immediate_operand" ""))
19635      (clobber (match_operand 0 "register_operand" ""))
19636      (clobber (match_operand 1 "register_operand" ""))
19637      (clobber (match_operand 2 "register_operand" ""))])
19638    (set (match_operand:QI 7 "register_operand" "")
19639         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19640    (set (match_operand:QI 8 "register_operand" "")
19641         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19642    (set (reg FLAGS_REG)
19643         (compare (match_dup 7) (match_dup 8)))
19644   ]
19645   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19646   [(parallel[
19647      (set (reg:CC FLAGS_REG)
19648           (compare:CC (mem:BLK (match_dup 4))
19649                       (mem:BLK (match_dup 5))))
19650      (use (match_dup 6))
19651      (use (match_dup 3))
19652      (clobber (match_dup 0))
19653      (clobber (match_dup 1))
19654      (clobber (match_dup 2))])]
19655   "")
19656
19657 ;; ...and this one handles cmpstrn*_1.
19658 (define_peephole2
19659   [(parallel[
19660      (set (reg:CC FLAGS_REG)
19661           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19662                                (const_int 0))
19663             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19664                         (mem:BLK (match_operand 5 "register_operand" "")))
19665             (const_int 0)))
19666      (use (match_operand:SI 3 "immediate_operand" ""))
19667      (use (reg:CC FLAGS_REG))
19668      (clobber (match_operand 0 "register_operand" ""))
19669      (clobber (match_operand 1 "register_operand" ""))
19670      (clobber (match_operand 2 "register_operand" ""))])
19671    (set (match_operand:QI 7 "register_operand" "")
19672         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19673    (set (match_operand:QI 8 "register_operand" "")
19674         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19675    (set (reg FLAGS_REG)
19676         (compare (match_dup 7) (match_dup 8)))
19677   ]
19678   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19679   [(parallel[
19680      (set (reg:CC FLAGS_REG)
19681           (if_then_else:CC (ne (match_dup 6)
19682                                (const_int 0))
19683             (compare:CC (mem:BLK (match_dup 4))
19684                         (mem:BLK (match_dup 5)))
19685             (const_int 0)))
19686      (use (match_dup 3))
19687      (use (reg:CC FLAGS_REG))
19688      (clobber (match_dup 0))
19689      (clobber (match_dup 1))
19690      (clobber (match_dup 2))])]
19691   "")
19692
19693
19694 \f
19695 ;; Conditional move instructions.
19696
19697 (define_expand "movdicc"
19698   [(set (match_operand:DI 0 "register_operand" "")
19699         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19700                          (match_operand:DI 2 "general_operand" "")
19701                          (match_operand:DI 3 "general_operand" "")))]
19702   "TARGET_64BIT"
19703   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19704
19705 (define_insn "x86_movdicc_0_m1_rex64"
19706   [(set (match_operand:DI 0 "register_operand" "=r")
19707         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19708           (const_int -1)
19709           (const_int 0)))
19710    (clobber (reg:CC FLAGS_REG))]
19711   "TARGET_64BIT"
19712   "sbb{q}\t%0, %0"
19713   ; Since we don't have the proper number of operands for an alu insn,
19714   ; fill in all the blanks.
19715   [(set_attr "type" "alu")
19716    (set_attr "pent_pair" "pu")
19717    (set_attr "memory" "none")
19718    (set_attr "imm_disp" "false")
19719    (set_attr "mode" "DI")
19720    (set_attr "length_immediate" "0")])
19721
19722 (define_insn "*x86_movdicc_0_m1_se"
19723   [(set (match_operand:DI 0 "register_operand" "=r")
19724         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19725                          (const_int 1)
19726                          (const_int 0)))
19727    (clobber (reg:CC FLAGS_REG))]
19728   ""
19729   "sbb{q}\t%0, %0"
19730   [(set_attr "type" "alu")
19731    (set_attr "pent_pair" "pu")
19732    (set_attr "memory" "none")
19733    (set_attr "imm_disp" "false")
19734    (set_attr "mode" "DI")
19735    (set_attr "length_immediate" "0")])
19736
19737 (define_insn "*movdicc_c_rex64"
19738   [(set (match_operand:DI 0 "register_operand" "=r,r")
19739         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19740                                 [(reg FLAGS_REG) (const_int 0)])
19741                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19742                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19743   "TARGET_64BIT && TARGET_CMOVE
19744    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19745   "@
19746    cmov%O2%C1\t{%2, %0|%0, %2}
19747    cmov%O2%c1\t{%3, %0|%0, %3}"
19748   [(set_attr "type" "icmov")
19749    (set_attr "mode" "DI")])
19750
19751 (define_expand "movsicc"
19752   [(set (match_operand:SI 0 "register_operand" "")
19753         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19754                          (match_operand:SI 2 "general_operand" "")
19755                          (match_operand:SI 3 "general_operand" "")))]
19756   ""
19757   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19758
19759 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19760 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19761 ;; So just document what we're doing explicitly.
19762
19763 (define_insn "x86_movsicc_0_m1"
19764   [(set (match_operand:SI 0 "register_operand" "=r")
19765         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19766           (const_int -1)
19767           (const_int 0)))
19768    (clobber (reg:CC FLAGS_REG))]
19769   ""
19770   "sbb{l}\t%0, %0"
19771   ; Since we don't have the proper number of operands for an alu insn,
19772   ; fill in all the blanks.
19773   [(set_attr "type" "alu")
19774    (set_attr "pent_pair" "pu")
19775    (set_attr "memory" "none")
19776    (set_attr "imm_disp" "false")
19777    (set_attr "mode" "SI")
19778    (set_attr "length_immediate" "0")])
19779
19780 (define_insn "*x86_movsicc_0_m1_se"
19781   [(set (match_operand:SI 0 "register_operand" "=r")
19782         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19783                          (const_int 1)
19784                          (const_int 0)))
19785    (clobber (reg:CC FLAGS_REG))]
19786   ""
19787   "sbb{l}\t%0, %0"
19788   [(set_attr "type" "alu")
19789    (set_attr "pent_pair" "pu")
19790    (set_attr "memory" "none")
19791    (set_attr "imm_disp" "false")
19792    (set_attr "mode" "SI")
19793    (set_attr "length_immediate" "0")])
19794
19795 (define_insn "*movsicc_noc"
19796   [(set (match_operand:SI 0 "register_operand" "=r,r")
19797         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19798                                 [(reg FLAGS_REG) (const_int 0)])
19799                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19800                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19801   "TARGET_CMOVE
19802    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19803   "@
19804    cmov%O2%C1\t{%2, %0|%0, %2}
19805    cmov%O2%c1\t{%3, %0|%0, %3}"
19806   [(set_attr "type" "icmov")
19807    (set_attr "mode" "SI")])
19808
19809 (define_expand "movhicc"
19810   [(set (match_operand:HI 0 "register_operand" "")
19811         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19812                          (match_operand:HI 2 "general_operand" "")
19813                          (match_operand:HI 3 "general_operand" "")))]
19814   "TARGET_HIMODE_MATH"
19815   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19816
19817 (define_insn "*movhicc_noc"
19818   [(set (match_operand:HI 0 "register_operand" "=r,r")
19819         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19820                                 [(reg FLAGS_REG) (const_int 0)])
19821                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19822                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19823   "TARGET_CMOVE
19824    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19825   "@
19826    cmov%O2%C1\t{%2, %0|%0, %2}
19827    cmov%O2%c1\t{%3, %0|%0, %3}"
19828   [(set_attr "type" "icmov")
19829    (set_attr "mode" "HI")])
19830
19831 (define_expand "movqicc"
19832   [(set (match_operand:QI 0 "register_operand" "")
19833         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19834                          (match_operand:QI 2 "general_operand" "")
19835                          (match_operand:QI 3 "general_operand" "")))]
19836   "TARGET_QIMODE_MATH"
19837   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19838
19839 (define_insn_and_split "*movqicc_noc"
19840   [(set (match_operand:QI 0 "register_operand" "=r,r")
19841         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19842                                 [(match_operand 4 "flags_reg_operand" "")
19843                                  (const_int 0)])
19844                       (match_operand:QI 2 "register_operand" "r,0")
19845                       (match_operand:QI 3 "register_operand" "0,r")))]
19846   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19847   "#"
19848   "&& reload_completed"
19849   [(set (match_dup 0)
19850         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19851                       (match_dup 2)
19852                       (match_dup 3)))]
19853   "operands[0] = gen_lowpart (SImode, operands[0]);
19854    operands[2] = gen_lowpart (SImode, operands[2]);
19855    operands[3] = gen_lowpart (SImode, operands[3]);"
19856   [(set_attr "type" "icmov")
19857    (set_attr "mode" "SI")])
19858
19859 (define_expand "mov<mode>cc"
19860   [(set (match_operand:X87MODEF 0 "register_operand" "")
19861         (if_then_else:X87MODEF
19862           (match_operand 1 "comparison_operator" "")
19863           (match_operand:X87MODEF 2 "register_operand" "")
19864           (match_operand:X87MODEF 3 "register_operand" "")))]
19865   "(TARGET_80387 && TARGET_CMOVE)
19866    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19867   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19868
19869 (define_insn "*movsfcc_1_387"
19870   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19871         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19872                                 [(reg FLAGS_REG) (const_int 0)])
19873                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19874                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19875   "TARGET_80387 && TARGET_CMOVE
19876    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19877   "@
19878    fcmov%F1\t{%2, %0|%0, %2}
19879    fcmov%f1\t{%3, %0|%0, %3}
19880    cmov%O2%C1\t{%2, %0|%0, %2}
19881    cmov%O2%c1\t{%3, %0|%0, %3}"
19882   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19883    (set_attr "mode" "SF,SF,SI,SI")])
19884
19885 (define_insn "*movdfcc_1"
19886   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19887         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19888                                 [(reg FLAGS_REG) (const_int 0)])
19889                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19890                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19891   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19892    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19893   "@
19894    fcmov%F1\t{%2, %0|%0, %2}
19895    fcmov%f1\t{%3, %0|%0, %3}
19896    #
19897    #"
19898   [(set_attr "type" "fcmov,fcmov,multi,multi")
19899    (set_attr "mode" "DF")])
19900
19901 (define_insn "*movdfcc_1_rex64"
19902   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19903         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19904                                 [(reg FLAGS_REG) (const_int 0)])
19905                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19906                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19907   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19908    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19909   "@
19910    fcmov%F1\t{%2, %0|%0, %2}
19911    fcmov%f1\t{%3, %0|%0, %3}
19912    cmov%O2%C1\t{%2, %0|%0, %2}
19913    cmov%O2%c1\t{%3, %0|%0, %3}"
19914   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19915    (set_attr "mode" "DF")])
19916
19917 (define_split
19918   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19919         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19920                                 [(match_operand 4 "flags_reg_operand" "")
19921                                  (const_int 0)])
19922                       (match_operand:DF 2 "nonimmediate_operand" "")
19923                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19924   "!TARGET_64BIT && reload_completed"
19925   [(set (match_dup 2)
19926         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19927                       (match_dup 5)
19928                       (match_dup 6)))
19929    (set (match_dup 3)
19930         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19931                       (match_dup 7)
19932                       (match_dup 8)))]
19933   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19934    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19935
19936 (define_insn "*movxfcc_1"
19937   [(set (match_operand:XF 0 "register_operand" "=f,f")
19938         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19939                                 [(reg FLAGS_REG) (const_int 0)])
19940                       (match_operand:XF 2 "register_operand" "f,0")
19941                       (match_operand:XF 3 "register_operand" "0,f")))]
19942   "TARGET_80387 && TARGET_CMOVE"
19943   "@
19944    fcmov%F1\t{%2, %0|%0, %2}
19945    fcmov%f1\t{%3, %0|%0, %3}"
19946   [(set_attr "type" "fcmov")
19947    (set_attr "mode" "XF")])
19948
19949 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19950 ;; the scalar versions to have only XMM registers as operands.
19951
19952 ;; SSE5 conditional move
19953 (define_insn "*sse5_pcmov_<mode>"
19954   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19955         (if_then_else:MODEF
19956           (match_operand:MODEF 1 "register_operand" "x,0")
19957           (match_operand:MODEF 2 "register_operand" "0,x")
19958           (match_operand:MODEF 3 "register_operand" "x,x")))]
19959   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19960   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19961   [(set_attr "type" "sse4arg")])
19962
19963 ;; These versions of the min/max patterns are intentionally ignorant of
19964 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19965 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19966 ;; are undefined in this condition, we're certain this is correct.
19967
19968 (define_insn "*avx_<code><mode>3"
19969   [(set (match_operand:MODEF 0 "register_operand" "=x")
19970         (smaxmin:MODEF
19971           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19972           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19973   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19974   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19975   [(set_attr "type" "sseadd")
19976    (set_attr "prefix" "vex")
19977    (set_attr "mode" "<MODE>")])
19978
19979 (define_insn "<code><mode>3"
19980   [(set (match_operand:MODEF 0 "register_operand" "=x")
19981         (smaxmin:MODEF
19982           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19983           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19984   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19985   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19986   [(set_attr "type" "sseadd")
19987    (set_attr "mode" "<MODE>")])
19988
19989 ;; These versions of the min/max patterns implement exactly the operations
19990 ;;   min = (op1 < op2 ? op1 : op2)
19991 ;;   max = (!(op1 < op2) ? op1 : op2)
19992 ;; Their operands are not commutative, and thus they may be used in the
19993 ;; presence of -0.0 and NaN.
19994
19995 (define_insn "*avx_ieee_smin<mode>3"
19996   [(set (match_operand:MODEF 0 "register_operand" "=x")
19997         (unspec:MODEF
19998           [(match_operand:MODEF 1 "register_operand" "x")
19999            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20000          UNSPEC_IEEE_MIN))]
20001   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20002   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20003   [(set_attr "type" "sseadd")
20004    (set_attr "prefix" "vex")
20005    (set_attr "mode" "<MODE>")])
20006
20007 (define_insn "*ieee_smin<mode>3"
20008   [(set (match_operand:MODEF 0 "register_operand" "=x")
20009         (unspec:MODEF
20010           [(match_operand:MODEF 1 "register_operand" "0")
20011            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20012          UNSPEC_IEEE_MIN))]
20013   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20014   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20015   [(set_attr "type" "sseadd")
20016    (set_attr "mode" "<MODE>")])
20017
20018 (define_insn "*avx_ieee_smax<mode>3"
20019   [(set (match_operand:MODEF 0 "register_operand" "=x")
20020         (unspec:MODEF
20021           [(match_operand:MODEF 1 "register_operand" "0")
20022            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20023          UNSPEC_IEEE_MAX))]
20024   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20025   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20026   [(set_attr "type" "sseadd")
20027    (set_attr "prefix" "vex")
20028    (set_attr "mode" "<MODE>")])
20029
20030 (define_insn "*ieee_smax<mode>3"
20031   [(set (match_operand:MODEF 0 "register_operand" "=x")
20032         (unspec:MODEF
20033           [(match_operand:MODEF 1 "register_operand" "0")
20034            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20035          UNSPEC_IEEE_MAX))]
20036   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20037   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20038   [(set_attr "type" "sseadd")
20039    (set_attr "mode" "<MODE>")])
20040
20041 ;; Make two stack loads independent:
20042 ;;   fld aa              fld aa
20043 ;;   fld %st(0)     ->   fld bb
20044 ;;   fmul bb             fmul %st(1), %st
20045 ;;
20046 ;; Actually we only match the last two instructions for simplicity.
20047 (define_peephole2
20048   [(set (match_operand 0 "fp_register_operand" "")
20049         (match_operand 1 "fp_register_operand" ""))
20050    (set (match_dup 0)
20051         (match_operator 2 "binary_fp_operator"
20052            [(match_dup 0)
20053             (match_operand 3 "memory_operand" "")]))]
20054   "REGNO (operands[0]) != REGNO (operands[1])"
20055   [(set (match_dup 0) (match_dup 3))
20056    (set (match_dup 0) (match_dup 4))]
20057
20058   ;; The % modifier is not operational anymore in peephole2's, so we have to
20059   ;; swap the operands manually in the case of addition and multiplication.
20060   "if (COMMUTATIVE_ARITH_P (operands[2]))
20061      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20062                                  operands[0], operands[1]);
20063    else
20064      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20065                                  operands[1], operands[0]);")
20066
20067 ;; Conditional addition patterns
20068 (define_expand "add<mode>cc"
20069   [(match_operand:SWI 0 "register_operand" "")
20070    (match_operand 1 "comparison_operator" "")
20071    (match_operand:SWI 2 "register_operand" "")
20072    (match_operand:SWI 3 "const_int_operand" "")]
20073   ""
20074   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20075
20076 \f
20077 ;; Misc patterns (?)
20078
20079 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20080 ;; Otherwise there will be nothing to keep
20081 ;;
20082 ;; [(set (reg ebp) (reg esp))]
20083 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20084 ;;  (clobber (eflags)]
20085 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20086 ;;
20087 ;; in proper program order.
20088 (define_insn "pro_epilogue_adjust_stack_1"
20089   [(set (match_operand:SI 0 "register_operand" "=r,r")
20090         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20091                  (match_operand:SI 2 "immediate_operand" "i,i")))
20092    (clobber (reg:CC FLAGS_REG))
20093    (clobber (mem:BLK (scratch)))]
20094   "!TARGET_64BIT"
20095 {
20096   switch (get_attr_type (insn))
20097     {
20098     case TYPE_IMOV:
20099       return "mov{l}\t{%1, %0|%0, %1}";
20100
20101     case TYPE_ALU:
20102       if (CONST_INT_P (operands[2])
20103           && (INTVAL (operands[2]) == 128
20104               || (INTVAL (operands[2]) < 0
20105                   && INTVAL (operands[2]) != -128)))
20106         {
20107           operands[2] = GEN_INT (-INTVAL (operands[2]));
20108           return "sub{l}\t{%2, %0|%0, %2}";
20109         }
20110       return "add{l}\t{%2, %0|%0, %2}";
20111
20112     case TYPE_LEA:
20113       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20114       return "lea{l}\t{%a2, %0|%0, %a2}";
20115
20116     default:
20117       gcc_unreachable ();
20118     }
20119 }
20120   [(set (attr "type")
20121         (cond [(eq_attr "alternative" "0")
20122                  (const_string "alu")
20123                (match_operand:SI 2 "const0_operand" "")
20124                  (const_string "imov")
20125               ]
20126               (const_string "lea")))
20127    (set_attr "mode" "SI")])
20128
20129 (define_insn "pro_epilogue_adjust_stack_rex64"
20130   [(set (match_operand:DI 0 "register_operand" "=r,r")
20131         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20132                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20133    (clobber (reg:CC FLAGS_REG))
20134    (clobber (mem:BLK (scratch)))]
20135   "TARGET_64BIT"
20136 {
20137   switch (get_attr_type (insn))
20138     {
20139     case TYPE_IMOV:
20140       return "mov{q}\t{%1, %0|%0, %1}";
20141
20142     case TYPE_ALU:
20143       if (CONST_INT_P (operands[2])
20144           /* Avoid overflows.  */
20145           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20146           && (INTVAL (operands[2]) == 128
20147               || (INTVAL (operands[2]) < 0
20148                   && INTVAL (operands[2]) != -128)))
20149         {
20150           operands[2] = GEN_INT (-INTVAL (operands[2]));
20151           return "sub{q}\t{%2, %0|%0, %2}";
20152         }
20153       return "add{q}\t{%2, %0|%0, %2}";
20154
20155     case TYPE_LEA:
20156       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20157       return "lea{q}\t{%a2, %0|%0, %a2}";
20158
20159     default:
20160       gcc_unreachable ();
20161     }
20162 }
20163   [(set (attr "type")
20164         (cond [(eq_attr "alternative" "0")
20165                  (const_string "alu")
20166                (match_operand:DI 2 "const0_operand" "")
20167                  (const_string "imov")
20168               ]
20169               (const_string "lea")))
20170    (set_attr "mode" "DI")])
20171
20172 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20173   [(set (match_operand:DI 0 "register_operand" "=r,r")
20174         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20175                  (match_operand:DI 3 "immediate_operand" "i,i")))
20176    (use (match_operand:DI 2 "register_operand" "r,r"))
20177    (clobber (reg:CC FLAGS_REG))
20178    (clobber (mem:BLK (scratch)))]
20179   "TARGET_64BIT"
20180 {
20181   switch (get_attr_type (insn))
20182     {
20183     case TYPE_ALU:
20184       return "add{q}\t{%2, %0|%0, %2}";
20185
20186     case TYPE_LEA:
20187       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20188       return "lea{q}\t{%a2, %0|%0, %a2}";
20189
20190     default:
20191       gcc_unreachable ();
20192     }
20193 }
20194   [(set_attr "type" "alu,lea")
20195    (set_attr "mode" "DI")])
20196
20197 (define_insn "allocate_stack_worker_32"
20198   [(set (match_operand:SI 0 "register_operand" "=a")
20199         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20200                             UNSPECV_STACK_PROBE))
20201    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20202    (clobber (reg:CC FLAGS_REG))]
20203   "!TARGET_64BIT && TARGET_STACK_PROBE"
20204   "call\t___chkstk"
20205   [(set_attr "type" "multi")
20206    (set_attr "length" "5")])
20207
20208 (define_insn "allocate_stack_worker_64"
20209   [(set (match_operand:DI 0 "register_operand" "=a")
20210         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20211                             UNSPECV_STACK_PROBE))
20212    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20213    (clobber (reg:DI R10_REG))
20214    (clobber (reg:DI R11_REG))
20215    (clobber (reg:CC FLAGS_REG))]
20216   "TARGET_64BIT && TARGET_STACK_PROBE"
20217   "call\t___chkstk"
20218   [(set_attr "type" "multi")
20219    (set_attr "length" "5")])
20220
20221 (define_expand "allocate_stack"
20222   [(match_operand 0 "register_operand" "")
20223    (match_operand 1 "general_operand" "")]
20224   "TARGET_STACK_PROBE"
20225 {
20226   rtx x;
20227
20228 #ifndef CHECK_STACK_LIMIT
20229 #define CHECK_STACK_LIMIT 0
20230 #endif
20231
20232   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20233       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20234     {
20235       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20236                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20237       if (x != stack_pointer_rtx)
20238         emit_move_insn (stack_pointer_rtx, x);
20239     }
20240   else
20241     {
20242       x = copy_to_mode_reg (Pmode, operands[1]);
20243       if (TARGET_64BIT)
20244         x = gen_allocate_stack_worker_64 (x, x);
20245       else
20246         x = gen_allocate_stack_worker_32 (x, x);
20247       emit_insn (x);
20248     }
20249
20250   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20251   DONE;
20252 })
20253
20254 (define_expand "builtin_setjmp_receiver"
20255   [(label_ref (match_operand 0 "" ""))]
20256   "!TARGET_64BIT && flag_pic"
20257 {
20258 #if TARGET_MACHO
20259   if (TARGET_MACHO)
20260     {
20261       rtx xops[3];
20262       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20263       rtx label_rtx = gen_label_rtx ();
20264       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20265       xops[0] = xops[1] = picreg;
20266       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20267       ix86_expand_binary_operator (MINUS, SImode, xops);
20268     }
20269   else
20270 #endif
20271     emit_insn (gen_set_got (pic_offset_table_rtx));
20272   DONE;
20273 })
20274 \f
20275 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20276
20277 (define_split
20278   [(set (match_operand 0 "register_operand" "")
20279         (match_operator 3 "promotable_binary_operator"
20280            [(match_operand 1 "register_operand" "")
20281             (match_operand 2 "aligned_operand" "")]))
20282    (clobber (reg:CC FLAGS_REG))]
20283   "! TARGET_PARTIAL_REG_STALL && reload_completed
20284    && ((GET_MODE (operands[0]) == HImode
20285         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20286             /* ??? next two lines just !satisfies_constraint_K (...) */
20287             || !CONST_INT_P (operands[2])
20288             || satisfies_constraint_K (operands[2])))
20289        || (GET_MODE (operands[0]) == QImode
20290            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20291   [(parallel [(set (match_dup 0)
20292                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20293               (clobber (reg:CC FLAGS_REG))])]
20294   "operands[0] = gen_lowpart (SImode, operands[0]);
20295    operands[1] = gen_lowpart (SImode, operands[1]);
20296    if (GET_CODE (operands[3]) != ASHIFT)
20297      operands[2] = gen_lowpart (SImode, operands[2]);
20298    PUT_MODE (operands[3], SImode);")
20299
20300 ; Promote the QImode tests, as i386 has encoding of the AND
20301 ; instruction with 32-bit sign-extended immediate and thus the
20302 ; instruction size is unchanged, except in the %eax case for
20303 ; which it is increased by one byte, hence the ! optimize_size.
20304 (define_split
20305   [(set (match_operand 0 "flags_reg_operand" "")
20306         (match_operator 2 "compare_operator"
20307           [(and (match_operand 3 "aligned_operand" "")
20308                 (match_operand 4 "const_int_operand" ""))
20309            (const_int 0)]))
20310    (set (match_operand 1 "register_operand" "")
20311         (and (match_dup 3) (match_dup 4)))]
20312   "! TARGET_PARTIAL_REG_STALL && reload_completed
20313    && optimize_insn_for_speed_p ()
20314    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20315        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20316    /* Ensure that the operand will remain sign-extended immediate.  */
20317    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20318   [(parallel [(set (match_dup 0)
20319                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20320                                     (const_int 0)]))
20321               (set (match_dup 1)
20322                    (and:SI (match_dup 3) (match_dup 4)))])]
20323 {
20324   operands[4]
20325     = gen_int_mode (INTVAL (operands[4])
20326                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20327   operands[1] = gen_lowpart (SImode, operands[1]);
20328   operands[3] = gen_lowpart (SImode, operands[3]);
20329 })
20330
20331 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20332 ; the TEST instruction with 32-bit sign-extended immediate and thus
20333 ; the instruction size would at least double, which is not what we
20334 ; want even with ! optimize_size.
20335 (define_split
20336   [(set (match_operand 0 "flags_reg_operand" "")
20337         (match_operator 1 "compare_operator"
20338           [(and (match_operand:HI 2 "aligned_operand" "")
20339                 (match_operand:HI 3 "const_int_operand" ""))
20340            (const_int 0)]))]
20341   "! TARGET_PARTIAL_REG_STALL && reload_completed
20342    && ! TARGET_FAST_PREFIX
20343    && optimize_insn_for_speed_p ()
20344    /* Ensure that the operand will remain sign-extended immediate.  */
20345    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20346   [(set (match_dup 0)
20347         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20348                          (const_int 0)]))]
20349 {
20350   operands[3]
20351     = gen_int_mode (INTVAL (operands[3])
20352                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20353   operands[2] = gen_lowpart (SImode, operands[2]);
20354 })
20355
20356 (define_split
20357   [(set (match_operand 0 "register_operand" "")
20358         (neg (match_operand 1 "register_operand" "")))
20359    (clobber (reg:CC FLAGS_REG))]
20360   "! TARGET_PARTIAL_REG_STALL && reload_completed
20361    && (GET_MODE (operands[0]) == HImode
20362        || (GET_MODE (operands[0]) == QImode
20363            && (TARGET_PROMOTE_QImode
20364                || optimize_insn_for_size_p ())))"
20365   [(parallel [(set (match_dup 0)
20366                    (neg:SI (match_dup 1)))
20367               (clobber (reg:CC FLAGS_REG))])]
20368   "operands[0] = gen_lowpart (SImode, operands[0]);
20369    operands[1] = gen_lowpart (SImode, operands[1]);")
20370
20371 (define_split
20372   [(set (match_operand 0 "register_operand" "")
20373         (not (match_operand 1 "register_operand" "")))]
20374   "! TARGET_PARTIAL_REG_STALL && reload_completed
20375    && (GET_MODE (operands[0]) == HImode
20376        || (GET_MODE (operands[0]) == QImode
20377            && (TARGET_PROMOTE_QImode
20378                || optimize_insn_for_size_p ())))"
20379   [(set (match_dup 0)
20380         (not:SI (match_dup 1)))]
20381   "operands[0] = gen_lowpart (SImode, operands[0]);
20382    operands[1] = gen_lowpart (SImode, operands[1]);")
20383
20384 (define_split
20385   [(set (match_operand 0 "register_operand" "")
20386         (if_then_else (match_operator 1 "comparison_operator"
20387                                 [(reg FLAGS_REG) (const_int 0)])
20388                       (match_operand 2 "register_operand" "")
20389                       (match_operand 3 "register_operand" "")))]
20390   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20391    && (GET_MODE (operands[0]) == HImode
20392        || (GET_MODE (operands[0]) == QImode
20393            && (TARGET_PROMOTE_QImode
20394                || optimize_insn_for_size_p ())))"
20395   [(set (match_dup 0)
20396         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20397   "operands[0] = gen_lowpart (SImode, operands[0]);
20398    operands[2] = gen_lowpart (SImode, operands[2]);
20399    operands[3] = gen_lowpart (SImode, operands[3]);")
20400
20401 \f
20402 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20403 ;; transform a complex memory operation into two memory to register operations.
20404
20405 ;; Don't push memory operands
20406 (define_peephole2
20407   [(set (match_operand:SI 0 "push_operand" "")
20408         (match_operand:SI 1 "memory_operand" ""))
20409    (match_scratch:SI 2 "r")]
20410   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20411    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20412   [(set (match_dup 2) (match_dup 1))
20413    (set (match_dup 0) (match_dup 2))]
20414   "")
20415
20416 (define_peephole2
20417   [(set (match_operand:DI 0 "push_operand" "")
20418         (match_operand:DI 1 "memory_operand" ""))
20419    (match_scratch:DI 2 "r")]
20420   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20421    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20422   [(set (match_dup 2) (match_dup 1))
20423    (set (match_dup 0) (match_dup 2))]
20424   "")
20425
20426 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20427 ;; SImode pushes.
20428 (define_peephole2
20429   [(set (match_operand:SF 0 "push_operand" "")
20430         (match_operand:SF 1 "memory_operand" ""))
20431    (match_scratch:SF 2 "r")]
20432   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20433    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20434   [(set (match_dup 2) (match_dup 1))
20435    (set (match_dup 0) (match_dup 2))]
20436   "")
20437
20438 (define_peephole2
20439   [(set (match_operand:HI 0 "push_operand" "")
20440         (match_operand:HI 1 "memory_operand" ""))
20441    (match_scratch:HI 2 "r")]
20442   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20443    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20444   [(set (match_dup 2) (match_dup 1))
20445    (set (match_dup 0) (match_dup 2))]
20446   "")
20447
20448 (define_peephole2
20449   [(set (match_operand:QI 0 "push_operand" "")
20450         (match_operand:QI 1 "memory_operand" ""))
20451    (match_scratch:QI 2 "q")]
20452   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20453    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20454   [(set (match_dup 2) (match_dup 1))
20455    (set (match_dup 0) (match_dup 2))]
20456   "")
20457
20458 ;; Don't move an immediate directly to memory when the instruction
20459 ;; gets too big.
20460 (define_peephole2
20461   [(match_scratch:SI 1 "r")
20462    (set (match_operand:SI 0 "memory_operand" "")
20463         (const_int 0))]
20464   "optimize_insn_for_speed_p ()
20465    && ! TARGET_USE_MOV0
20466    && TARGET_SPLIT_LONG_MOVES
20467    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20468    && peep2_regno_dead_p (0, FLAGS_REG)"
20469   [(parallel [(set (match_dup 1) (const_int 0))
20470               (clobber (reg:CC FLAGS_REG))])
20471    (set (match_dup 0) (match_dup 1))]
20472   "")
20473
20474 (define_peephole2
20475   [(match_scratch:HI 1 "r")
20476    (set (match_operand:HI 0 "memory_operand" "")
20477         (const_int 0))]
20478   "optimize_insn_for_speed_p ()
20479    && ! TARGET_USE_MOV0
20480    && TARGET_SPLIT_LONG_MOVES
20481    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20482    && peep2_regno_dead_p (0, FLAGS_REG)"
20483   [(parallel [(set (match_dup 2) (const_int 0))
20484               (clobber (reg:CC FLAGS_REG))])
20485    (set (match_dup 0) (match_dup 1))]
20486   "operands[2] = gen_lowpart (SImode, operands[1]);")
20487
20488 (define_peephole2
20489   [(match_scratch:QI 1 "q")
20490    (set (match_operand:QI 0 "memory_operand" "")
20491         (const_int 0))]
20492   "optimize_insn_for_speed_p ()
20493    && ! TARGET_USE_MOV0
20494    && TARGET_SPLIT_LONG_MOVES
20495    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20496    && peep2_regno_dead_p (0, FLAGS_REG)"
20497   [(parallel [(set (match_dup 2) (const_int 0))
20498               (clobber (reg:CC FLAGS_REG))])
20499    (set (match_dup 0) (match_dup 1))]
20500   "operands[2] = gen_lowpart (SImode, operands[1]);")
20501
20502 (define_peephole2
20503   [(match_scratch:SI 2 "r")
20504    (set (match_operand:SI 0 "memory_operand" "")
20505         (match_operand:SI 1 "immediate_operand" ""))]
20506   "optimize_insn_for_speed_p ()
20507    && TARGET_SPLIT_LONG_MOVES
20508    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20509   [(set (match_dup 2) (match_dup 1))
20510    (set (match_dup 0) (match_dup 2))]
20511   "")
20512
20513 (define_peephole2
20514   [(match_scratch:HI 2 "r")
20515    (set (match_operand:HI 0 "memory_operand" "")
20516         (match_operand:HI 1 "immediate_operand" ""))]
20517   "optimize_insn_for_speed_p ()
20518    && TARGET_SPLIT_LONG_MOVES
20519    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20520   [(set (match_dup 2) (match_dup 1))
20521    (set (match_dup 0) (match_dup 2))]
20522   "")
20523
20524 (define_peephole2
20525   [(match_scratch:QI 2 "q")
20526    (set (match_operand:QI 0 "memory_operand" "")
20527         (match_operand:QI 1 "immediate_operand" ""))]
20528   "optimize_insn_for_speed_p ()
20529    && TARGET_SPLIT_LONG_MOVES
20530    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20531   [(set (match_dup 2) (match_dup 1))
20532    (set (match_dup 0) (match_dup 2))]
20533   "")
20534
20535 ;; Don't compare memory with zero, load and use a test instead.
20536 (define_peephole2
20537   [(set (match_operand 0 "flags_reg_operand" "")
20538         (match_operator 1 "compare_operator"
20539           [(match_operand:SI 2 "memory_operand" "")
20540            (const_int 0)]))
20541    (match_scratch:SI 3 "r")]
20542   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20543   [(set (match_dup 3) (match_dup 2))
20544    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20545   "")
20546
20547 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20548 ;; Don't split NOTs with a displacement operand, because resulting XOR
20549 ;; will not be pairable anyway.
20550 ;;
20551 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20552 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20553 ;; so this split helps here as well.
20554 ;;
20555 ;; Note: Can't do this as a regular split because we can't get proper
20556 ;; lifetime information then.
20557
20558 (define_peephole2
20559   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20560         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20561   "optimize_insn_for_speed_p ()
20562    && ((TARGET_NOT_UNPAIRABLE
20563         && (!MEM_P (operands[0])
20564             || !memory_displacement_operand (operands[0], SImode)))
20565        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20566    && peep2_regno_dead_p (0, FLAGS_REG)"
20567   [(parallel [(set (match_dup 0)
20568                    (xor:SI (match_dup 1) (const_int -1)))
20569               (clobber (reg:CC FLAGS_REG))])]
20570   "")
20571
20572 (define_peephole2
20573   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20574         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20575   "optimize_insn_for_speed_p ()
20576    && ((TARGET_NOT_UNPAIRABLE
20577         && (!MEM_P (operands[0])
20578             || !memory_displacement_operand (operands[0], HImode)))
20579        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20580    && peep2_regno_dead_p (0, FLAGS_REG)"
20581   [(parallel [(set (match_dup 0)
20582                    (xor:HI (match_dup 1) (const_int -1)))
20583               (clobber (reg:CC FLAGS_REG))])]
20584   "")
20585
20586 (define_peephole2
20587   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20588         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20589   "optimize_insn_for_speed_p ()
20590    && ((TARGET_NOT_UNPAIRABLE
20591         && (!MEM_P (operands[0])
20592             || !memory_displacement_operand (operands[0], QImode)))
20593        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20594    && peep2_regno_dead_p (0, FLAGS_REG)"
20595   [(parallel [(set (match_dup 0)
20596                    (xor:QI (match_dup 1) (const_int -1)))
20597               (clobber (reg:CC FLAGS_REG))])]
20598   "")
20599
20600 ;; Non pairable "test imm, reg" instructions can be translated to
20601 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20602 ;; byte opcode instead of two, have a short form for byte operands),
20603 ;; so do it for other CPUs as well.  Given that the value was dead,
20604 ;; this should not create any new dependencies.  Pass on the sub-word
20605 ;; versions if we're concerned about partial register stalls.
20606
20607 (define_peephole2
20608   [(set (match_operand 0 "flags_reg_operand" "")
20609         (match_operator 1 "compare_operator"
20610           [(and:SI (match_operand:SI 2 "register_operand" "")
20611                    (match_operand:SI 3 "immediate_operand" ""))
20612            (const_int 0)]))]
20613   "ix86_match_ccmode (insn, CCNOmode)
20614    && (true_regnum (operands[2]) != AX_REG
20615        || satisfies_constraint_K (operands[3]))
20616    && peep2_reg_dead_p (1, operands[2])"
20617   [(parallel
20618      [(set (match_dup 0)
20619            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20620                             (const_int 0)]))
20621       (set (match_dup 2)
20622            (and:SI (match_dup 2) (match_dup 3)))])]
20623   "")
20624
20625 ;; We don't need to handle HImode case, because it will be promoted to SImode
20626 ;; on ! TARGET_PARTIAL_REG_STALL
20627
20628 (define_peephole2
20629   [(set (match_operand 0 "flags_reg_operand" "")
20630         (match_operator 1 "compare_operator"
20631           [(and:QI (match_operand:QI 2 "register_operand" "")
20632                    (match_operand:QI 3 "immediate_operand" ""))
20633            (const_int 0)]))]
20634   "! TARGET_PARTIAL_REG_STALL
20635    && ix86_match_ccmode (insn, CCNOmode)
20636    && true_regnum (operands[2]) != AX_REG
20637    && peep2_reg_dead_p (1, operands[2])"
20638   [(parallel
20639      [(set (match_dup 0)
20640            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20641                             (const_int 0)]))
20642       (set (match_dup 2)
20643            (and:QI (match_dup 2) (match_dup 3)))])]
20644   "")
20645
20646 (define_peephole2
20647   [(set (match_operand 0 "flags_reg_operand" "")
20648         (match_operator 1 "compare_operator"
20649           [(and:SI
20650              (zero_extract:SI
20651                (match_operand 2 "ext_register_operand" "")
20652                (const_int 8)
20653                (const_int 8))
20654              (match_operand 3 "const_int_operand" ""))
20655            (const_int 0)]))]
20656   "! TARGET_PARTIAL_REG_STALL
20657    && ix86_match_ccmode (insn, CCNOmode)
20658    && true_regnum (operands[2]) != AX_REG
20659    && peep2_reg_dead_p (1, operands[2])"
20660   [(parallel [(set (match_dup 0)
20661                    (match_op_dup 1
20662                      [(and:SI
20663                         (zero_extract:SI
20664                           (match_dup 2)
20665                           (const_int 8)
20666                           (const_int 8))
20667                         (match_dup 3))
20668                       (const_int 0)]))
20669               (set (zero_extract:SI (match_dup 2)
20670                                     (const_int 8)
20671                                     (const_int 8))
20672                    (and:SI
20673                      (zero_extract:SI
20674                        (match_dup 2)
20675                        (const_int 8)
20676                        (const_int 8))
20677                      (match_dup 3)))])]
20678   "")
20679
20680 ;; Don't do logical operations with memory inputs.
20681 (define_peephole2
20682   [(match_scratch:SI 2 "r")
20683    (parallel [(set (match_operand:SI 0 "register_operand" "")
20684                    (match_operator:SI 3 "arith_or_logical_operator"
20685                      [(match_dup 0)
20686                       (match_operand:SI 1 "memory_operand" "")]))
20687               (clobber (reg:CC FLAGS_REG))])]
20688   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20689   [(set (match_dup 2) (match_dup 1))
20690    (parallel [(set (match_dup 0)
20691                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20692               (clobber (reg:CC FLAGS_REG))])]
20693   "")
20694
20695 (define_peephole2
20696   [(match_scratch:SI 2 "r")
20697    (parallel [(set (match_operand:SI 0 "register_operand" "")
20698                    (match_operator:SI 3 "arith_or_logical_operator"
20699                      [(match_operand:SI 1 "memory_operand" "")
20700                       (match_dup 0)]))
20701               (clobber (reg:CC FLAGS_REG))])]
20702   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20703   [(set (match_dup 2) (match_dup 1))
20704    (parallel [(set (match_dup 0)
20705                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20706               (clobber (reg:CC FLAGS_REG))])]
20707   "")
20708
20709 ; Don't do logical operations with memory outputs
20710 ;
20711 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20712 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20713 ; the same decoder scheduling characteristics as the original.
20714
20715 (define_peephole2
20716   [(match_scratch:SI 2 "r")
20717    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20718                    (match_operator:SI 3 "arith_or_logical_operator"
20719                      [(match_dup 0)
20720                       (match_operand:SI 1 "nonmemory_operand" "")]))
20721               (clobber (reg:CC FLAGS_REG))])]
20722   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20723   [(set (match_dup 2) (match_dup 0))
20724    (parallel [(set (match_dup 2)
20725                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20726               (clobber (reg:CC FLAGS_REG))])
20727    (set (match_dup 0) (match_dup 2))]
20728   "")
20729
20730 (define_peephole2
20731   [(match_scratch:SI 2 "r")
20732    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20733                    (match_operator:SI 3 "arith_or_logical_operator"
20734                      [(match_operand:SI 1 "nonmemory_operand" "")
20735                       (match_dup 0)]))
20736               (clobber (reg:CC FLAGS_REG))])]
20737   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20738   [(set (match_dup 2) (match_dup 0))
20739    (parallel [(set (match_dup 2)
20740                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20741               (clobber (reg:CC FLAGS_REG))])
20742    (set (match_dup 0) (match_dup 2))]
20743   "")
20744
20745 ;; Attempt to always use XOR for zeroing registers.
20746 (define_peephole2
20747   [(set (match_operand 0 "register_operand" "")
20748         (match_operand 1 "const0_operand" ""))]
20749   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20750    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20751    && GENERAL_REG_P (operands[0])
20752    && peep2_regno_dead_p (0, FLAGS_REG)"
20753   [(parallel [(set (match_dup 0) (const_int 0))
20754               (clobber (reg:CC FLAGS_REG))])]
20755 {
20756   operands[0] = gen_lowpart (word_mode, operands[0]);
20757 })
20758
20759 (define_peephole2
20760   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20761         (const_int 0))]
20762   "(GET_MODE (operands[0]) == QImode
20763     || GET_MODE (operands[0]) == HImode)
20764    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20765    && peep2_regno_dead_p (0, FLAGS_REG)"
20766   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20767               (clobber (reg:CC FLAGS_REG))])])
20768
20769 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20770 (define_peephole2
20771   [(set (match_operand 0 "register_operand" "")
20772         (const_int -1))]
20773   "(GET_MODE (operands[0]) == HImode
20774     || GET_MODE (operands[0]) == SImode
20775     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20776    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20777    && peep2_regno_dead_p (0, FLAGS_REG)"
20778   [(parallel [(set (match_dup 0) (const_int -1))
20779               (clobber (reg:CC FLAGS_REG))])]
20780   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20781                               operands[0]);")
20782
20783 ;; Attempt to convert simple leas to adds. These can be created by
20784 ;; move expanders.
20785 (define_peephole2
20786   [(set (match_operand:SI 0 "register_operand" "")
20787         (plus:SI (match_dup 0)
20788                  (match_operand:SI 1 "nonmemory_operand" "")))]
20789   "peep2_regno_dead_p (0, FLAGS_REG)"
20790   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20791               (clobber (reg:CC FLAGS_REG))])]
20792   "")
20793
20794 (define_peephole2
20795   [(set (match_operand:SI 0 "register_operand" "")
20796         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20797                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20798   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20799   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20800               (clobber (reg:CC FLAGS_REG))])]
20801   "operands[2] = gen_lowpart (SImode, operands[2]);")
20802
20803 (define_peephole2
20804   [(set (match_operand:DI 0 "register_operand" "")
20805         (plus:DI (match_dup 0)
20806                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20807   "peep2_regno_dead_p (0, FLAGS_REG)"
20808   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20809               (clobber (reg:CC FLAGS_REG))])]
20810   "")
20811
20812 (define_peephole2
20813   [(set (match_operand:SI 0 "register_operand" "")
20814         (mult:SI (match_dup 0)
20815                  (match_operand:SI 1 "const_int_operand" "")))]
20816   "exact_log2 (INTVAL (operands[1])) >= 0
20817    && peep2_regno_dead_p (0, FLAGS_REG)"
20818   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20819               (clobber (reg:CC FLAGS_REG))])]
20820   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20821
20822 (define_peephole2
20823   [(set (match_operand:DI 0 "register_operand" "")
20824         (mult:DI (match_dup 0)
20825                  (match_operand:DI 1 "const_int_operand" "")))]
20826   "exact_log2 (INTVAL (operands[1])) >= 0
20827    && peep2_regno_dead_p (0, FLAGS_REG)"
20828   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20829               (clobber (reg:CC FLAGS_REG))])]
20830   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20831
20832 (define_peephole2
20833   [(set (match_operand:SI 0 "register_operand" "")
20834         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20835                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20836   "exact_log2 (INTVAL (operands[2])) >= 0
20837    && REGNO (operands[0]) == REGNO (operands[1])
20838    && peep2_regno_dead_p (0, FLAGS_REG)"
20839   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20840               (clobber (reg:CC FLAGS_REG))])]
20841   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20842
20843 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20844 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20845 ;; many CPUs it is also faster, since special hardware to avoid esp
20846 ;; dependencies is present.
20847
20848 ;; While some of these conversions may be done using splitters, we use peepholes
20849 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20850
20851 ;; Convert prologue esp subtractions to push.
20852 ;; We need register to push.  In order to keep verify_flow_info happy we have
20853 ;; two choices
20854 ;; - use scratch and clobber it in order to avoid dependencies
20855 ;; - use already live register
20856 ;; We can't use the second way right now, since there is no reliable way how to
20857 ;; verify that given register is live.  First choice will also most likely in
20858 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20859 ;; call clobbered registers are dead.  We may want to use base pointer as an
20860 ;; alternative when no register is available later.
20861
20862 (define_peephole2
20863   [(match_scratch:SI 0 "r")
20864    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20865               (clobber (reg:CC FLAGS_REG))
20866               (clobber (mem:BLK (scratch)))])]
20867   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20868   [(clobber (match_dup 0))
20869    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20870               (clobber (mem:BLK (scratch)))])])
20871
20872 (define_peephole2
20873   [(match_scratch:SI 0 "r")
20874    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20875               (clobber (reg:CC FLAGS_REG))
20876               (clobber (mem:BLK (scratch)))])]
20877   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20878   [(clobber (match_dup 0))
20879    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20880    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20881               (clobber (mem:BLK (scratch)))])])
20882
20883 ;; Convert esp subtractions to push.
20884 (define_peephole2
20885   [(match_scratch:SI 0 "r")
20886    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20887               (clobber (reg:CC FLAGS_REG))])]
20888   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20889   [(clobber (match_dup 0))
20890    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20891
20892 (define_peephole2
20893   [(match_scratch:SI 0 "r")
20894    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20895               (clobber (reg:CC FLAGS_REG))])]
20896   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20897   [(clobber (match_dup 0))
20898    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20899    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20900
20901 ;; Convert epilogue deallocator to pop.
20902 (define_peephole2
20903   [(match_scratch:SI 0 "r")
20904    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20905               (clobber (reg:CC FLAGS_REG))
20906               (clobber (mem:BLK (scratch)))])]
20907   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20908   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20909               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20910               (clobber (mem:BLK (scratch)))])]
20911   "")
20912
20913 ;; Two pops case is tricky, since pop causes dependency on destination register.
20914 ;; We use two registers if available.
20915 (define_peephole2
20916   [(match_scratch:SI 0 "r")
20917    (match_scratch:SI 1 "r")
20918    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20919               (clobber (reg:CC FLAGS_REG))
20920               (clobber (mem:BLK (scratch)))])]
20921   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20922   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20923               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20924               (clobber (mem:BLK (scratch)))])
20925    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20926               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20927   "")
20928
20929 (define_peephole2
20930   [(match_scratch:SI 0 "r")
20931    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20932               (clobber (reg:CC FLAGS_REG))
20933               (clobber (mem:BLK (scratch)))])]
20934   "optimize_insn_for_size_p ()"
20935   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20936               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20937               (clobber (mem:BLK (scratch)))])
20938    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20939               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20940   "")
20941
20942 ;; Convert esp additions to pop.
20943 (define_peephole2
20944   [(match_scratch:SI 0 "r")
20945    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20946               (clobber (reg:CC FLAGS_REG))])]
20947   ""
20948   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20949               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20950   "")
20951
20952 ;; Two pops case is tricky, since pop causes dependency on destination register.
20953 ;; We use two registers if available.
20954 (define_peephole2
20955   [(match_scratch:SI 0 "r")
20956    (match_scratch:SI 1 "r")
20957    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20958               (clobber (reg:CC FLAGS_REG))])]
20959   ""
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    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20963               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20964   "")
20965
20966 (define_peephole2
20967   [(match_scratch:SI 0 "r")
20968    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20969               (clobber (reg:CC FLAGS_REG))])]
20970   "optimize_insn_for_size_p ()"
20971   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20972               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
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   "")
20976 \f
20977 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20978 ;; required and register dies.  Similarly for 128 to -128.
20979 (define_peephole2
20980   [(set (match_operand 0 "flags_reg_operand" "")
20981         (match_operator 1 "compare_operator"
20982           [(match_operand 2 "register_operand" "")
20983            (match_operand 3 "const_int_operand" "")]))]
20984   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20985      && incdec_operand (operands[3], GET_MODE (operands[3])))
20986     || (!TARGET_FUSE_CMP_AND_BRANCH
20987         && INTVAL (operands[3]) == 128))
20988    && ix86_match_ccmode (insn, CCGCmode)
20989    && peep2_reg_dead_p (1, operands[2])"
20990   [(parallel [(set (match_dup 0)
20991                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20992               (clobber (match_dup 2))])]
20993   "")
20994 \f
20995 (define_peephole2
20996   [(match_scratch:DI 0 "r")
20997    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20998               (clobber (reg:CC FLAGS_REG))
20999               (clobber (mem:BLK (scratch)))])]
21000   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21001   [(clobber (match_dup 0))
21002    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21003               (clobber (mem:BLK (scratch)))])])
21004
21005 (define_peephole2
21006   [(match_scratch:DI 0 "r")
21007    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21008               (clobber (reg:CC FLAGS_REG))
21009               (clobber (mem:BLK (scratch)))])]
21010   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21011   [(clobber (match_dup 0))
21012    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21013    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21014               (clobber (mem:BLK (scratch)))])])
21015
21016 ;; Convert esp subtractions to push.
21017 (define_peephole2
21018   [(match_scratch:DI 0 "r")
21019    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21020               (clobber (reg:CC FLAGS_REG))])]
21021   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21022   [(clobber (match_dup 0))
21023    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21024
21025 (define_peephole2
21026   [(match_scratch:DI 0 "r")
21027    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21028               (clobber (reg:CC FLAGS_REG))])]
21029   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21030   [(clobber (match_dup 0))
21031    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21032    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21033
21034 ;; Convert epilogue deallocator to pop.
21035 (define_peephole2
21036   [(match_scratch:DI 0 "r")
21037    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21038               (clobber (reg:CC FLAGS_REG))
21039               (clobber (mem:BLK (scratch)))])]
21040   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21041   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21042               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21043               (clobber (mem:BLK (scratch)))])]
21044   "")
21045
21046 ;; Two pops case is tricky, since pop causes dependency on destination register.
21047 ;; We use two registers if available.
21048 (define_peephole2
21049   [(match_scratch:DI 0 "r")
21050    (match_scratch:DI 1 "r")
21051    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21052               (clobber (reg:CC FLAGS_REG))
21053               (clobber (mem:BLK (scratch)))])]
21054   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21055   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21056               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21057               (clobber (mem:BLK (scratch)))])
21058    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21059               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21060   "")
21061
21062 (define_peephole2
21063   [(match_scratch:DI 0 "r")
21064    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21065               (clobber (reg:CC FLAGS_REG))
21066               (clobber (mem:BLK (scratch)))])]
21067   "optimize_insn_for_size_p ()"
21068   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21069               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21070               (clobber (mem:BLK (scratch)))])
21071    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21072               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21073   "")
21074
21075 ;; Convert esp additions to pop.
21076 (define_peephole2
21077   [(match_scratch:DI 0 "r")
21078    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21079               (clobber (reg:CC FLAGS_REG))])]
21080   ""
21081   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21082               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21083   "")
21084
21085 ;; Two pops case is tricky, since pop causes dependency on destination register.
21086 ;; We use two registers if available.
21087 (define_peephole2
21088   [(match_scratch:DI 0 "r")
21089    (match_scratch:DI 1 "r")
21090    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21091               (clobber (reg:CC FLAGS_REG))])]
21092   ""
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    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21096               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21097   "")
21098
21099 (define_peephole2
21100   [(match_scratch:DI 0 "r")
21101    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21102               (clobber (reg:CC FLAGS_REG))])]
21103   "optimize_insn_for_size_p ()"
21104   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21105               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
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   "")
21109 \f
21110 ;; Convert imul by three, five and nine into lea
21111 (define_peephole2
21112   [(parallel
21113     [(set (match_operand:SI 0 "register_operand" "")
21114           (mult:SI (match_operand:SI 1 "register_operand" "")
21115                    (match_operand:SI 2 "const_int_operand" "")))
21116      (clobber (reg:CC FLAGS_REG))])]
21117   "INTVAL (operands[2]) == 3
21118    || INTVAL (operands[2]) == 5
21119    || INTVAL (operands[2]) == 9"
21120   [(set (match_dup 0)
21121         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21122                  (match_dup 1)))]
21123   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21124
21125 (define_peephole2
21126   [(parallel
21127     [(set (match_operand:SI 0 "register_operand" "")
21128           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21129                    (match_operand:SI 2 "const_int_operand" "")))
21130      (clobber (reg:CC FLAGS_REG))])]
21131   "optimize_insn_for_speed_p ()
21132    && (INTVAL (operands[2]) == 3
21133        || INTVAL (operands[2]) == 5
21134        || INTVAL (operands[2]) == 9)"
21135   [(set (match_dup 0) (match_dup 1))
21136    (set (match_dup 0)
21137         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21138                  (match_dup 0)))]
21139   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21140
21141 (define_peephole2
21142   [(parallel
21143     [(set (match_operand:DI 0 "register_operand" "")
21144           (mult:DI (match_operand:DI 1 "register_operand" "")
21145                    (match_operand:DI 2 "const_int_operand" "")))
21146      (clobber (reg:CC FLAGS_REG))])]
21147   "TARGET_64BIT
21148    && (INTVAL (operands[2]) == 3
21149        || INTVAL (operands[2]) == 5
21150        || INTVAL (operands[2]) == 9)"
21151   [(set (match_dup 0)
21152         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21153                  (match_dup 1)))]
21154   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21155
21156 (define_peephole2
21157   [(parallel
21158     [(set (match_operand:DI 0 "register_operand" "")
21159           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21160                    (match_operand:DI 2 "const_int_operand" "")))
21161      (clobber (reg:CC FLAGS_REG))])]
21162   "TARGET_64BIT
21163    && optimize_insn_for_speed_p ()
21164    && (INTVAL (operands[2]) == 3
21165        || INTVAL (operands[2]) == 5
21166        || INTVAL (operands[2]) == 9)"
21167   [(set (match_dup 0) (match_dup 1))
21168    (set (match_dup 0)
21169         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21170                  (match_dup 0)))]
21171   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21172
21173 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21174 ;; imul $32bit_imm, reg, reg is direct decoded.
21175 (define_peephole2
21176   [(match_scratch:DI 3 "r")
21177    (parallel [(set (match_operand:DI 0 "register_operand" "")
21178                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21179                             (match_operand:DI 2 "immediate_operand" "")))
21180               (clobber (reg:CC FLAGS_REG))])]
21181   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21182    && !satisfies_constraint_K (operands[2])"
21183   [(set (match_dup 3) (match_dup 1))
21184    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21185               (clobber (reg:CC FLAGS_REG))])]
21186 "")
21187
21188 (define_peephole2
21189   [(match_scratch:SI 3 "r")
21190    (parallel [(set (match_operand:SI 0 "register_operand" "")
21191                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21192                             (match_operand:SI 2 "immediate_operand" "")))
21193               (clobber (reg:CC FLAGS_REG))])]
21194   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21195    && !satisfies_constraint_K (operands[2])"
21196   [(set (match_dup 3) (match_dup 1))
21197    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21198               (clobber (reg:CC FLAGS_REG))])]
21199 "")
21200
21201 (define_peephole2
21202   [(match_scratch:SI 3 "r")
21203    (parallel [(set (match_operand:DI 0 "register_operand" "")
21204                    (zero_extend:DI
21205                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21206                               (match_operand:SI 2 "immediate_operand" ""))))
21207               (clobber (reg:CC FLAGS_REG))])]
21208   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21209    && !satisfies_constraint_K (operands[2])"
21210   [(set (match_dup 3) (match_dup 1))
21211    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21212               (clobber (reg:CC FLAGS_REG))])]
21213 "")
21214
21215 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21216 ;; Convert it into imul reg, reg
21217 ;; It would be better to force assembler to encode instruction using long
21218 ;; immediate, but there is apparently no way to do so.
21219 (define_peephole2
21220   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21221                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21222                             (match_operand:DI 2 "const_int_operand" "")))
21223               (clobber (reg:CC FLAGS_REG))])
21224    (match_scratch:DI 3 "r")]
21225   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21226    && satisfies_constraint_K (operands[2])"
21227   [(set (match_dup 3) (match_dup 2))
21228    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21229               (clobber (reg:CC FLAGS_REG))])]
21230 {
21231   if (!rtx_equal_p (operands[0], operands[1]))
21232     emit_move_insn (operands[0], operands[1]);
21233 })
21234
21235 (define_peephole2
21236   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21237                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21238                             (match_operand:SI 2 "const_int_operand" "")))
21239               (clobber (reg:CC FLAGS_REG))])
21240    (match_scratch:SI 3 "r")]
21241   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21242    && satisfies_constraint_K (operands[2])"
21243   [(set (match_dup 3) (match_dup 2))
21244    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21245               (clobber (reg:CC FLAGS_REG))])]
21246 {
21247   if (!rtx_equal_p (operands[0], operands[1]))
21248     emit_move_insn (operands[0], operands[1]);
21249 })
21250
21251 (define_peephole2
21252   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21253                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21254                             (match_operand:HI 2 "immediate_operand" "")))
21255               (clobber (reg:CC FLAGS_REG))])
21256    (match_scratch:HI 3 "r")]
21257   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21258   [(set (match_dup 3) (match_dup 2))
21259    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21260               (clobber (reg:CC FLAGS_REG))])]
21261 {
21262   if (!rtx_equal_p (operands[0], operands[1]))
21263     emit_move_insn (operands[0], operands[1]);
21264 })
21265
21266 ;; After splitting up read-modify operations, array accesses with memory
21267 ;; operands might end up in form:
21268 ;;  sall    $2, %eax
21269 ;;  movl    4(%esp), %edx
21270 ;;  addl    %edx, %eax
21271 ;; instead of pre-splitting:
21272 ;;  sall    $2, %eax
21273 ;;  addl    4(%esp), %eax
21274 ;; Turn it into:
21275 ;;  movl    4(%esp), %edx
21276 ;;  leal    (%edx,%eax,4), %eax
21277
21278 (define_peephole2
21279   [(parallel [(set (match_operand 0 "register_operand" "")
21280                    (ashift (match_operand 1 "register_operand" "")
21281                            (match_operand 2 "const_int_operand" "")))
21282                (clobber (reg:CC FLAGS_REG))])
21283    (set (match_operand 3 "register_operand")
21284         (match_operand 4 "x86_64_general_operand" ""))
21285    (parallel [(set (match_operand 5 "register_operand" "")
21286                    (plus (match_operand 6 "register_operand" "")
21287                          (match_operand 7 "register_operand" "")))
21288                    (clobber (reg:CC FLAGS_REG))])]
21289   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21290    /* Validate MODE for lea.  */
21291    && ((!TARGET_PARTIAL_REG_STALL
21292         && (GET_MODE (operands[0]) == QImode
21293             || GET_MODE (operands[0]) == HImode))
21294        || GET_MODE (operands[0]) == SImode
21295        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21296    /* We reorder load and the shift.  */
21297    && !rtx_equal_p (operands[1], operands[3])
21298    && !reg_overlap_mentioned_p (operands[0], operands[4])
21299    /* Last PLUS must consist of operand 0 and 3.  */
21300    && !rtx_equal_p (operands[0], operands[3])
21301    && (rtx_equal_p (operands[3], operands[6])
21302        || rtx_equal_p (operands[3], operands[7]))
21303    && (rtx_equal_p (operands[0], operands[6])
21304        || rtx_equal_p (operands[0], operands[7]))
21305    /* The intermediate operand 0 must die or be same as output.  */
21306    && (rtx_equal_p (operands[0], operands[5])
21307        || peep2_reg_dead_p (3, operands[0]))"
21308   [(set (match_dup 3) (match_dup 4))
21309    (set (match_dup 0) (match_dup 1))]
21310 {
21311   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21312   int scale = 1 << INTVAL (operands[2]);
21313   rtx index = gen_lowpart (Pmode, operands[1]);
21314   rtx base = gen_lowpart (Pmode, operands[3]);
21315   rtx dest = gen_lowpart (mode, operands[5]);
21316
21317   operands[1] = gen_rtx_PLUS (Pmode, base,
21318                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21319   if (mode != Pmode)
21320     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21321   operands[0] = dest;
21322 })
21323 \f
21324 ;; Call-value patterns last so that the wildcard operand does not
21325 ;; disrupt insn-recog's switch tables.
21326
21327 (define_insn "*call_value_pop_0"
21328   [(set (match_operand 0 "" "")
21329         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21330               (match_operand:SI 2 "" "")))
21331    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21332                             (match_operand:SI 3 "immediate_operand" "")))]
21333   "!TARGET_64BIT"
21334 {
21335   if (SIBLING_CALL_P (insn))
21336     return "jmp\t%P1";
21337   else
21338     return "call\t%P1";
21339 }
21340   [(set_attr "type" "callv")])
21341
21342 (define_insn "*call_value_pop_1"
21343   [(set (match_operand 0 "" "")
21344         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21345               (match_operand:SI 2 "" "")))
21346    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21347                             (match_operand:SI 3 "immediate_operand" "i")))]
21348   "!TARGET_64BIT"
21349 {
21350   if (constant_call_address_operand (operands[1], Pmode))
21351     {
21352       if (SIBLING_CALL_P (insn))
21353         return "jmp\t%P1";
21354       else
21355         return "call\t%P1";
21356     }
21357   if (SIBLING_CALL_P (insn))
21358     return "jmp\t%A1";
21359   else
21360     return "call\t%A1";
21361 }
21362   [(set_attr "type" "callv")])
21363
21364 (define_insn "*call_value_0"
21365   [(set (match_operand 0 "" "")
21366         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21367               (match_operand:SI 2 "" "")))]
21368   "!TARGET_64BIT"
21369 {
21370   if (SIBLING_CALL_P (insn))
21371     return "jmp\t%P1";
21372   else
21373     return "call\t%P1";
21374 }
21375   [(set_attr "type" "callv")])
21376
21377 (define_insn "*call_value_0_rex64"
21378   [(set (match_operand 0 "" "")
21379         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21380               (match_operand:DI 2 "const_int_operand" "")))]
21381   "TARGET_64BIT"
21382 {
21383   if (SIBLING_CALL_P (insn))
21384     return "jmp\t%P1";
21385   else
21386     return "call\t%P1";
21387 }
21388   [(set_attr "type" "callv")])
21389
21390 (define_insn "*call_value_0_rex64_ms_sysv"
21391   [(set (match_operand 0 "" "")
21392         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21393               (match_operand:DI 2 "const_int_operand" "")))
21394    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21395    (clobber (reg:TI 27))
21396    (clobber (reg:TI 28))
21397    (clobber (reg:TI 45))
21398    (clobber (reg:TI 46))
21399    (clobber (reg:TI 47))
21400    (clobber (reg:TI 48))
21401    (clobber (reg:TI 49))
21402    (clobber (reg:TI 50))
21403    (clobber (reg:TI 51))
21404    (clobber (reg:TI 52))
21405    (clobber (reg:DI SI_REG))
21406    (clobber (reg:DI DI_REG))]
21407   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21408 {
21409   if (SIBLING_CALL_P (insn))
21410     return "jmp\t%P1";
21411   else
21412     return "call\t%P1";
21413 }
21414   [(set_attr "type" "callv")])
21415
21416 (define_insn "*call_value_1"
21417   [(set (match_operand 0 "" "")
21418         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21419               (match_operand:SI 2 "" "")))]
21420   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21421 {
21422   if (constant_call_address_operand (operands[1], Pmode))
21423     return "call\t%P1";
21424   return "call\t%A1";
21425 }
21426   [(set_attr "type" "callv")])
21427
21428 (define_insn "*sibcall_value_1"
21429   [(set (match_operand 0 "" "")
21430         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21431               (match_operand:SI 2 "" "")))]
21432   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21433 {
21434   if (constant_call_address_operand (operands[1], Pmode))
21435     return "jmp\t%P1";
21436   return "jmp\t%A1";
21437 }
21438   [(set_attr "type" "callv")])
21439
21440 (define_insn "*call_value_1_rex64"
21441   [(set (match_operand 0 "" "")
21442         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21443               (match_operand:DI 2 "" "")))]
21444   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21445    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21446 {
21447   if (constant_call_address_operand (operands[1], Pmode))
21448     return "call\t%P1";
21449   return "call\t%A1";
21450 }
21451   [(set_attr "type" "callv")])
21452
21453 (define_insn "*call_value_1_rex64_ms_sysv"
21454   [(set (match_operand 0 "" "")
21455         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21456               (match_operand:DI 2 "" "")))
21457    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21458    (clobber (reg:TI 27))
21459    (clobber (reg:TI 28))
21460    (clobber (reg:TI 45))
21461    (clobber (reg:TI 46))
21462    (clobber (reg:TI 47))
21463    (clobber (reg:TI 48))
21464    (clobber (reg:TI 49))
21465    (clobber (reg:TI 50))
21466    (clobber (reg:TI 51))
21467    (clobber (reg:TI 52))
21468    (clobber (reg:DI SI_REG))
21469    (clobber (reg:DI DI_REG))]
21470   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21471 {
21472   if (constant_call_address_operand (operands[1], Pmode))
21473     return "call\t%P1";
21474   return "call\t%A1";
21475 }
21476   [(set_attr "type" "callv")])
21477
21478 (define_insn "*call_value_1_rex64_large"
21479   [(set (match_operand 0 "" "")
21480         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21481               (match_operand:DI 2 "" "")))]
21482   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21483   "call\t%A1"
21484   [(set_attr "type" "callv")])
21485
21486 (define_insn "*sibcall_value_1_rex64"
21487   [(set (match_operand 0 "" "")
21488         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21489               (match_operand:DI 2 "" "")))]
21490   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21491   "jmp\t%P1"
21492   [(set_attr "type" "callv")])
21493
21494 (define_insn "*sibcall_value_1_rex64_v"
21495   [(set (match_operand 0 "" "")
21496         (call (mem:QI (reg:DI R11_REG))
21497               (match_operand:DI 1 "" "")))]
21498   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21499   "jmp\t{*%%}r11"
21500   [(set_attr "type" "callv")])
21501 \f
21502 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21503 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21504 ;; caught for use by garbage collectors and the like.  Using an insn that
21505 ;; maps to SIGILL makes it more likely the program will rightfully die.
21506 ;; Keeping with tradition, "6" is in honor of #UD.
21507 (define_insn "trap"
21508   [(trap_if (const_int 1) (const_int 6))]
21509   ""
21510   { return ASM_SHORT "0x0b0f"; }
21511   [(set_attr "length" "2")])
21512
21513 (define_expand "sse_prologue_save"
21514   [(parallel [(set (match_operand:BLK 0 "" "")
21515                    (unspec:BLK [(reg:DI 21)
21516                                 (reg:DI 22)
21517                                 (reg:DI 23)
21518                                 (reg:DI 24)
21519                                 (reg:DI 25)
21520                                 (reg:DI 26)
21521                                 (reg:DI 27)
21522                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21523               (use (match_operand:DI 1 "register_operand" ""))
21524               (use (match_operand:DI 2 "immediate_operand" ""))
21525               (use (label_ref:DI (match_operand 3 "" "")))])]
21526   "TARGET_64BIT"
21527   "")
21528
21529 (define_insn "*sse_prologue_save_insn"
21530   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21531                           (match_operand:DI 4 "const_int_operand" "n")))
21532         (unspec:BLK [(reg:DI 21)
21533                      (reg:DI 22)
21534                      (reg:DI 23)
21535                      (reg:DI 24)
21536                      (reg:DI 25)
21537                      (reg:DI 26)
21538                      (reg:DI 27)
21539                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21540    (use (match_operand:DI 1 "register_operand" "r"))
21541    (use (match_operand:DI 2 "const_int_operand" "i"))
21542    (use (label_ref:DI (match_operand 3 "" "X")))]
21543   "TARGET_64BIT
21544    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21545    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21546 {
21547   int i;
21548   operands[0] = gen_rtx_MEM (Pmode,
21549                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21550   /* VEX instruction with a REX prefix will #UD.  */
21551   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21552     gcc_unreachable ();
21553
21554   output_asm_insn ("jmp\t%A1", operands);
21555   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21556     {
21557       operands[4] = adjust_address (operands[0], DImode, i*16);
21558       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21559       PUT_MODE (operands[4], TImode);
21560       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21561         output_asm_insn ("rex", operands);
21562       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21563     }
21564   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21565                                      CODE_LABEL_NUMBER (operands[3]));
21566   return "";
21567 }
21568   [(set_attr "type" "other")
21569    (set_attr "length_immediate" "0")
21570    (set_attr "length_address" "0")
21571    (set (attr "length")
21572      (if_then_else
21573        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21574        (const_string "34")
21575        (const_string "42")))
21576    (set_attr "memory" "store")
21577    (set_attr "modrm" "0")
21578    (set_attr "prefix" "maybe_vex")
21579    (set_attr "mode" "DI")])
21580
21581 (define_expand "prefetch"
21582   [(prefetch (match_operand 0 "address_operand" "")
21583              (match_operand:SI 1 "const_int_operand" "")
21584              (match_operand:SI 2 "const_int_operand" ""))]
21585   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21586 {
21587   int rw = INTVAL (operands[1]);
21588   int locality = INTVAL (operands[2]);
21589
21590   gcc_assert (rw == 0 || rw == 1);
21591   gcc_assert (locality >= 0 && locality <= 3);
21592   gcc_assert (GET_MODE (operands[0]) == Pmode
21593               || GET_MODE (operands[0]) == VOIDmode);
21594
21595   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21596      supported by SSE counterpart or the SSE prefetch is not available
21597      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21598      of locality.  */
21599   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21600     operands[2] = GEN_INT (3);
21601   else
21602     operands[1] = const0_rtx;
21603 })
21604
21605 (define_insn "*prefetch_sse"
21606   [(prefetch (match_operand:SI 0 "address_operand" "p")
21607              (const_int 0)
21608              (match_operand:SI 1 "const_int_operand" ""))]
21609   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21610 {
21611   static const char * const patterns[4] = {
21612    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21613   };
21614
21615   int locality = INTVAL (operands[1]);
21616   gcc_assert (locality >= 0 && locality <= 3);
21617
21618   return patterns[locality];
21619 }
21620   [(set_attr "type" "sse")
21621    (set_attr "memory" "none")])
21622
21623 (define_insn "*prefetch_sse_rex"
21624   [(prefetch (match_operand:DI 0 "address_operand" "p")
21625              (const_int 0)
21626              (match_operand:SI 1 "const_int_operand" ""))]
21627   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21628 {
21629   static const char * const patterns[4] = {
21630    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21631   };
21632
21633   int locality = INTVAL (operands[1]);
21634   gcc_assert (locality >= 0 && locality <= 3);
21635
21636   return patterns[locality];
21637 }
21638   [(set_attr "type" "sse")
21639    (set_attr "memory" "none")])
21640
21641 (define_insn "*prefetch_3dnow"
21642   [(prefetch (match_operand:SI 0 "address_operand" "p")
21643              (match_operand:SI 1 "const_int_operand" "n")
21644              (const_int 3))]
21645   "TARGET_3DNOW && !TARGET_64BIT"
21646 {
21647   if (INTVAL (operands[1]) == 0)
21648     return "prefetch\t%a0";
21649   else
21650     return "prefetchw\t%a0";
21651 }
21652   [(set_attr "type" "mmx")
21653    (set_attr "memory" "none")])
21654
21655 (define_insn "*prefetch_3dnow_rex"
21656   [(prefetch (match_operand:DI 0 "address_operand" "p")
21657              (match_operand:SI 1 "const_int_operand" "n")
21658              (const_int 3))]
21659   "TARGET_3DNOW && TARGET_64BIT"
21660 {
21661   if (INTVAL (operands[1]) == 0)
21662     return "prefetch\t%a0";
21663   else
21664     return "prefetchw\t%a0";
21665 }
21666   [(set_attr "type" "mmx")
21667    (set_attr "memory" "none")])
21668
21669 (define_expand "stack_protect_set"
21670   [(match_operand 0 "memory_operand" "")
21671    (match_operand 1 "memory_operand" "")]
21672   ""
21673 {
21674 #ifdef TARGET_THREAD_SSP_OFFSET
21675   if (TARGET_64BIT)
21676     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21677                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21678   else
21679     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21680                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21681 #else
21682   if (TARGET_64BIT)
21683     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21684   else
21685     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21686 #endif
21687   DONE;
21688 })
21689
21690 (define_insn "stack_protect_set_si"
21691   [(set (match_operand:SI 0 "memory_operand" "=m")
21692         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21693    (set (match_scratch:SI 2 "=&r") (const_int 0))
21694    (clobber (reg:CC FLAGS_REG))]
21695   ""
21696   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21697   [(set_attr "type" "multi")])
21698
21699 (define_insn "stack_protect_set_di"
21700   [(set (match_operand:DI 0 "memory_operand" "=m")
21701         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21702    (set (match_scratch:DI 2 "=&r") (const_int 0))
21703    (clobber (reg:CC FLAGS_REG))]
21704   "TARGET_64BIT"
21705   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21706   [(set_attr "type" "multi")])
21707
21708 (define_insn "stack_tls_protect_set_si"
21709   [(set (match_operand:SI 0 "memory_operand" "=m")
21710         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21711    (set (match_scratch:SI 2 "=&r") (const_int 0))
21712    (clobber (reg:CC FLAGS_REG))]
21713   ""
21714   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21715   [(set_attr "type" "multi")])
21716
21717 (define_insn "stack_tls_protect_set_di"
21718   [(set (match_operand:DI 0 "memory_operand" "=m")
21719         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21720    (set (match_scratch:DI 2 "=&r") (const_int 0))
21721    (clobber (reg:CC FLAGS_REG))]
21722   "TARGET_64BIT"
21723   {
21724      /* The kernel uses a different segment register for performance reasons; a
21725         system call would not have to trash the userspace segment register,
21726         which would be expensive */
21727      if (ix86_cmodel != CM_KERNEL)
21728         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21729      else
21730         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21731   }
21732   [(set_attr "type" "multi")])
21733
21734 (define_expand "stack_protect_test"
21735   [(match_operand 0 "memory_operand" "")
21736    (match_operand 1 "memory_operand" "")
21737    (match_operand 2 "" "")]
21738   ""
21739 {
21740   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21741   ix86_compare_op0 = operands[0];
21742   ix86_compare_op1 = operands[1];
21743   ix86_compare_emitted = flags;
21744
21745 #ifdef TARGET_THREAD_SSP_OFFSET
21746   if (TARGET_64BIT)
21747     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21748                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21749   else
21750     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21751                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21752 #else
21753   if (TARGET_64BIT)
21754     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21755   else
21756     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21757 #endif
21758   emit_jump_insn (gen_beq (operands[2]));
21759   DONE;
21760 })
21761
21762 (define_insn "stack_protect_test_si"
21763   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21764         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21765                      (match_operand:SI 2 "memory_operand" "m")]
21766                     UNSPEC_SP_TEST))
21767    (clobber (match_scratch:SI 3 "=&r"))]
21768   ""
21769   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21770   [(set_attr "type" "multi")])
21771
21772 (define_insn "stack_protect_test_di"
21773   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21774         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21775                      (match_operand:DI 2 "memory_operand" "m")]
21776                     UNSPEC_SP_TEST))
21777    (clobber (match_scratch:DI 3 "=&r"))]
21778   "TARGET_64BIT"
21779   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21780   [(set_attr "type" "multi")])
21781
21782 (define_insn "stack_tls_protect_test_si"
21783   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21784         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21785                      (match_operand:SI 2 "const_int_operand" "i")]
21786                     UNSPEC_SP_TLS_TEST))
21787    (clobber (match_scratch:SI 3 "=r"))]
21788   ""
21789   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21790   [(set_attr "type" "multi")])
21791
21792 (define_insn "stack_tls_protect_test_di"
21793   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21794         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21795                      (match_operand:DI 2 "const_int_operand" "i")]
21796                     UNSPEC_SP_TLS_TEST))
21797    (clobber (match_scratch:DI 3 "=r"))]
21798   "TARGET_64BIT"
21799   {
21800      /* The kernel uses a different segment register for performance reasons; a
21801         system call would not have to trash the userspace segment register,
21802         which would be expensive */
21803      if (ix86_cmodel != CM_KERNEL)
21804         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21805      else
21806         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21807   }
21808   [(set_attr "type" "multi")])
21809
21810 (define_mode_iterator CRC32MODE [QI HI SI])
21811 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21812 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21813
21814 (define_insn "sse4_2_crc32<mode>"
21815   [(set (match_operand:SI 0 "register_operand" "=r")
21816         (unspec:SI
21817           [(match_operand:SI 1 "register_operand" "0")
21818            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21819           UNSPEC_CRC32))]
21820   "TARGET_SSE4_2"
21821   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21822   [(set_attr "type" "sselog1")
21823    (set_attr "prefix_rep" "1")
21824    (set_attr "prefix_extra" "1")
21825    (set_attr "mode" "SI")])
21826
21827 (define_insn "sse4_2_crc32di"
21828   [(set (match_operand:DI 0 "register_operand" "=r")
21829         (unspec:DI
21830           [(match_operand:DI 1 "register_operand" "0")
21831            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21832           UNSPEC_CRC32))]
21833   "TARGET_SSE4_2 && TARGET_64BIT"
21834   "crc32q\t{%2, %0|%0, %2}"
21835   [(set_attr "type" "sselog1")
21836    (set_attr "prefix_rep" "1")
21837    (set_attr "prefix_extra" "1")
21838    (set_attr "mode" "DI")])
21839
21840 (include "mmx.md")
21841 (include "sse.md")
21842 (include "sync.md")