OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; '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_MMXADD:
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 "mmxadd")
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_MMXADD:
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 "mmxadd")
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:DI SI_REG))
15047    (clobber (reg:DI DI_REG))]
15048   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15049 {
15050   if (constant_call_address_operand (operands[0], Pmode))
15051     return "call\t%P0";
15052   return "call\t%A0";
15053 }
15054   [(set_attr "type" "call")])
15055
15056 (define_insn "*call_1_rex64_large"
15057   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15058          (match_operand 1 "" ""))]
15059   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15060   "call\t%A0"
15061   [(set_attr "type" "call")])
15062
15063 (define_insn "*sibcall_1_rex64"
15064   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15065          (match_operand 1 "" ""))]
15066   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15067   "jmp\t%P0"
15068   [(set_attr "type" "call")])
15069
15070 (define_insn "*sibcall_1_rex64_v"
15071   [(call (mem:QI (reg:DI R11_REG))
15072          (match_operand 0 "" ""))]
15073   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15074   "jmp\t{*%%}r11"
15075   [(set_attr "type" "call")])
15076
15077
15078 ;; Call subroutine, returning value in operand 0
15079
15080 (define_expand "call_value_pop"
15081   [(parallel [(set (match_operand 0 "" "")
15082                    (call (match_operand:QI 1 "" "")
15083                          (match_operand:SI 2 "" "")))
15084               (set (reg:SI SP_REG)
15085                    (plus:SI (reg:SI SP_REG)
15086                             (match_operand:SI 4 "" "")))])]
15087   "!TARGET_64BIT"
15088 {
15089   ix86_expand_call (operands[0], operands[1], operands[2],
15090                     operands[3], operands[4], 0);
15091   DONE;
15092 })
15093
15094 (define_expand "call_value"
15095   [(set (match_operand 0 "" "")
15096         (call (match_operand:QI 1 "" "")
15097               (match_operand:SI 2 "" "")))
15098    (use (match_operand:SI 3 "" ""))]
15099   ;; Operand 2 not used on the i386.
15100   ""
15101 {
15102   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15103   DONE;
15104 })
15105
15106 (define_expand "sibcall_value"
15107   [(set (match_operand 0 "" "")
15108         (call (match_operand:QI 1 "" "")
15109               (match_operand:SI 2 "" "")))
15110    (use (match_operand:SI 3 "" ""))]
15111   ;; Operand 2 not used on the i386.
15112   ""
15113 {
15114   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15115   DONE;
15116 })
15117
15118 ;; Call subroutine returning any type.
15119
15120 (define_expand "untyped_call"
15121   [(parallel [(call (match_operand 0 "" "")
15122                     (const_int 0))
15123               (match_operand 1 "" "")
15124               (match_operand 2 "" "")])]
15125   ""
15126 {
15127   int i;
15128
15129   /* In order to give reg-stack an easier job in validating two
15130      coprocessor registers as containing a possible return value,
15131      simply pretend the untyped call returns a complex long double
15132      value.  */
15133
15134   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15135                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15136                     operands[0], const0_rtx,
15137                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15138                                                       : X64_SSE_REGPARM_MAX)
15139                              - 1),
15140                     NULL, 0);
15141
15142   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15143     {
15144       rtx set = XVECEXP (operands[2], 0, i);
15145       emit_move_insn (SET_DEST (set), SET_SRC (set));
15146     }
15147
15148   /* The optimizer does not know that the call sets the function value
15149      registers we stored in the result block.  We avoid problems by
15150      claiming that all hard registers are used and clobbered at this
15151      point.  */
15152   emit_insn (gen_blockage ());
15153
15154   DONE;
15155 })
15156 \f
15157 ;; Prologue and epilogue instructions
15158
15159 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15160 ;; all of memory.  This blocks insns from being moved across this point.
15161
15162 (define_insn "blockage"
15163   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15164   ""
15165   ""
15166   [(set_attr "length" "0")])
15167
15168 ;; As USE insns aren't meaningful after reload, this is used instead
15169 ;; to prevent deleting instructions setting registers for PIC code
15170 (define_insn "prologue_use"
15171   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15172   ""
15173   ""
15174   [(set_attr "length" "0")])
15175
15176 ;; Insn emitted into the body of a function to return from a function.
15177 ;; This is only done if the function's epilogue is known to be simple.
15178 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15179
15180 (define_expand "return"
15181   [(return)]
15182   "ix86_can_use_return_insn_p ()"
15183 {
15184   if (crtl->args.pops_args)
15185     {
15186       rtx popc = GEN_INT (crtl->args.pops_args);
15187       emit_jump_insn (gen_return_pop_internal (popc));
15188       DONE;
15189     }
15190 })
15191
15192 (define_insn "return_internal"
15193   [(return)]
15194   "reload_completed"
15195   "ret"
15196   [(set_attr "length" "1")
15197    (set_attr "length_immediate" "0")
15198    (set_attr "modrm" "0")])
15199
15200 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15201 ;; instruction Athlon and K8 have.
15202
15203 (define_insn "return_internal_long"
15204   [(return)
15205    (unspec [(const_int 0)] UNSPEC_REP)]
15206   "reload_completed"
15207   "rep\;ret"
15208   [(set_attr "length" "1")
15209    (set_attr "length_immediate" "0")
15210    (set_attr "prefix_rep" "1")
15211    (set_attr "modrm" "0")])
15212
15213 (define_insn "return_pop_internal"
15214   [(return)
15215    (use (match_operand:SI 0 "const_int_operand" ""))]
15216   "reload_completed"
15217   "ret\t%0"
15218   [(set_attr "length" "3")
15219    (set_attr "length_immediate" "2")
15220    (set_attr "modrm" "0")])
15221
15222 (define_insn "return_indirect_internal"
15223   [(return)
15224    (use (match_operand:SI 0 "register_operand" "r"))]
15225   "reload_completed"
15226   "jmp\t%A0"
15227   [(set_attr "type" "ibr")
15228    (set_attr "length_immediate" "0")])
15229
15230 (define_insn "nop"
15231   [(const_int 0)]
15232   ""
15233   "nop"
15234   [(set_attr "length" "1")
15235    (set_attr "length_immediate" "0")
15236    (set_attr "modrm" "0")])
15237
15238 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15239 ;; branch prediction penalty for the third jump in a 16-byte
15240 ;; block on K8.
15241
15242 (define_insn "align"
15243   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15244   ""
15245 {
15246 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15247   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15248 #else
15249   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15250      The align insn is used to avoid 3 jump instructions in the row to improve
15251      branch prediction and the benefits hardly outweigh the cost of extra 8
15252      nops on the average inserted by full alignment pseudo operation.  */
15253 #endif
15254   return "";
15255 }
15256   [(set_attr "length" "16")])
15257
15258 (define_expand "prologue"
15259   [(const_int 0)]
15260   ""
15261   "ix86_expand_prologue (); DONE;")
15262
15263 (define_insn "set_got"
15264   [(set (match_operand:SI 0 "register_operand" "=r")
15265         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15266    (clobber (reg:CC FLAGS_REG))]
15267   "!TARGET_64BIT"
15268   { return output_set_got (operands[0], NULL_RTX); }
15269   [(set_attr "type" "multi")
15270    (set_attr "length" "12")])
15271
15272 (define_insn "set_got_labelled"
15273   [(set (match_operand:SI 0 "register_operand" "=r")
15274         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15275          UNSPEC_SET_GOT))
15276    (clobber (reg:CC FLAGS_REG))]
15277   "!TARGET_64BIT"
15278   { return output_set_got (operands[0], operands[1]); }
15279   [(set_attr "type" "multi")
15280    (set_attr "length" "12")])
15281
15282 (define_insn "set_got_rex64"
15283   [(set (match_operand:DI 0 "register_operand" "=r")
15284         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15285   "TARGET_64BIT"
15286   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15287   [(set_attr "type" "lea")
15288    (set_attr "length" "6")])
15289
15290 (define_insn "set_rip_rex64"
15291   [(set (match_operand:DI 0 "register_operand" "=r")
15292         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15293   "TARGET_64BIT"
15294   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15295   [(set_attr "type" "lea")
15296    (set_attr "length" "6")])
15297
15298 (define_insn "set_got_offset_rex64"
15299   [(set (match_operand:DI 0 "register_operand" "=r")
15300         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15301   "TARGET_64BIT"
15302   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15303   [(set_attr "type" "imov")
15304    (set_attr "length" "11")])
15305
15306 (define_expand "epilogue"
15307   [(const_int 0)]
15308   ""
15309   "ix86_expand_epilogue (1); DONE;")
15310
15311 (define_expand "sibcall_epilogue"
15312   [(const_int 0)]
15313   ""
15314   "ix86_expand_epilogue (0); DONE;")
15315
15316 (define_expand "eh_return"
15317   [(use (match_operand 0 "register_operand" ""))]
15318   ""
15319 {
15320   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15321
15322   /* Tricky bit: we write the address of the handler to which we will
15323      be returning into someone else's stack frame, one word below the
15324      stack address we wish to restore.  */
15325   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15326   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15327   tmp = gen_rtx_MEM (Pmode, tmp);
15328   emit_move_insn (tmp, ra);
15329
15330   if (Pmode == SImode)
15331     emit_jump_insn (gen_eh_return_si (sa));
15332   else
15333     emit_jump_insn (gen_eh_return_di (sa));
15334   emit_barrier ();
15335   DONE;
15336 })
15337
15338 (define_insn_and_split "eh_return_<mode>"
15339   [(set (pc)
15340         (unspec [(match_operand:P 0 "register_operand" "c")]
15341                  UNSPEC_EH_RETURN))]
15342   ""
15343   "#"
15344   "reload_completed"
15345   [(const_int 0)]
15346   "ix86_expand_epilogue (2); DONE;")
15347
15348 (define_insn "leave"
15349   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15350    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15351    (clobber (mem:BLK (scratch)))]
15352   "!TARGET_64BIT"
15353   "leave"
15354   [(set_attr "type" "leave")])
15355
15356 (define_insn "leave_rex64"
15357   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15358    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15359    (clobber (mem:BLK (scratch)))]
15360   "TARGET_64BIT"
15361   "leave"
15362   [(set_attr "type" "leave")])
15363 \f
15364 (define_expand "ffssi2"
15365   [(parallel
15366      [(set (match_operand:SI 0 "register_operand" "")
15367            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15368       (clobber (match_scratch:SI 2 ""))
15369       (clobber (reg:CC FLAGS_REG))])]
15370   ""
15371 {
15372   if (TARGET_CMOVE)
15373     {
15374       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15375       DONE;
15376     }
15377 })
15378
15379 (define_expand "ffs_cmove"
15380   [(set (match_dup 2) (const_int -1))
15381    (parallel [(set (reg:CCZ FLAGS_REG)
15382                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15383                                 (const_int 0)))
15384               (set (match_operand:SI 0 "register_operand" "")
15385                    (ctz:SI (match_dup 1)))])
15386    (set (match_dup 0) (if_then_else:SI
15387                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15388                         (match_dup 2)
15389                         (match_dup 0)))
15390    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15391               (clobber (reg:CC FLAGS_REG))])]
15392   "TARGET_CMOVE"
15393   "operands[2] = gen_reg_rtx (SImode);")
15394
15395 (define_insn_and_split "*ffs_no_cmove"
15396   [(set (match_operand:SI 0 "register_operand" "=r")
15397         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15398    (clobber (match_scratch:SI 2 "=&q"))
15399    (clobber (reg:CC FLAGS_REG))]
15400   "!TARGET_CMOVE"
15401   "#"
15402   "&& reload_completed"
15403   [(parallel [(set (reg:CCZ FLAGS_REG)
15404                    (compare:CCZ (match_dup 1) (const_int 0)))
15405               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15406    (set (strict_low_part (match_dup 3))
15407         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15408    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15409               (clobber (reg:CC FLAGS_REG))])
15410    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15411               (clobber (reg:CC FLAGS_REG))])
15412    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15413               (clobber (reg:CC FLAGS_REG))])]
15414 {
15415   operands[3] = gen_lowpart (QImode, operands[2]);
15416   ix86_expand_clear (operands[2]);
15417 })
15418
15419 (define_insn "*ffssi_1"
15420   [(set (reg:CCZ FLAGS_REG)
15421         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15422                      (const_int 0)))
15423    (set (match_operand:SI 0 "register_operand" "=r")
15424         (ctz:SI (match_dup 1)))]
15425   ""
15426   "bsf{l}\t{%1, %0|%0, %1}"
15427   [(set_attr "prefix_0f" "1")])
15428
15429 (define_expand "ffsdi2"
15430   [(set (match_dup 2) (const_int -1))
15431    (parallel [(set (reg:CCZ FLAGS_REG)
15432                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15433                                 (const_int 0)))
15434               (set (match_operand:DI 0 "register_operand" "")
15435                    (ctz:DI (match_dup 1)))])
15436    (set (match_dup 0) (if_then_else:DI
15437                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15438                         (match_dup 2)
15439                         (match_dup 0)))
15440    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15441               (clobber (reg:CC FLAGS_REG))])]
15442   "TARGET_64BIT"
15443   "operands[2] = gen_reg_rtx (DImode);")
15444
15445 (define_insn "*ffsdi_1"
15446   [(set (reg:CCZ FLAGS_REG)
15447         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15448                      (const_int 0)))
15449    (set (match_operand:DI 0 "register_operand" "=r")
15450         (ctz:DI (match_dup 1)))]
15451   "TARGET_64BIT"
15452   "bsf{q}\t{%1, %0|%0, %1}"
15453   [(set_attr "prefix_0f" "1")])
15454
15455 (define_insn "ctzsi2"
15456   [(set (match_operand:SI 0 "register_operand" "=r")
15457         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15458    (clobber (reg:CC FLAGS_REG))]
15459   ""
15460   "bsf{l}\t{%1, %0|%0, %1}"
15461   [(set_attr "prefix_0f" "1")])
15462
15463 (define_insn "ctzdi2"
15464   [(set (match_operand:DI 0 "register_operand" "=r")
15465         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15466    (clobber (reg:CC FLAGS_REG))]
15467   "TARGET_64BIT"
15468   "bsf{q}\t{%1, %0|%0, %1}"
15469   [(set_attr "prefix_0f" "1")])
15470
15471 (define_expand "clzsi2"
15472   [(parallel
15473      [(set (match_operand:SI 0 "register_operand" "")
15474            (minus:SI (const_int 31)
15475                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15476       (clobber (reg:CC FLAGS_REG))])
15477    (parallel
15478      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15479       (clobber (reg:CC FLAGS_REG))])]
15480   ""
15481 {
15482   if (TARGET_ABM)
15483     {
15484       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15485       DONE;
15486     }
15487 })
15488
15489 (define_insn "clzsi2_abm"
15490   [(set (match_operand:SI 0 "register_operand" "=r")
15491         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15492    (clobber (reg:CC FLAGS_REG))]
15493   "TARGET_ABM"
15494   "lzcnt{l}\t{%1, %0|%0, %1}"
15495   [(set_attr "prefix_rep" "1")
15496    (set_attr "type" "bitmanip")
15497    (set_attr "mode" "SI")])
15498
15499 (define_insn "*bsr"
15500   [(set (match_operand:SI 0 "register_operand" "=r")
15501         (minus:SI (const_int 31)
15502                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15503    (clobber (reg:CC FLAGS_REG))]
15504   ""
15505   "bsr{l}\t{%1, %0|%0, %1}"
15506   [(set_attr "prefix_0f" "1")
15507    (set_attr "mode" "SI")])
15508
15509 (define_insn "popcount<mode>2"
15510   [(set (match_operand:SWI248 0 "register_operand" "=r")
15511         (popcount:SWI248
15512           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15513    (clobber (reg:CC FLAGS_REG))]
15514   "TARGET_POPCNT"
15515 {
15516 #if TARGET_MACHO
15517   return "popcnt\t{%1, %0|%0, %1}";
15518 #else
15519   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15520 #endif
15521 }
15522   [(set_attr "prefix_rep" "1")
15523    (set_attr "type" "bitmanip")
15524    (set_attr "mode" "<MODE>")])
15525
15526 (define_insn "*popcount<mode>2_cmp"
15527   [(set (reg FLAGS_REG)
15528         (compare
15529           (popcount:SWI248
15530             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15531           (const_int 0)))
15532    (set (match_operand:SWI248 0 "register_operand" "=r")
15533         (popcount:SWI248 (match_dup 1)))]
15534   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15535 {
15536 #if TARGET_MACHO
15537   return "popcnt\t{%1, %0|%0, %1}";
15538 #else
15539   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15540 #endif
15541 }
15542   [(set_attr "prefix_rep" "1")
15543    (set_attr "type" "bitmanip")
15544    (set_attr "mode" "<MODE>")])
15545
15546 (define_insn "*popcountsi2_cmp_zext"
15547   [(set (reg FLAGS_REG)
15548         (compare
15549           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15550           (const_int 0)))
15551    (set (match_operand:DI 0 "register_operand" "=r")
15552         (zero_extend:DI(popcount:SI (match_dup 1))))]
15553   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15554 {
15555 #if TARGET_MACHO
15556   return "popcnt\t{%1, %0|%0, %1}";
15557 #else
15558   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15559 #endif
15560 }
15561   [(set_attr "prefix_rep" "1")
15562    (set_attr "type" "bitmanip")
15563    (set_attr "mode" "SI")])
15564
15565 (define_expand "bswapsi2"
15566   [(set (match_operand:SI 0 "register_operand" "")
15567         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15568   ""
15569 {
15570   if (!TARGET_BSWAP)
15571     {
15572       rtx x = operands[0];
15573
15574       emit_move_insn (x, operands[1]);
15575       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15576       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15577       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15578       DONE;
15579     }
15580 })
15581
15582 (define_insn "*bswapsi_1"
15583   [(set (match_operand:SI 0 "register_operand" "=r")
15584         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15585   "TARGET_BSWAP"
15586   "bswap\t%0"
15587   [(set_attr "prefix_0f" "1")
15588    (set_attr "length" "2")])
15589
15590 (define_insn "*bswaphi_lowpart_1"
15591   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15592         (bswap:HI (match_dup 0)))
15593    (clobber (reg:CC FLAGS_REG))]
15594   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15595   "@
15596     xchg{b}\t{%h0, %b0|%b0, %h0}
15597     rol{w}\t{$8, %0|%0, 8}"
15598   [(set_attr "length" "2,4")
15599    (set_attr "mode" "QI,HI")])
15600
15601 (define_insn "bswaphi_lowpart"
15602   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15603         (bswap:HI (match_dup 0)))
15604    (clobber (reg:CC FLAGS_REG))]
15605   ""
15606   "rol{w}\t{$8, %0|%0, 8}"
15607   [(set_attr "length" "4")
15608    (set_attr "mode" "HI")])
15609
15610 (define_insn "bswapdi2"
15611   [(set (match_operand:DI 0 "register_operand" "=r")
15612         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15613   "TARGET_64BIT"
15614   "bswap\t%0"
15615   [(set_attr "prefix_0f" "1")
15616    (set_attr "length" "3")])
15617
15618 (define_expand "clzdi2"
15619   [(parallel
15620      [(set (match_operand:DI 0 "register_operand" "")
15621            (minus:DI (const_int 63)
15622                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15623       (clobber (reg:CC FLAGS_REG))])
15624    (parallel
15625      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15626       (clobber (reg:CC FLAGS_REG))])]
15627   "TARGET_64BIT"
15628 {
15629   if (TARGET_ABM)
15630     {
15631       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15632       DONE;
15633     }
15634 })
15635
15636 (define_insn "clzdi2_abm"
15637   [(set (match_operand:DI 0 "register_operand" "=r")
15638         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15639    (clobber (reg:CC FLAGS_REG))]
15640   "TARGET_64BIT && TARGET_ABM"
15641   "lzcnt{q}\t{%1, %0|%0, %1}"
15642   [(set_attr "prefix_rep" "1")
15643    (set_attr "type" "bitmanip")
15644    (set_attr "mode" "DI")])
15645
15646 (define_insn "*bsr_rex64"
15647   [(set (match_operand:DI 0 "register_operand" "=r")
15648         (minus:DI (const_int 63)
15649                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15650    (clobber (reg:CC FLAGS_REG))]
15651   "TARGET_64BIT"
15652   "bsr{q}\t{%1, %0|%0, %1}"
15653   [(set_attr "prefix_0f" "1")
15654    (set_attr "mode" "DI")])
15655
15656 (define_expand "clzhi2"
15657   [(parallel
15658      [(set (match_operand:HI 0 "register_operand" "")
15659            (minus:HI (const_int 15)
15660                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15661       (clobber (reg:CC FLAGS_REG))])
15662    (parallel
15663      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15664       (clobber (reg:CC FLAGS_REG))])]
15665   ""
15666 {
15667   if (TARGET_ABM)
15668     {
15669       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15670       DONE;
15671     }
15672 })
15673
15674 (define_insn "clzhi2_abm"
15675   [(set (match_operand:HI 0 "register_operand" "=r")
15676         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15677    (clobber (reg:CC FLAGS_REG))]
15678   "TARGET_ABM"
15679   "lzcnt{w}\t{%1, %0|%0, %1}"
15680   [(set_attr "prefix_rep" "1")
15681    (set_attr "type" "bitmanip")
15682    (set_attr "mode" "HI")])
15683
15684 (define_insn "*bsrhi"
15685   [(set (match_operand:HI 0 "register_operand" "=r")
15686         (minus:HI (const_int 15)
15687                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15688    (clobber (reg:CC FLAGS_REG))]
15689   ""
15690   "bsr{w}\t{%1, %0|%0, %1}"
15691   [(set_attr "prefix_0f" "1")
15692    (set_attr "mode" "HI")])
15693
15694 (define_expand "paritydi2"
15695   [(set (match_operand:DI 0 "register_operand" "")
15696         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15697   "! TARGET_POPCNT"
15698 {
15699   rtx scratch = gen_reg_rtx (QImode);
15700   rtx cond;
15701
15702   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15703                                 NULL_RTX, operands[1]));
15704
15705   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15706                          gen_rtx_REG (CCmode, FLAGS_REG),
15707                          const0_rtx);
15708   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15709
15710   if (TARGET_64BIT)
15711     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15712   else
15713     {
15714       rtx tmp = gen_reg_rtx (SImode);
15715
15716       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15717       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15718     }
15719   DONE;
15720 })
15721
15722 (define_insn_and_split "paritydi2_cmp"
15723   [(set (reg:CC FLAGS_REG)
15724         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15725    (clobber (match_scratch:DI 0 "=r"))
15726    (clobber (match_scratch:SI 1 "=&r"))
15727    (clobber (match_scratch:HI 2 "=Q"))]
15728   "! TARGET_POPCNT"
15729   "#"
15730   "&& reload_completed"
15731   [(parallel
15732      [(set (match_dup 1)
15733            (xor:SI (match_dup 1) (match_dup 4)))
15734       (clobber (reg:CC FLAGS_REG))])
15735    (parallel
15736      [(set (reg:CC FLAGS_REG)
15737            (parity:CC (match_dup 1)))
15738       (clobber (match_dup 1))
15739       (clobber (match_dup 2))])]
15740 {
15741   operands[4] = gen_lowpart (SImode, operands[3]);
15742
15743   if (TARGET_64BIT)
15744     {
15745       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15746       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15747     }
15748   else
15749     operands[1] = gen_highpart (SImode, operands[3]);
15750 })
15751
15752 (define_expand "paritysi2"
15753   [(set (match_operand:SI 0 "register_operand" "")
15754         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15755   "! TARGET_POPCNT"
15756 {
15757   rtx scratch = gen_reg_rtx (QImode);
15758   rtx cond;
15759
15760   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15761
15762   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15763                          gen_rtx_REG (CCmode, FLAGS_REG),
15764                          const0_rtx);
15765   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15766
15767   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15768   DONE;
15769 })
15770
15771 (define_insn_and_split "paritysi2_cmp"
15772   [(set (reg:CC FLAGS_REG)
15773         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15774    (clobber (match_scratch:SI 0 "=r"))
15775    (clobber (match_scratch:HI 1 "=&Q"))]
15776   "! TARGET_POPCNT"
15777   "#"
15778   "&& reload_completed"
15779   [(parallel
15780      [(set (match_dup 1)
15781            (xor:HI (match_dup 1) (match_dup 3)))
15782       (clobber (reg:CC FLAGS_REG))])
15783    (parallel
15784      [(set (reg:CC FLAGS_REG)
15785            (parity:CC (match_dup 1)))
15786       (clobber (match_dup 1))])]
15787 {
15788   operands[3] = gen_lowpart (HImode, operands[2]);
15789
15790   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15791   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15792 })
15793
15794 (define_insn "*parityhi2_cmp"
15795   [(set (reg:CC FLAGS_REG)
15796         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15797    (clobber (match_scratch:HI 0 "=Q"))]
15798   "! TARGET_POPCNT"
15799   "xor{b}\t{%h0, %b0|%b0, %h0}"
15800   [(set_attr "length" "2")
15801    (set_attr "mode" "HI")])
15802
15803 (define_insn "*parityqi2_cmp"
15804   [(set (reg:CC FLAGS_REG)
15805         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15806   "! TARGET_POPCNT"
15807   "test{b}\t%0, %0"
15808   [(set_attr "length" "2")
15809    (set_attr "mode" "QI")])
15810 \f
15811 ;; Thread-local storage patterns for ELF.
15812 ;;
15813 ;; Note that these code sequences must appear exactly as shown
15814 ;; in order to allow linker relaxation.
15815
15816 (define_insn "*tls_global_dynamic_32_gnu"
15817   [(set (match_operand:SI 0 "register_operand" "=a")
15818         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15819                     (match_operand:SI 2 "tls_symbolic_operand" "")
15820                     (match_operand:SI 3 "call_insn_operand" "")]
15821                     UNSPEC_TLS_GD))
15822    (clobber (match_scratch:SI 4 "=d"))
15823    (clobber (match_scratch:SI 5 "=c"))
15824    (clobber (reg:CC FLAGS_REG))]
15825   "!TARGET_64BIT && TARGET_GNU_TLS"
15826   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15827   [(set_attr "type" "multi")
15828    (set_attr "length" "12")])
15829
15830 (define_insn "*tls_global_dynamic_32_sun"
15831   [(set (match_operand:SI 0 "register_operand" "=a")
15832         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15833                     (match_operand:SI 2 "tls_symbolic_operand" "")
15834                     (match_operand:SI 3 "call_insn_operand" "")]
15835                     UNSPEC_TLS_GD))
15836    (clobber (match_scratch:SI 4 "=d"))
15837    (clobber (match_scratch:SI 5 "=c"))
15838    (clobber (reg:CC FLAGS_REG))]
15839   "!TARGET_64BIT && TARGET_SUN_TLS"
15840   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15841         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15842   [(set_attr "type" "multi")
15843    (set_attr "length" "14")])
15844
15845 (define_expand "tls_global_dynamic_32"
15846   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15847                    (unspec:SI
15848                     [(match_dup 2)
15849                      (match_operand:SI 1 "tls_symbolic_operand" "")
15850                      (match_dup 3)]
15851                     UNSPEC_TLS_GD))
15852               (clobber (match_scratch:SI 4 ""))
15853               (clobber (match_scratch:SI 5 ""))
15854               (clobber (reg:CC FLAGS_REG))])]
15855   ""
15856 {
15857   if (flag_pic)
15858     operands[2] = pic_offset_table_rtx;
15859   else
15860     {
15861       operands[2] = gen_reg_rtx (Pmode);
15862       emit_insn (gen_set_got (operands[2]));
15863     }
15864   if (TARGET_GNU2_TLS)
15865     {
15866        emit_insn (gen_tls_dynamic_gnu2_32
15867                   (operands[0], operands[1], operands[2]));
15868        DONE;
15869     }
15870   operands[3] = ix86_tls_get_addr ();
15871 })
15872
15873 (define_insn "*tls_global_dynamic_64"
15874   [(set (match_operand:DI 0 "register_operand" "=a")
15875         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15876                  (match_operand:DI 3 "" "")))
15877    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15878               UNSPEC_TLS_GD)]
15879   "TARGET_64BIT"
15880   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15881   [(set_attr "type" "multi")
15882    (set_attr "length" "16")])
15883
15884 (define_expand "tls_global_dynamic_64"
15885   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15886                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15887               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15888                          UNSPEC_TLS_GD)])]
15889   ""
15890 {
15891   if (TARGET_GNU2_TLS)
15892     {
15893        emit_insn (gen_tls_dynamic_gnu2_64
15894                   (operands[0], operands[1]));
15895        DONE;
15896     }
15897   operands[2] = ix86_tls_get_addr ();
15898 })
15899
15900 (define_insn "*tls_local_dynamic_base_32_gnu"
15901   [(set (match_operand:SI 0 "register_operand" "=a")
15902         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15903                     (match_operand:SI 2 "call_insn_operand" "")]
15904                    UNSPEC_TLS_LD_BASE))
15905    (clobber (match_scratch:SI 3 "=d"))
15906    (clobber (match_scratch:SI 4 "=c"))
15907    (clobber (reg:CC FLAGS_REG))]
15908   "!TARGET_64BIT && TARGET_GNU_TLS"
15909   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15910   [(set_attr "type" "multi")
15911    (set_attr "length" "11")])
15912
15913 (define_insn "*tls_local_dynamic_base_32_sun"
15914   [(set (match_operand:SI 0 "register_operand" "=a")
15915         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15916                     (match_operand:SI 2 "call_insn_operand" "")]
15917                    UNSPEC_TLS_LD_BASE))
15918    (clobber (match_scratch:SI 3 "=d"))
15919    (clobber (match_scratch:SI 4 "=c"))
15920    (clobber (reg:CC FLAGS_REG))]
15921   "!TARGET_64BIT && TARGET_SUN_TLS"
15922   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15923         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15924   [(set_attr "type" "multi")
15925    (set_attr "length" "13")])
15926
15927 (define_expand "tls_local_dynamic_base_32"
15928   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15929                    (unspec:SI [(match_dup 1) (match_dup 2)]
15930                               UNSPEC_TLS_LD_BASE))
15931               (clobber (match_scratch:SI 3 ""))
15932               (clobber (match_scratch:SI 4 ""))
15933               (clobber (reg:CC FLAGS_REG))])]
15934   ""
15935 {
15936   if (flag_pic)
15937     operands[1] = pic_offset_table_rtx;
15938   else
15939     {
15940       operands[1] = gen_reg_rtx (Pmode);
15941       emit_insn (gen_set_got (operands[1]));
15942     }
15943   if (TARGET_GNU2_TLS)
15944     {
15945        emit_insn (gen_tls_dynamic_gnu2_32
15946                   (operands[0], ix86_tls_module_base (), operands[1]));
15947        DONE;
15948     }
15949   operands[2] = ix86_tls_get_addr ();
15950 })
15951
15952 (define_insn "*tls_local_dynamic_base_64"
15953   [(set (match_operand:DI 0 "register_operand" "=a")
15954         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15955                  (match_operand:DI 2 "" "")))
15956    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15957   "TARGET_64BIT"
15958   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15959   [(set_attr "type" "multi")
15960    (set_attr "length" "12")])
15961
15962 (define_expand "tls_local_dynamic_base_64"
15963   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15964                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15965               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15966   ""
15967 {
15968   if (TARGET_GNU2_TLS)
15969     {
15970        emit_insn (gen_tls_dynamic_gnu2_64
15971                   (operands[0], ix86_tls_module_base ()));
15972        DONE;
15973     }
15974   operands[1] = ix86_tls_get_addr ();
15975 })
15976
15977 ;; Local dynamic of a single variable is a lose.  Show combine how
15978 ;; to convert that back to global dynamic.
15979
15980 (define_insn_and_split "*tls_local_dynamic_32_once"
15981   [(set (match_operand:SI 0 "register_operand" "=a")
15982         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15983                              (match_operand:SI 2 "call_insn_operand" "")]
15984                             UNSPEC_TLS_LD_BASE)
15985                  (const:SI (unspec:SI
15986                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15987                             UNSPEC_DTPOFF))))
15988    (clobber (match_scratch:SI 4 "=d"))
15989    (clobber (match_scratch:SI 5 "=c"))
15990    (clobber (reg:CC FLAGS_REG))]
15991   ""
15992   "#"
15993   ""
15994   [(parallel [(set (match_dup 0)
15995                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15996                               UNSPEC_TLS_GD))
15997               (clobber (match_dup 4))
15998               (clobber (match_dup 5))
15999               (clobber (reg:CC FLAGS_REG))])]
16000   "")
16001
16002 ;; Load and add the thread base pointer from %gs:0.
16003
16004 (define_insn "*load_tp_si"
16005   [(set (match_operand:SI 0 "register_operand" "=r")
16006         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16007   "!TARGET_64BIT"
16008   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16009   [(set_attr "type" "imov")
16010    (set_attr "modrm" "0")
16011    (set_attr "length" "7")
16012    (set_attr "memory" "load")
16013    (set_attr "imm_disp" "false")])
16014
16015 (define_insn "*add_tp_si"
16016   [(set (match_operand:SI 0 "register_operand" "=r")
16017         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16018                  (match_operand:SI 1 "register_operand" "0")))
16019    (clobber (reg:CC FLAGS_REG))]
16020   "!TARGET_64BIT"
16021   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16022   [(set_attr "type" "alu")
16023    (set_attr "modrm" "0")
16024    (set_attr "length" "7")
16025    (set_attr "memory" "load")
16026    (set_attr "imm_disp" "false")])
16027
16028 (define_insn "*load_tp_di"
16029   [(set (match_operand:DI 0 "register_operand" "=r")
16030         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16031   "TARGET_64BIT"
16032   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16033   [(set_attr "type" "imov")
16034    (set_attr "modrm" "0")
16035    (set_attr "length" "7")
16036    (set_attr "memory" "load")
16037    (set_attr "imm_disp" "false")])
16038
16039 (define_insn "*add_tp_di"
16040   [(set (match_operand:DI 0 "register_operand" "=r")
16041         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16042                  (match_operand:DI 1 "register_operand" "0")))
16043    (clobber (reg:CC FLAGS_REG))]
16044   "TARGET_64BIT"
16045   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16046   [(set_attr "type" "alu")
16047    (set_attr "modrm" "0")
16048    (set_attr "length" "7")
16049    (set_attr "memory" "load")
16050    (set_attr "imm_disp" "false")])
16051
16052 ;; GNU2 TLS patterns can be split.
16053
16054 (define_expand "tls_dynamic_gnu2_32"
16055   [(set (match_dup 3)
16056         (plus:SI (match_operand:SI 2 "register_operand" "")
16057                  (const:SI
16058                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16059                              UNSPEC_TLSDESC))))
16060    (parallel
16061     [(set (match_operand:SI 0 "register_operand" "")
16062           (unspec:SI [(match_dup 1) (match_dup 3)
16063                       (match_dup 2) (reg:SI SP_REG)]
16064                       UNSPEC_TLSDESC))
16065      (clobber (reg:CC FLAGS_REG))])]
16066   "!TARGET_64BIT && TARGET_GNU2_TLS"
16067 {
16068   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16069   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16070 })
16071
16072 (define_insn "*tls_dynamic_lea_32"
16073   [(set (match_operand:SI 0 "register_operand" "=r")
16074         (plus:SI (match_operand:SI 1 "register_operand" "b")
16075                  (const:SI
16076                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16077                               UNSPEC_TLSDESC))))]
16078   "!TARGET_64BIT && TARGET_GNU2_TLS"
16079   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16080   [(set_attr "type" "lea")
16081    (set_attr "mode" "SI")
16082    (set_attr "length" "6")
16083    (set_attr "length_address" "4")])
16084
16085 (define_insn "*tls_dynamic_call_32"
16086   [(set (match_operand:SI 0 "register_operand" "=a")
16087         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16088                     (match_operand:SI 2 "register_operand" "0")
16089                     ;; we have to make sure %ebx still points to the GOT
16090                     (match_operand:SI 3 "register_operand" "b")
16091                     (reg:SI SP_REG)]
16092                    UNSPEC_TLSDESC))
16093    (clobber (reg:CC FLAGS_REG))]
16094   "!TARGET_64BIT && TARGET_GNU2_TLS"
16095   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16096   [(set_attr "type" "call")
16097    (set_attr "length" "2")
16098    (set_attr "length_address" "0")])
16099
16100 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16101   [(set (match_operand:SI 0 "register_operand" "=&a")
16102         (plus:SI
16103          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16104                      (match_operand:SI 4 "" "")
16105                      (match_operand:SI 2 "register_operand" "b")
16106                      (reg:SI SP_REG)]
16107                     UNSPEC_TLSDESC)
16108          (const:SI (unspec:SI
16109                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16110                     UNSPEC_DTPOFF))))
16111    (clobber (reg:CC FLAGS_REG))]
16112   "!TARGET_64BIT && TARGET_GNU2_TLS"
16113   "#"
16114   ""
16115   [(set (match_dup 0) (match_dup 5))]
16116 {
16117   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16118   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16119 })
16120
16121 (define_expand "tls_dynamic_gnu2_64"
16122   [(set (match_dup 2)
16123         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16124                    UNSPEC_TLSDESC))
16125    (parallel
16126     [(set (match_operand:DI 0 "register_operand" "")
16127           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16128                      UNSPEC_TLSDESC))
16129      (clobber (reg:CC FLAGS_REG))])]
16130   "TARGET_64BIT && TARGET_GNU2_TLS"
16131 {
16132   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16133   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16134 })
16135
16136 (define_insn "*tls_dynamic_lea_64"
16137   [(set (match_operand:DI 0 "register_operand" "=r")
16138         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16139                    UNSPEC_TLSDESC))]
16140   "TARGET_64BIT && TARGET_GNU2_TLS"
16141   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16142   [(set_attr "type" "lea")
16143    (set_attr "mode" "DI")
16144    (set_attr "length" "7")
16145    (set_attr "length_address" "4")])
16146
16147 (define_insn "*tls_dynamic_call_64"
16148   [(set (match_operand:DI 0 "register_operand" "=a")
16149         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16150                     (match_operand:DI 2 "register_operand" "0")
16151                     (reg:DI SP_REG)]
16152                    UNSPEC_TLSDESC))
16153    (clobber (reg:CC FLAGS_REG))]
16154   "TARGET_64BIT && TARGET_GNU2_TLS"
16155   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16156   [(set_attr "type" "call")
16157    (set_attr "length" "2")
16158    (set_attr "length_address" "0")])
16159
16160 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16161   [(set (match_operand:DI 0 "register_operand" "=&a")
16162         (plus:DI
16163          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16164                      (match_operand:DI 3 "" "")
16165                      (reg:DI SP_REG)]
16166                     UNSPEC_TLSDESC)
16167          (const:DI (unspec:DI
16168                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16169                     UNSPEC_DTPOFF))))
16170    (clobber (reg:CC FLAGS_REG))]
16171   "TARGET_64BIT && TARGET_GNU2_TLS"
16172   "#"
16173   ""
16174   [(set (match_dup 0) (match_dup 4))]
16175 {
16176   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16177   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16178 })
16179
16180 ;;
16181 \f
16182 ;; These patterns match the binary 387 instructions for addM3, subM3,
16183 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16184 ;; SFmode.  The first is the normal insn, the second the same insn but
16185 ;; with one operand a conversion, and the third the same insn but with
16186 ;; the other operand a conversion.  The conversion may be SFmode or
16187 ;; SImode if the target mode DFmode, but only SImode if the target mode
16188 ;; is SFmode.
16189
16190 ;; Gcc is slightly more smart about handling normal two address instructions
16191 ;; so use special patterns for add and mull.
16192
16193 (define_insn "*fop_<mode>_comm_mixed_avx"
16194   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16195         (match_operator:MODEF 3 "binary_fp_operator"
16196           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16197            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16198   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16199    && COMMUTATIVE_ARITH_P (operands[3])
16200    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16201   "* return output_387_binary_op (insn, operands);"
16202   [(set (attr "type")
16203         (if_then_else (eq_attr "alternative" "1")
16204            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16205               (const_string "ssemul")
16206               (const_string "sseadd"))
16207            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16208               (const_string "fmul")
16209               (const_string "fop"))))
16210    (set_attr "prefix" "orig,maybe_vex")
16211    (set_attr "mode" "<MODE>")])
16212
16213 (define_insn "*fop_<mode>_comm_mixed"
16214   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16215         (match_operator:MODEF 3 "binary_fp_operator"
16216           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16217            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16218   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16219    && COMMUTATIVE_ARITH_P (operands[3])
16220    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16221   "* return output_387_binary_op (insn, operands);"
16222   [(set (attr "type")
16223         (if_then_else (eq_attr "alternative" "1")
16224            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16225               (const_string "ssemul")
16226               (const_string "sseadd"))
16227            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16228               (const_string "fmul")
16229               (const_string "fop"))))
16230    (set_attr "mode" "<MODE>")])
16231
16232 (define_insn "*fop_<mode>_comm_avx"
16233   [(set (match_operand:MODEF 0 "register_operand" "=x")
16234         (match_operator:MODEF 3 "binary_fp_operator"
16235           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16236            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16237   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16238    && COMMUTATIVE_ARITH_P (operands[3])
16239    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16240   "* return output_387_binary_op (insn, operands);"
16241   [(set (attr "type")
16242         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16243            (const_string "ssemul")
16244            (const_string "sseadd")))
16245    (set_attr "prefix" "vex")
16246    (set_attr "mode" "<MODE>")])
16247
16248 (define_insn "*fop_<mode>_comm_sse"
16249   [(set (match_operand:MODEF 0 "register_operand" "=x")
16250         (match_operator:MODEF 3 "binary_fp_operator"
16251           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16252            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16253   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16254    && COMMUTATIVE_ARITH_P (operands[3])
16255    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16256   "* return output_387_binary_op (insn, operands);"
16257   [(set (attr "type")
16258         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16259            (const_string "ssemul")
16260            (const_string "sseadd")))
16261    (set_attr "mode" "<MODE>")])
16262
16263 (define_insn "*fop_<mode>_comm_i387"
16264   [(set (match_operand:MODEF 0 "register_operand" "=f")
16265         (match_operator:MODEF 3 "binary_fp_operator"
16266           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16267            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16268   "TARGET_80387
16269    && COMMUTATIVE_ARITH_P (operands[3])
16270    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16271   "* return output_387_binary_op (insn, operands);"
16272   [(set (attr "type")
16273         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16274            (const_string "fmul")
16275            (const_string "fop")))
16276    (set_attr "mode" "<MODE>")])
16277
16278 (define_insn "*fop_<mode>_1_mixed_avx"
16279   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16280         (match_operator:MODEF 3 "binary_fp_operator"
16281           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16282            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16283   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16284    && !COMMUTATIVE_ARITH_P (operands[3])
16285    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16286   "* return output_387_binary_op (insn, operands);"
16287   [(set (attr "type")
16288         (cond [(and (eq_attr "alternative" "2")
16289                     (match_operand:MODEF 3 "mult_operator" ""))
16290                  (const_string "ssemul")
16291                (and (eq_attr "alternative" "2")
16292                     (match_operand:MODEF 3 "div_operator" ""))
16293                  (const_string "ssediv")
16294                (eq_attr "alternative" "2")
16295                  (const_string "sseadd")
16296                (match_operand:MODEF 3 "mult_operator" "")
16297                  (const_string "fmul")
16298                (match_operand:MODEF 3 "div_operator" "")
16299                  (const_string "fdiv")
16300               ]
16301               (const_string "fop")))
16302    (set_attr "prefix" "orig,orig,maybe_vex")
16303    (set_attr "mode" "<MODE>")])
16304
16305 (define_insn "*fop_<mode>_1_mixed"
16306   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16307         (match_operator:MODEF 3 "binary_fp_operator"
16308           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16309            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16310   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16311    && !COMMUTATIVE_ARITH_P (operands[3])
16312    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16313   "* return output_387_binary_op (insn, operands);"
16314   [(set (attr "type")
16315         (cond [(and (eq_attr "alternative" "2")
16316                     (match_operand:MODEF 3 "mult_operator" ""))
16317                  (const_string "ssemul")
16318                (and (eq_attr "alternative" "2")
16319                     (match_operand:MODEF 3 "div_operator" ""))
16320                  (const_string "ssediv")
16321                (eq_attr "alternative" "2")
16322                  (const_string "sseadd")
16323                (match_operand:MODEF 3 "mult_operator" "")
16324                  (const_string "fmul")
16325                (match_operand:MODEF 3 "div_operator" "")
16326                  (const_string "fdiv")
16327               ]
16328               (const_string "fop")))
16329    (set_attr "mode" "<MODE>")])
16330
16331 (define_insn "*rcpsf2_sse"
16332   [(set (match_operand:SF 0 "register_operand" "=x")
16333         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16334                    UNSPEC_RCP))]
16335   "TARGET_SSE_MATH"
16336   "%vrcpss\t{%1, %d0|%d0, %1}"
16337   [(set_attr "type" "sse")
16338    (set_attr "prefix" "maybe_vex")
16339    (set_attr "mode" "SF")])
16340
16341 (define_insn "*fop_<mode>_1_avx"
16342   [(set (match_operand:MODEF 0 "register_operand" "=x")
16343         (match_operator:MODEF 3 "binary_fp_operator"
16344           [(match_operand:MODEF 1 "register_operand" "x")
16345            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16346   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16347    && !COMMUTATIVE_ARITH_P (operands[3])"
16348   "* return output_387_binary_op (insn, operands);"
16349   [(set (attr "type")
16350         (cond [(match_operand:MODEF 3 "mult_operator" "")
16351                  (const_string "ssemul")
16352                (match_operand:MODEF 3 "div_operator" "")
16353                  (const_string "ssediv")
16354               ]
16355               (const_string "sseadd")))
16356    (set_attr "prefix" "vex")
16357    (set_attr "mode" "<MODE>")])
16358
16359 (define_insn "*fop_<mode>_1_sse"
16360   [(set (match_operand:MODEF 0 "register_operand" "=x")
16361         (match_operator:MODEF 3 "binary_fp_operator"
16362           [(match_operand:MODEF 1 "register_operand" "0")
16363            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16364   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16365    && !COMMUTATIVE_ARITH_P (operands[3])"
16366   "* return output_387_binary_op (insn, operands);"
16367   [(set (attr "type")
16368         (cond [(match_operand:MODEF 3 "mult_operator" "")
16369                  (const_string "ssemul")
16370                (match_operand:MODEF 3 "div_operator" "")
16371                  (const_string "ssediv")
16372               ]
16373               (const_string "sseadd")))
16374    (set_attr "mode" "<MODE>")])
16375
16376 ;; This pattern is not fully shadowed by the pattern above.
16377 (define_insn "*fop_<mode>_1_i387"
16378   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16379         (match_operator:MODEF 3 "binary_fp_operator"
16380           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16381            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16382   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16383    && !COMMUTATIVE_ARITH_P (operands[3])
16384    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16385   "* return output_387_binary_op (insn, operands);"
16386   [(set (attr "type")
16387         (cond [(match_operand:MODEF 3 "mult_operator" "")
16388                  (const_string "fmul")
16389                (match_operand:MODEF 3 "div_operator" "")
16390                  (const_string "fdiv")
16391               ]
16392               (const_string "fop")))
16393    (set_attr "mode" "<MODE>")])
16394
16395 ;; ??? Add SSE splitters for these!
16396 (define_insn "*fop_<MODEF:mode>_2_i387"
16397   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16398         (match_operator:MODEF 3 "binary_fp_operator"
16399           [(float:MODEF
16400              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16401            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16402   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16403    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16404   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16405   [(set (attr "type")
16406         (cond [(match_operand:MODEF 3 "mult_operator" "")
16407                  (const_string "fmul")
16408                (match_operand:MODEF 3 "div_operator" "")
16409                  (const_string "fdiv")
16410               ]
16411               (const_string "fop")))
16412    (set_attr "fp_int_src" "true")
16413    (set_attr "mode" "<X87MODEI12:MODE>")])
16414
16415 (define_insn "*fop_<MODEF:mode>_3_i387"
16416   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16417         (match_operator:MODEF 3 "binary_fp_operator"
16418           [(match_operand:MODEF 1 "register_operand" "0,0")
16419            (float:MODEF
16420              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16421   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16422    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16423   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16424   [(set (attr "type")
16425         (cond [(match_operand:MODEF 3 "mult_operator" "")
16426                  (const_string "fmul")
16427                (match_operand:MODEF 3 "div_operator" "")
16428                  (const_string "fdiv")
16429               ]
16430               (const_string "fop")))
16431    (set_attr "fp_int_src" "true")
16432    (set_attr "mode" "<MODE>")])
16433
16434 (define_insn "*fop_df_4_i387"
16435   [(set (match_operand:DF 0 "register_operand" "=f,f")
16436         (match_operator:DF 3 "binary_fp_operator"
16437            [(float_extend:DF
16438              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16439             (match_operand:DF 2 "register_operand" "0,f")]))]
16440   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16441    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16442   "* return output_387_binary_op (insn, operands);"
16443   [(set (attr "type")
16444         (cond [(match_operand:DF 3 "mult_operator" "")
16445                  (const_string "fmul")
16446                (match_operand:DF 3 "div_operator" "")
16447                  (const_string "fdiv")
16448               ]
16449               (const_string "fop")))
16450    (set_attr "mode" "SF")])
16451
16452 (define_insn "*fop_df_5_i387"
16453   [(set (match_operand:DF 0 "register_operand" "=f,f")
16454         (match_operator:DF 3 "binary_fp_operator"
16455           [(match_operand:DF 1 "register_operand" "0,f")
16456            (float_extend:DF
16457             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16458   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16459   "* return output_387_binary_op (insn, operands);"
16460   [(set (attr "type")
16461         (cond [(match_operand:DF 3 "mult_operator" "")
16462                  (const_string "fmul")
16463                (match_operand:DF 3 "div_operator" "")
16464                  (const_string "fdiv")
16465               ]
16466               (const_string "fop")))
16467    (set_attr "mode" "SF")])
16468
16469 (define_insn "*fop_df_6_i387"
16470   [(set (match_operand:DF 0 "register_operand" "=f,f")
16471         (match_operator:DF 3 "binary_fp_operator"
16472           [(float_extend:DF
16473             (match_operand:SF 1 "register_operand" "0,f"))
16474            (float_extend:DF
16475             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16476   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16477   "* return output_387_binary_op (insn, operands);"
16478   [(set (attr "type")
16479         (cond [(match_operand:DF 3 "mult_operator" "")
16480                  (const_string "fmul")
16481                (match_operand:DF 3 "div_operator" "")
16482                  (const_string "fdiv")
16483               ]
16484               (const_string "fop")))
16485    (set_attr "mode" "SF")])
16486
16487 (define_insn "*fop_xf_comm_i387"
16488   [(set (match_operand:XF 0 "register_operand" "=f")
16489         (match_operator:XF 3 "binary_fp_operator"
16490                         [(match_operand:XF 1 "register_operand" "%0")
16491                          (match_operand:XF 2 "register_operand" "f")]))]
16492   "TARGET_80387
16493    && COMMUTATIVE_ARITH_P (operands[3])"
16494   "* return output_387_binary_op (insn, operands);"
16495   [(set (attr "type")
16496         (if_then_else (match_operand:XF 3 "mult_operator" "")
16497            (const_string "fmul")
16498            (const_string "fop")))
16499    (set_attr "mode" "XF")])
16500
16501 (define_insn "*fop_xf_1_i387"
16502   [(set (match_operand:XF 0 "register_operand" "=f,f")
16503         (match_operator:XF 3 "binary_fp_operator"
16504                         [(match_operand:XF 1 "register_operand" "0,f")
16505                          (match_operand:XF 2 "register_operand" "f,0")]))]
16506   "TARGET_80387
16507    && !COMMUTATIVE_ARITH_P (operands[3])"
16508   "* return output_387_binary_op (insn, operands);"
16509   [(set (attr "type")
16510         (cond [(match_operand:XF 3 "mult_operator" "")
16511                  (const_string "fmul")
16512                (match_operand:XF 3 "div_operator" "")
16513                  (const_string "fdiv")
16514               ]
16515               (const_string "fop")))
16516    (set_attr "mode" "XF")])
16517
16518 (define_insn "*fop_xf_2_i387"
16519   [(set (match_operand:XF 0 "register_operand" "=f,f")
16520         (match_operator:XF 3 "binary_fp_operator"
16521           [(float:XF
16522              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16523            (match_operand:XF 2 "register_operand" "0,0")]))]
16524   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16525   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16526   [(set (attr "type")
16527         (cond [(match_operand:XF 3 "mult_operator" "")
16528                  (const_string "fmul")
16529                (match_operand:XF 3 "div_operator" "")
16530                  (const_string "fdiv")
16531               ]
16532               (const_string "fop")))
16533    (set_attr "fp_int_src" "true")
16534    (set_attr "mode" "<MODE>")])
16535
16536 (define_insn "*fop_xf_3_i387"
16537   [(set (match_operand:XF 0 "register_operand" "=f,f")
16538         (match_operator:XF 3 "binary_fp_operator"
16539           [(match_operand:XF 1 "register_operand" "0,0")
16540            (float:XF
16541              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16542   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16543   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16544   [(set (attr "type")
16545         (cond [(match_operand:XF 3 "mult_operator" "")
16546                  (const_string "fmul")
16547                (match_operand:XF 3 "div_operator" "")
16548                  (const_string "fdiv")
16549               ]
16550               (const_string "fop")))
16551    (set_attr "fp_int_src" "true")
16552    (set_attr "mode" "<MODE>")])
16553
16554 (define_insn "*fop_xf_4_i387"
16555   [(set (match_operand:XF 0 "register_operand" "=f,f")
16556         (match_operator:XF 3 "binary_fp_operator"
16557            [(float_extend:XF
16558               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16559             (match_operand:XF 2 "register_operand" "0,f")]))]
16560   "TARGET_80387"
16561   "* return output_387_binary_op (insn, operands);"
16562   [(set (attr "type")
16563         (cond [(match_operand:XF 3 "mult_operator" "")
16564                  (const_string "fmul")
16565                (match_operand:XF 3 "div_operator" "")
16566                  (const_string "fdiv")
16567               ]
16568               (const_string "fop")))
16569    (set_attr "mode" "<MODE>")])
16570
16571 (define_insn "*fop_xf_5_i387"
16572   [(set (match_operand:XF 0 "register_operand" "=f,f")
16573         (match_operator:XF 3 "binary_fp_operator"
16574           [(match_operand:XF 1 "register_operand" "0,f")
16575            (float_extend:XF
16576              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16577   "TARGET_80387"
16578   "* return output_387_binary_op (insn, operands);"
16579   [(set (attr "type")
16580         (cond [(match_operand:XF 3 "mult_operator" "")
16581                  (const_string "fmul")
16582                (match_operand:XF 3 "div_operator" "")
16583                  (const_string "fdiv")
16584               ]
16585               (const_string "fop")))
16586    (set_attr "mode" "<MODE>")])
16587
16588 (define_insn "*fop_xf_6_i387"
16589   [(set (match_operand:XF 0 "register_operand" "=f,f")
16590         (match_operator:XF 3 "binary_fp_operator"
16591           [(float_extend:XF
16592              (match_operand:MODEF 1 "register_operand" "0,f"))
16593            (float_extend:XF
16594              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16595   "TARGET_80387"
16596   "* return output_387_binary_op (insn, operands);"
16597   [(set (attr "type")
16598         (cond [(match_operand:XF 3 "mult_operator" "")
16599                  (const_string "fmul")
16600                (match_operand:XF 3 "div_operator" "")
16601                  (const_string "fdiv")
16602               ]
16603               (const_string "fop")))
16604    (set_attr "mode" "<MODE>")])
16605
16606 (define_split
16607   [(set (match_operand 0 "register_operand" "")
16608         (match_operator 3 "binary_fp_operator"
16609            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16610             (match_operand 2 "register_operand" "")]))]
16611   "reload_completed
16612    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16613   [(const_int 0)]
16614 {
16615   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16616   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16617   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16618                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16619                                           GET_MODE (operands[3]),
16620                                           operands[4],
16621                                           operands[2])));
16622   ix86_free_from_memory (GET_MODE (operands[1]));
16623   DONE;
16624 })
16625
16626 (define_split
16627   [(set (match_operand 0 "register_operand" "")
16628         (match_operator 3 "binary_fp_operator"
16629            [(match_operand 1 "register_operand" "")
16630             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16631   "reload_completed
16632    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16633   [(const_int 0)]
16634 {
16635   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16636   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16637   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16638                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16639                                           GET_MODE (operands[3]),
16640                                           operands[1],
16641                                           operands[4])));
16642   ix86_free_from_memory (GET_MODE (operands[2]));
16643   DONE;
16644 })
16645 \f
16646 ;; FPU special functions.
16647
16648 ;; This pattern implements a no-op XFmode truncation for
16649 ;; all fancy i386 XFmode math functions.
16650
16651 (define_insn "truncxf<mode>2_i387_noop_unspec"
16652   [(set (match_operand:MODEF 0 "register_operand" "=f")
16653         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16654         UNSPEC_TRUNC_NOOP))]
16655   "TARGET_USE_FANCY_MATH_387"
16656   "* return output_387_reg_move (insn, operands);"
16657   [(set_attr "type" "fmov")
16658    (set_attr "mode" "<MODE>")])
16659
16660 (define_insn "sqrtxf2"
16661   [(set (match_operand:XF 0 "register_operand" "=f")
16662         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16663   "TARGET_USE_FANCY_MATH_387"
16664   "fsqrt"
16665   [(set_attr "type" "fpspc")
16666    (set_attr "mode" "XF")
16667    (set_attr "athlon_decode" "direct")
16668    (set_attr "amdfam10_decode" "direct")])
16669
16670 (define_insn "sqrt_extend<mode>xf2_i387"
16671   [(set (match_operand:XF 0 "register_operand" "=f")
16672         (sqrt:XF
16673           (float_extend:XF
16674             (match_operand:MODEF 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 "*rsqrtsf2_sse"
16683   [(set (match_operand:SF 0 "register_operand" "=x")
16684         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16685                    UNSPEC_RSQRT))]
16686   "TARGET_SSE_MATH"
16687   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16688   [(set_attr "type" "sse")
16689    (set_attr "prefix" "maybe_vex")
16690    (set_attr "mode" "SF")])
16691
16692 (define_expand "rsqrtsf2"
16693   [(set (match_operand:SF 0 "register_operand" "")
16694         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16695                    UNSPEC_RSQRT))]
16696   "TARGET_SSE_MATH"
16697 {
16698   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16699   DONE;
16700 })
16701
16702 (define_insn "*sqrt<mode>2_sse"
16703   [(set (match_operand:MODEF 0 "register_operand" "=x")
16704         (sqrt:MODEF
16705           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16706   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16707   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16708   [(set_attr "type" "sse")
16709    (set_attr "prefix" "maybe_vex")
16710    (set_attr "mode" "<MODE>")
16711    (set_attr "athlon_decode" "*")
16712    (set_attr "amdfam10_decode" "*")])
16713
16714 (define_expand "sqrt<mode>2"
16715   [(set (match_operand:MODEF 0 "register_operand" "")
16716         (sqrt:MODEF
16717           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16718   "TARGET_USE_FANCY_MATH_387
16719    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16720 {
16721   if (<MODE>mode == SFmode
16722       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16723       && flag_finite_math_only && !flag_trapping_math
16724       && flag_unsafe_math_optimizations)
16725     {
16726       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16727       DONE;
16728     }
16729
16730   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16731     {
16732       rtx op0 = gen_reg_rtx (XFmode);
16733       rtx op1 = force_reg (<MODE>mode, operands[1]);
16734
16735       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16736       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16737       DONE;
16738    }
16739 })
16740
16741 (define_insn "fpremxf4_i387"
16742   [(set (match_operand:XF 0 "register_operand" "=f")
16743         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16744                     (match_operand:XF 3 "register_operand" "1")]
16745                    UNSPEC_FPREM_F))
16746    (set (match_operand:XF 1 "register_operand" "=u")
16747         (unspec:XF [(match_dup 2) (match_dup 3)]
16748                    UNSPEC_FPREM_U))
16749    (set (reg:CCFP FPSR_REG)
16750         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16751                      UNSPEC_C2_FLAG))]
16752   "TARGET_USE_FANCY_MATH_387"
16753   "fprem"
16754   [(set_attr "type" "fpspc")
16755    (set_attr "mode" "XF")])
16756
16757 (define_expand "fmodxf3"
16758   [(use (match_operand:XF 0 "register_operand" ""))
16759    (use (match_operand:XF 1 "general_operand" ""))
16760    (use (match_operand:XF 2 "general_operand" ""))]
16761   "TARGET_USE_FANCY_MATH_387"
16762 {
16763   rtx label = gen_label_rtx ();
16764
16765   rtx op1 = gen_reg_rtx (XFmode);
16766   rtx op2 = gen_reg_rtx (XFmode);
16767
16768   emit_move_insn (op2, operands[2]);
16769   emit_move_insn (op1, operands[1]);
16770
16771   emit_label (label);
16772   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16773   ix86_emit_fp_unordered_jump (label);
16774   LABEL_NUSES (label) = 1;
16775
16776   emit_move_insn (operands[0], op1);
16777   DONE;
16778 })
16779
16780 (define_expand "fmod<mode>3"
16781   [(use (match_operand:MODEF 0 "register_operand" ""))
16782    (use (match_operand:MODEF 1 "general_operand" ""))
16783    (use (match_operand:MODEF 2 "general_operand" ""))]
16784   "TARGET_USE_FANCY_MATH_387"
16785 {
16786   rtx label = gen_label_rtx ();
16787
16788   rtx op1 = gen_reg_rtx (XFmode);
16789   rtx op2 = gen_reg_rtx (XFmode);
16790
16791   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16792   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16793
16794   emit_label (label);
16795   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16796   ix86_emit_fp_unordered_jump (label);
16797   LABEL_NUSES (label) = 1;
16798
16799   /* Truncate the result properly for strict SSE math.  */
16800   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16801       && !TARGET_MIX_SSE_I387)
16802     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16803   else
16804     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16805
16806   DONE;
16807 })
16808
16809 (define_insn "fprem1xf4_i387"
16810   [(set (match_operand:XF 0 "register_operand" "=f")
16811         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16812                     (match_operand:XF 3 "register_operand" "1")]
16813                    UNSPEC_FPREM1_F))
16814    (set (match_operand:XF 1 "register_operand" "=u")
16815         (unspec:XF [(match_dup 2) (match_dup 3)]
16816                    UNSPEC_FPREM1_U))
16817    (set (reg:CCFP FPSR_REG)
16818         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16819                      UNSPEC_C2_FLAG))]
16820   "TARGET_USE_FANCY_MATH_387"
16821   "fprem1"
16822   [(set_attr "type" "fpspc")
16823    (set_attr "mode" "XF")])
16824
16825 (define_expand "remainderxf3"
16826   [(use (match_operand:XF 0 "register_operand" ""))
16827    (use (match_operand:XF 1 "general_operand" ""))
16828    (use (match_operand:XF 2 "general_operand" ""))]
16829   "TARGET_USE_FANCY_MATH_387"
16830 {
16831   rtx label = gen_label_rtx ();
16832
16833   rtx op1 = gen_reg_rtx (XFmode);
16834   rtx op2 = gen_reg_rtx (XFmode);
16835
16836   emit_move_insn (op2, operands[2]);
16837   emit_move_insn (op1, operands[1]);
16838
16839   emit_label (label);
16840   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16841   ix86_emit_fp_unordered_jump (label);
16842   LABEL_NUSES (label) = 1;
16843
16844   emit_move_insn (operands[0], op1);
16845   DONE;
16846 })
16847
16848 (define_expand "remainder<mode>3"
16849   [(use (match_operand:MODEF 0 "register_operand" ""))
16850    (use (match_operand:MODEF 1 "general_operand" ""))
16851    (use (match_operand:MODEF 2 "general_operand" ""))]
16852   "TARGET_USE_FANCY_MATH_387"
16853 {
16854   rtx label = gen_label_rtx ();
16855
16856   rtx op1 = gen_reg_rtx (XFmode);
16857   rtx op2 = gen_reg_rtx (XFmode);
16858
16859   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16860   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16861
16862   emit_label (label);
16863
16864   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16865   ix86_emit_fp_unordered_jump (label);
16866   LABEL_NUSES (label) = 1;
16867
16868   /* Truncate the result properly for strict SSE math.  */
16869   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16870       && !TARGET_MIX_SSE_I387)
16871     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16872   else
16873     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16874
16875   DONE;
16876 })
16877
16878 (define_insn "*sinxf2_i387"
16879   [(set (match_operand:XF 0 "register_operand" "=f")
16880         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16881   "TARGET_USE_FANCY_MATH_387
16882    && flag_unsafe_math_optimizations"
16883   "fsin"
16884   [(set_attr "type" "fpspc")
16885    (set_attr "mode" "XF")])
16886
16887 (define_insn "*sin_extend<mode>xf2_i387"
16888   [(set (match_operand:XF 0 "register_operand" "=f")
16889         (unspec:XF [(float_extend:XF
16890                       (match_operand:MODEF 1 "register_operand" "0"))]
16891                    UNSPEC_SIN))]
16892   "TARGET_USE_FANCY_MATH_387
16893    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16894        || TARGET_MIX_SSE_I387)
16895    && flag_unsafe_math_optimizations"
16896   "fsin"
16897   [(set_attr "type" "fpspc")
16898    (set_attr "mode" "XF")])
16899
16900 (define_insn "*cosxf2_i387"
16901   [(set (match_operand:XF 0 "register_operand" "=f")
16902         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16903   "TARGET_USE_FANCY_MATH_387
16904    && flag_unsafe_math_optimizations"
16905   "fcos"
16906   [(set_attr "type" "fpspc")
16907    (set_attr "mode" "XF")])
16908
16909 (define_insn "*cos_extend<mode>xf2_i387"
16910   [(set (match_operand:XF 0 "register_operand" "=f")
16911         (unspec:XF [(float_extend:XF
16912                       (match_operand:MODEF 1 "register_operand" "0"))]
16913                    UNSPEC_COS))]
16914   "TARGET_USE_FANCY_MATH_387
16915    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16916        || TARGET_MIX_SSE_I387)
16917    && flag_unsafe_math_optimizations"
16918   "fcos"
16919   [(set_attr "type" "fpspc")
16920    (set_attr "mode" "XF")])
16921
16922 ;; When sincos pattern is defined, sin and cos builtin functions will be
16923 ;; expanded to sincos pattern with one of its outputs left unused.
16924 ;; CSE pass will figure out if two sincos patterns can be combined,
16925 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16926 ;; depending on the unused output.
16927
16928 (define_insn "sincosxf3"
16929   [(set (match_operand:XF 0 "register_operand" "=f")
16930         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16931                    UNSPEC_SINCOS_COS))
16932    (set (match_operand:XF 1 "register_operand" "=u")
16933         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16934   "TARGET_USE_FANCY_MATH_387
16935    && flag_unsafe_math_optimizations"
16936   "fsincos"
16937   [(set_attr "type" "fpspc")
16938    (set_attr "mode" "XF")])
16939
16940 (define_split
16941   [(set (match_operand:XF 0 "register_operand" "")
16942         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16943                    UNSPEC_SINCOS_COS))
16944    (set (match_operand:XF 1 "register_operand" "")
16945         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16946   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16947    && !(reload_completed || reload_in_progress)"
16948   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16949   "")
16950
16951 (define_split
16952   [(set (match_operand:XF 0 "register_operand" "")
16953         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16954                    UNSPEC_SINCOS_COS))
16955    (set (match_operand:XF 1 "register_operand" "")
16956         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16957   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16958    && !(reload_completed || reload_in_progress)"
16959   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16960   "")
16961
16962 (define_insn "sincos_extend<mode>xf3_i387"
16963   [(set (match_operand:XF 0 "register_operand" "=f")
16964         (unspec:XF [(float_extend:XF
16965                       (match_operand:MODEF 2 "register_operand" "0"))]
16966                    UNSPEC_SINCOS_COS))
16967    (set (match_operand:XF 1 "register_operand" "=u")
16968         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16969   "TARGET_USE_FANCY_MATH_387
16970    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16971        || TARGET_MIX_SSE_I387)
16972    && flag_unsafe_math_optimizations"
16973   "fsincos"
16974   [(set_attr "type" "fpspc")
16975    (set_attr "mode" "XF")])
16976
16977 (define_split
16978   [(set (match_operand:XF 0 "register_operand" "")
16979         (unspec:XF [(float_extend:XF
16980                       (match_operand:MODEF 2 "register_operand" ""))]
16981                    UNSPEC_SINCOS_COS))
16982    (set (match_operand:XF 1 "register_operand" "")
16983         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16984   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16985    && !(reload_completed || reload_in_progress)"
16986   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16987   "")
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[1]))
16997    && !(reload_completed || reload_in_progress)"
16998   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16999   "")
17000
17001 (define_expand "sincos<mode>3"
17002   [(use (match_operand:MODEF 0 "register_operand" ""))
17003    (use (match_operand:MODEF 1 "register_operand" ""))
17004    (use (match_operand:MODEF 2 "register_operand" ""))]
17005   "TARGET_USE_FANCY_MATH_387
17006    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17007        || TARGET_MIX_SSE_I387)
17008    && flag_unsafe_math_optimizations"
17009 {
17010   rtx op0 = gen_reg_rtx (XFmode);
17011   rtx op1 = gen_reg_rtx (XFmode);
17012
17013   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17014   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17015   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17016   DONE;
17017 })
17018
17019 (define_insn "fptanxf4_i387"
17020   [(set (match_operand:XF 0 "register_operand" "=f")
17021         (match_operand:XF 3 "const_double_operand" "F"))
17022    (set (match_operand:XF 1 "register_operand" "=u")
17023         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17024                    UNSPEC_TAN))]
17025   "TARGET_USE_FANCY_MATH_387
17026    && flag_unsafe_math_optimizations
17027    && standard_80387_constant_p (operands[3]) == 2"
17028   "fptan"
17029   [(set_attr "type" "fpspc")
17030    (set_attr "mode" "XF")])
17031
17032 (define_insn "fptan_extend<mode>xf4_i387"
17033   [(set (match_operand:MODEF 0 "register_operand" "=f")
17034         (match_operand:MODEF 3 "const_double_operand" "F"))
17035    (set (match_operand:XF 1 "register_operand" "=u")
17036         (unspec:XF [(float_extend:XF
17037                       (match_operand:MODEF 2 "register_operand" "0"))]
17038                    UNSPEC_TAN))]
17039   "TARGET_USE_FANCY_MATH_387
17040    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17041        || TARGET_MIX_SSE_I387)
17042    && flag_unsafe_math_optimizations
17043    && standard_80387_constant_p (operands[3]) == 2"
17044   "fptan"
17045   [(set_attr "type" "fpspc")
17046    (set_attr "mode" "XF")])
17047
17048 (define_expand "tanxf2"
17049   [(use (match_operand:XF 0 "register_operand" ""))
17050    (use (match_operand:XF 1 "register_operand" ""))]
17051   "TARGET_USE_FANCY_MATH_387
17052    && flag_unsafe_math_optimizations"
17053 {
17054   rtx one = gen_reg_rtx (XFmode);
17055   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17056
17057   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17058   DONE;
17059 })
17060
17061 (define_expand "tan<mode>2"
17062   [(use (match_operand:MODEF 0 "register_operand" ""))
17063    (use (match_operand:MODEF 1 "register_operand" ""))]
17064   "TARGET_USE_FANCY_MATH_387
17065    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17066        || TARGET_MIX_SSE_I387)
17067    && flag_unsafe_math_optimizations"
17068 {
17069   rtx op0 = gen_reg_rtx (XFmode);
17070
17071   rtx one = gen_reg_rtx (<MODE>mode);
17072   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17073
17074   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17075                                              operands[1], op2));
17076   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17077   DONE;
17078 })
17079
17080 (define_insn "*fpatanxf3_i387"
17081   [(set (match_operand:XF 0 "register_operand" "=f")
17082         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17083                     (match_operand:XF 2 "register_operand" "u")]
17084                    UNSPEC_FPATAN))
17085    (clobber (match_scratch:XF 3 "=2"))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && flag_unsafe_math_optimizations"
17088   "fpatan"
17089   [(set_attr "type" "fpspc")
17090    (set_attr "mode" "XF")])
17091
17092 (define_insn "fpatan_extend<mode>xf3_i387"
17093   [(set (match_operand:XF 0 "register_operand" "=f")
17094         (unspec:XF [(float_extend:XF
17095                       (match_operand:MODEF 1 "register_operand" "0"))
17096                     (float_extend:XF
17097                       (match_operand:MODEF 2 "register_operand" "u"))]
17098                    UNSPEC_FPATAN))
17099    (clobber (match_scratch:XF 3 "=2"))]
17100   "TARGET_USE_FANCY_MATH_387
17101    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17102        || TARGET_MIX_SSE_I387)
17103    && flag_unsafe_math_optimizations"
17104   "fpatan"
17105   [(set_attr "type" "fpspc")
17106    (set_attr "mode" "XF")])
17107
17108 (define_expand "atan2xf3"
17109   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17110                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17111                                (match_operand:XF 1 "register_operand" "")]
17112                               UNSPEC_FPATAN))
17113               (clobber (match_scratch:XF 3 ""))])]
17114   "TARGET_USE_FANCY_MATH_387
17115    && flag_unsafe_math_optimizations"
17116   "")
17117
17118 (define_expand "atan2<mode>3"
17119   [(use (match_operand:MODEF 0 "register_operand" ""))
17120    (use (match_operand:MODEF 1 "register_operand" ""))
17121    (use (match_operand:MODEF 2 "register_operand" ""))]
17122   "TARGET_USE_FANCY_MATH_387
17123    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17124        || TARGET_MIX_SSE_I387)
17125    && flag_unsafe_math_optimizations"
17126 {
17127   rtx op0 = gen_reg_rtx (XFmode);
17128
17129   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17130   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17131   DONE;
17132 })
17133
17134 (define_expand "atanxf2"
17135   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17136                    (unspec:XF [(match_dup 2)
17137                                (match_operand:XF 1 "register_operand" "")]
17138                               UNSPEC_FPATAN))
17139               (clobber (match_scratch:XF 3 ""))])]
17140   "TARGET_USE_FANCY_MATH_387
17141    && flag_unsafe_math_optimizations"
17142 {
17143   operands[2] = gen_reg_rtx (XFmode);
17144   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17145 })
17146
17147 (define_expand "atan<mode>2"
17148   [(use (match_operand:MODEF 0 "register_operand" ""))
17149    (use (match_operand:MODEF 1 "register_operand" ""))]
17150   "TARGET_USE_FANCY_MATH_387
17151    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17152        || TARGET_MIX_SSE_I387)
17153    && flag_unsafe_math_optimizations"
17154 {
17155   rtx op0 = gen_reg_rtx (XFmode);
17156
17157   rtx op2 = gen_reg_rtx (<MODE>mode);
17158   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17159
17160   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17161   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17162   DONE;
17163 })
17164
17165 (define_expand "asinxf2"
17166   [(set (match_dup 2)
17167         (mult:XF (match_operand:XF 1 "register_operand" "")
17168                  (match_dup 1)))
17169    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17170    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17171    (parallel [(set (match_operand:XF 0 "register_operand" "")
17172                    (unspec:XF [(match_dup 5) (match_dup 1)]
17173                               UNSPEC_FPATAN))
17174               (clobber (match_scratch:XF 6 ""))])]
17175   "TARGET_USE_FANCY_MATH_387
17176    && flag_unsafe_math_optimizations"
17177 {
17178   int i;
17179
17180   if (optimize_insn_for_size_p ())
17181     FAIL;
17182
17183   for (i = 2; i < 6; i++)
17184     operands[i] = gen_reg_rtx (XFmode);
17185
17186   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17187 })
17188
17189 (define_expand "asin<mode>2"
17190   [(use (match_operand:MODEF 0 "register_operand" ""))
17191    (use (match_operand:MODEF 1 "general_operand" ""))]
17192  "TARGET_USE_FANCY_MATH_387
17193    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17194        || TARGET_MIX_SSE_I387)
17195    && flag_unsafe_math_optimizations"
17196 {
17197   rtx op0 = gen_reg_rtx (XFmode);
17198   rtx op1 = gen_reg_rtx (XFmode);
17199
17200   if (optimize_insn_for_size_p ())
17201     FAIL;
17202
17203   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17204   emit_insn (gen_asinxf2 (op0, op1));
17205   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17206   DONE;
17207 })
17208
17209 (define_expand "acosxf2"
17210   [(set (match_dup 2)
17211         (mult:XF (match_operand:XF 1 "register_operand" "")
17212                  (match_dup 1)))
17213    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17214    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17215    (parallel [(set (match_operand:XF 0 "register_operand" "")
17216                    (unspec:XF [(match_dup 1) (match_dup 5)]
17217                               UNSPEC_FPATAN))
17218               (clobber (match_scratch:XF 6 ""))])]
17219   "TARGET_USE_FANCY_MATH_387
17220    && flag_unsafe_math_optimizations"
17221 {
17222   int i;
17223
17224   if (optimize_insn_for_size_p ())
17225     FAIL;
17226
17227   for (i = 2; i < 6; i++)
17228     operands[i] = gen_reg_rtx (XFmode);
17229
17230   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17231 })
17232
17233 (define_expand "acos<mode>2"
17234   [(use (match_operand:MODEF 0 "register_operand" ""))
17235    (use (match_operand:MODEF 1 "general_operand" ""))]
17236  "TARGET_USE_FANCY_MATH_387
17237    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17238        || TARGET_MIX_SSE_I387)
17239    && flag_unsafe_math_optimizations"
17240 {
17241   rtx op0 = gen_reg_rtx (XFmode);
17242   rtx op1 = gen_reg_rtx (XFmode);
17243
17244   if (optimize_insn_for_size_p ())
17245     FAIL;
17246
17247   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17248   emit_insn (gen_acosxf2 (op0, op1));
17249   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17250   DONE;
17251 })
17252
17253 (define_insn "fyl2xxf3_i387"
17254   [(set (match_operand:XF 0 "register_operand" "=f")
17255         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17256                     (match_operand:XF 2 "register_operand" "u")]
17257                    UNSPEC_FYL2X))
17258    (clobber (match_scratch:XF 3 "=2"))]
17259   "TARGET_USE_FANCY_MATH_387
17260    && flag_unsafe_math_optimizations"
17261   "fyl2x"
17262   [(set_attr "type" "fpspc")
17263    (set_attr "mode" "XF")])
17264
17265 (define_insn "fyl2x_extend<mode>xf3_i387"
17266   [(set (match_operand:XF 0 "register_operand" "=f")
17267         (unspec:XF [(float_extend:XF
17268                       (match_operand:MODEF 1 "register_operand" "0"))
17269                     (match_operand:XF 2 "register_operand" "u")]
17270                    UNSPEC_FYL2X))
17271    (clobber (match_scratch:XF 3 "=2"))]
17272   "TARGET_USE_FANCY_MATH_387
17273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17274        || TARGET_MIX_SSE_I387)
17275    && flag_unsafe_math_optimizations"
17276   "fyl2x"
17277   [(set_attr "type" "fpspc")
17278    (set_attr "mode" "XF")])
17279
17280 (define_expand "logxf2"
17281   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17282                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17283                                (match_dup 2)] UNSPEC_FYL2X))
17284               (clobber (match_scratch:XF 3 ""))])]
17285   "TARGET_USE_FANCY_MATH_387
17286    && flag_unsafe_math_optimizations"
17287 {
17288   operands[2] = gen_reg_rtx (XFmode);
17289   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17290 })
17291
17292 (define_expand "log<mode>2"
17293   [(use (match_operand:MODEF 0 "register_operand" ""))
17294    (use (match_operand:MODEF 1 "register_operand" ""))]
17295   "TARGET_USE_FANCY_MATH_387
17296    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17297        || TARGET_MIX_SSE_I387)
17298    && flag_unsafe_math_optimizations"
17299 {
17300   rtx op0 = gen_reg_rtx (XFmode);
17301
17302   rtx op2 = gen_reg_rtx (XFmode);
17303   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17304
17305   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17306   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17307   DONE;
17308 })
17309
17310 (define_expand "log10xf2"
17311   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17312                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17313                                (match_dup 2)] UNSPEC_FYL2X))
17314               (clobber (match_scratch:XF 3 ""))])]
17315   "TARGET_USE_FANCY_MATH_387
17316    && flag_unsafe_math_optimizations"
17317 {
17318   operands[2] = gen_reg_rtx (XFmode);
17319   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17320 })
17321
17322 (define_expand "log10<mode>2"
17323   [(use (match_operand:MODEF 0 "register_operand" ""))
17324    (use (match_operand:MODEF 1 "register_operand" ""))]
17325   "TARGET_USE_FANCY_MATH_387
17326    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17327        || TARGET_MIX_SSE_I387)
17328    && flag_unsafe_math_optimizations"
17329 {
17330   rtx op0 = gen_reg_rtx (XFmode);
17331
17332   rtx op2 = gen_reg_rtx (XFmode);
17333   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17334
17335   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17336   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17337   DONE;
17338 })
17339
17340 (define_expand "log2xf2"
17341   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17342                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17343                                (match_dup 2)] UNSPEC_FYL2X))
17344               (clobber (match_scratch:XF 3 ""))])]
17345   "TARGET_USE_FANCY_MATH_387
17346    && flag_unsafe_math_optimizations"
17347 {
17348   operands[2] = gen_reg_rtx (XFmode);
17349   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17350 })
17351
17352 (define_expand "log2<mode>2"
17353   [(use (match_operand:MODEF 0 "register_operand" ""))
17354    (use (match_operand:MODEF 1 "register_operand" ""))]
17355   "TARGET_USE_FANCY_MATH_387
17356    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17357        || TARGET_MIX_SSE_I387)
17358    && flag_unsafe_math_optimizations"
17359 {
17360   rtx op0 = gen_reg_rtx (XFmode);
17361
17362   rtx op2 = gen_reg_rtx (XFmode);
17363   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17364
17365   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17366   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17367   DONE;
17368 })
17369
17370 (define_insn "fyl2xp1xf3_i387"
17371   [(set (match_operand:XF 0 "register_operand" "=f")
17372         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17373                     (match_operand:XF 2 "register_operand" "u")]
17374                    UNSPEC_FYL2XP1))
17375    (clobber (match_scratch:XF 3 "=2"))]
17376   "TARGET_USE_FANCY_MATH_387
17377    && flag_unsafe_math_optimizations"
17378   "fyl2xp1"
17379   [(set_attr "type" "fpspc")
17380    (set_attr "mode" "XF")])
17381
17382 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17383   [(set (match_operand:XF 0 "register_operand" "=f")
17384         (unspec:XF [(float_extend:XF
17385                       (match_operand:MODEF 1 "register_operand" "0"))
17386                     (match_operand:XF 2 "register_operand" "u")]
17387                    UNSPEC_FYL2XP1))
17388    (clobber (match_scratch:XF 3 "=2"))]
17389   "TARGET_USE_FANCY_MATH_387
17390    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17391        || TARGET_MIX_SSE_I387)
17392    && flag_unsafe_math_optimizations"
17393   "fyl2xp1"
17394   [(set_attr "type" "fpspc")
17395    (set_attr "mode" "XF")])
17396
17397 (define_expand "log1pxf2"
17398   [(use (match_operand:XF 0 "register_operand" ""))
17399    (use (match_operand:XF 1 "register_operand" ""))]
17400   "TARGET_USE_FANCY_MATH_387
17401    && flag_unsafe_math_optimizations"
17402 {
17403   if (optimize_insn_for_size_p ())
17404     FAIL;
17405
17406   ix86_emit_i387_log1p (operands[0], operands[1]);
17407   DONE;
17408 })
17409
17410 (define_expand "log1p<mode>2"
17411   [(use (match_operand:MODEF 0 "register_operand" ""))
17412    (use (match_operand:MODEF 1 "register_operand" ""))]
17413   "TARGET_USE_FANCY_MATH_387
17414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17415        || TARGET_MIX_SSE_I387)
17416    && flag_unsafe_math_optimizations"
17417 {
17418   rtx op0;
17419
17420   if (optimize_insn_for_size_p ())
17421     FAIL;
17422
17423   op0 = gen_reg_rtx (XFmode);
17424
17425   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17426
17427   ix86_emit_i387_log1p (op0, operands[1]);
17428   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17429   DONE;
17430 })
17431
17432 (define_insn "fxtractxf3_i387"
17433   [(set (match_operand:XF 0 "register_operand" "=f")
17434         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17435                    UNSPEC_XTRACT_FRACT))
17436    (set (match_operand:XF 1 "register_operand" "=u")
17437         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17438   "TARGET_USE_FANCY_MATH_387
17439    && flag_unsafe_math_optimizations"
17440   "fxtract"
17441   [(set_attr "type" "fpspc")
17442    (set_attr "mode" "XF")])
17443
17444 (define_insn "fxtract_extend<mode>xf3_i387"
17445   [(set (match_operand:XF 0 "register_operand" "=f")
17446         (unspec:XF [(float_extend:XF
17447                       (match_operand:MODEF 2 "register_operand" "0"))]
17448                    UNSPEC_XTRACT_FRACT))
17449    (set (match_operand:XF 1 "register_operand" "=u")
17450         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17451   "TARGET_USE_FANCY_MATH_387
17452    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17453        || TARGET_MIX_SSE_I387)
17454    && flag_unsafe_math_optimizations"
17455   "fxtract"
17456   [(set_attr "type" "fpspc")
17457    (set_attr "mode" "XF")])
17458
17459 (define_expand "logbxf2"
17460   [(parallel [(set (match_dup 2)
17461                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17462                               UNSPEC_XTRACT_FRACT))
17463               (set (match_operand:XF 0 "register_operand" "")
17464                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17465   "TARGET_USE_FANCY_MATH_387
17466    && flag_unsafe_math_optimizations"
17467 {
17468   operands[2] = gen_reg_rtx (XFmode);
17469 })
17470
17471 (define_expand "logb<mode>2"
17472   [(use (match_operand:MODEF 0 "register_operand" ""))
17473    (use (match_operand:MODEF 1 "register_operand" ""))]
17474   "TARGET_USE_FANCY_MATH_387
17475    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17476        || TARGET_MIX_SSE_I387)
17477    && flag_unsafe_math_optimizations"
17478 {
17479   rtx op0 = gen_reg_rtx (XFmode);
17480   rtx op1 = gen_reg_rtx (XFmode);
17481
17482   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17483   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17484   DONE;
17485 })
17486
17487 (define_expand "ilogbxf2"
17488   [(use (match_operand:SI 0 "register_operand" ""))
17489    (use (match_operand:XF 1 "register_operand" ""))]
17490   "TARGET_USE_FANCY_MATH_387
17491    && flag_unsafe_math_optimizations"
17492 {
17493   rtx op0, op1;
17494
17495   if (optimize_insn_for_size_p ())
17496     FAIL;
17497
17498   op0 = gen_reg_rtx (XFmode);
17499   op1 = gen_reg_rtx (XFmode);
17500
17501   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17502   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17503   DONE;
17504 })
17505
17506 (define_expand "ilogb<mode>2"
17507   [(use (match_operand:SI 0 "register_operand" ""))
17508    (use (match_operand:MODEF 1 "register_operand" ""))]
17509   "TARGET_USE_FANCY_MATH_387
17510    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17511        || TARGET_MIX_SSE_I387)
17512    && flag_unsafe_math_optimizations"
17513 {
17514   rtx op0, op1;
17515
17516   if (optimize_insn_for_size_p ())
17517     FAIL;
17518
17519   op0 = gen_reg_rtx (XFmode);
17520   op1 = gen_reg_rtx (XFmode);
17521
17522   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17523   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17524   DONE;
17525 })
17526
17527 (define_insn "*f2xm1xf2_i387"
17528   [(set (match_operand:XF 0 "register_operand" "=f")
17529         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17530                    UNSPEC_F2XM1))]
17531   "TARGET_USE_FANCY_MATH_387
17532    && flag_unsafe_math_optimizations"
17533   "f2xm1"
17534   [(set_attr "type" "fpspc")
17535    (set_attr "mode" "XF")])
17536
17537 (define_insn "*fscalexf4_i387"
17538   [(set (match_operand:XF 0 "register_operand" "=f")
17539         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17540                     (match_operand:XF 3 "register_operand" "1")]
17541                    UNSPEC_FSCALE_FRACT))
17542    (set (match_operand:XF 1 "register_operand" "=u")
17543         (unspec:XF [(match_dup 2) (match_dup 3)]
17544                    UNSPEC_FSCALE_EXP))]
17545   "TARGET_USE_FANCY_MATH_387
17546    && flag_unsafe_math_optimizations"
17547   "fscale"
17548   [(set_attr "type" "fpspc")
17549    (set_attr "mode" "XF")])
17550
17551 (define_expand "expNcorexf3"
17552   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17553                                (match_operand:XF 2 "register_operand" "")))
17554    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17555    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17556    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17557    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17558    (parallel [(set (match_operand:XF 0 "register_operand" "")
17559                    (unspec:XF [(match_dup 8) (match_dup 4)]
17560                               UNSPEC_FSCALE_FRACT))
17561               (set (match_dup 9)
17562                    (unspec:XF [(match_dup 8) (match_dup 4)]
17563                               UNSPEC_FSCALE_EXP))])]
17564   "TARGET_USE_FANCY_MATH_387
17565    && flag_unsafe_math_optimizations"
17566 {
17567   int i;
17568
17569   if (optimize_insn_for_size_p ())
17570     FAIL;
17571
17572   for (i = 3; i < 10; i++)
17573     operands[i] = gen_reg_rtx (XFmode);
17574
17575   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17576 })
17577
17578 (define_expand "expxf2"
17579   [(use (match_operand:XF 0 "register_operand" ""))
17580    (use (match_operand:XF 1 "register_operand" ""))]
17581   "TARGET_USE_FANCY_MATH_387
17582    && flag_unsafe_math_optimizations"
17583 {
17584   rtx op2;
17585
17586   if (optimize_insn_for_size_p ())
17587     FAIL;
17588
17589   op2 = gen_reg_rtx (XFmode);
17590   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17591
17592   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17593   DONE;
17594 })
17595
17596 (define_expand "exp<mode>2"
17597   [(use (match_operand:MODEF 0 "register_operand" ""))
17598    (use (match_operand:MODEF 1 "general_operand" ""))]
17599  "TARGET_USE_FANCY_MATH_387
17600    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17601        || TARGET_MIX_SSE_I387)
17602    && flag_unsafe_math_optimizations"
17603 {
17604   rtx op0, op1;
17605
17606   if (optimize_insn_for_size_p ())
17607     FAIL;
17608
17609   op0 = gen_reg_rtx (XFmode);
17610   op1 = gen_reg_rtx (XFmode);
17611
17612   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17613   emit_insn (gen_expxf2 (op0, op1));
17614   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17615   DONE;
17616 })
17617
17618 (define_expand "exp10xf2"
17619   [(use (match_operand:XF 0 "register_operand" ""))
17620    (use (match_operand:XF 1 "register_operand" ""))]
17621   "TARGET_USE_FANCY_MATH_387
17622    && flag_unsafe_math_optimizations"
17623 {
17624   rtx op2;
17625
17626   if (optimize_insn_for_size_p ())
17627     FAIL;
17628
17629   op2 = gen_reg_rtx (XFmode);
17630   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17631
17632   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17633   DONE;
17634 })
17635
17636 (define_expand "exp10<mode>2"
17637   [(use (match_operand:MODEF 0 "register_operand" ""))
17638    (use (match_operand:MODEF 1 "general_operand" ""))]
17639  "TARGET_USE_FANCY_MATH_387
17640    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17641        || TARGET_MIX_SSE_I387)
17642    && flag_unsafe_math_optimizations"
17643 {
17644   rtx op0, op1;
17645
17646   if (optimize_insn_for_size_p ())
17647     FAIL;
17648
17649   op0 = gen_reg_rtx (XFmode);
17650   op1 = gen_reg_rtx (XFmode);
17651
17652   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17653   emit_insn (gen_exp10xf2 (op0, op1));
17654   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17655   DONE;
17656 })
17657
17658 (define_expand "exp2xf2"
17659   [(use (match_operand:XF 0 "register_operand" ""))
17660    (use (match_operand:XF 1 "register_operand" ""))]
17661   "TARGET_USE_FANCY_MATH_387
17662    && flag_unsafe_math_optimizations"
17663 {
17664   rtx op2;
17665
17666   if (optimize_insn_for_size_p ())
17667     FAIL;
17668
17669   op2 = gen_reg_rtx (XFmode);
17670   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17671
17672   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17673   DONE;
17674 })
17675
17676 (define_expand "exp2<mode>2"
17677   [(use (match_operand:MODEF 0 "register_operand" ""))
17678    (use (match_operand:MODEF 1 "general_operand" ""))]
17679  "TARGET_USE_FANCY_MATH_387
17680    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17681        || TARGET_MIX_SSE_I387)
17682    && flag_unsafe_math_optimizations"
17683 {
17684   rtx op0, op1;
17685
17686   if (optimize_insn_for_size_p ())
17687     FAIL;
17688
17689   op0 = gen_reg_rtx (XFmode);
17690   op1 = gen_reg_rtx (XFmode);
17691
17692   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17693   emit_insn (gen_exp2xf2 (op0, op1));
17694   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17695   DONE;
17696 })
17697
17698 (define_expand "expm1xf2"
17699   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17700                                (match_dup 2)))
17701    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17702    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17703    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17704    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17705    (parallel [(set (match_dup 7)
17706                    (unspec:XF [(match_dup 6) (match_dup 4)]
17707                               UNSPEC_FSCALE_FRACT))
17708               (set (match_dup 8)
17709                    (unspec:XF [(match_dup 6) (match_dup 4)]
17710                               UNSPEC_FSCALE_EXP))])
17711    (parallel [(set (match_dup 10)
17712                    (unspec:XF [(match_dup 9) (match_dup 8)]
17713                               UNSPEC_FSCALE_FRACT))
17714               (set (match_dup 11)
17715                    (unspec:XF [(match_dup 9) (match_dup 8)]
17716                               UNSPEC_FSCALE_EXP))])
17717    (set (match_dup 12) (minus:XF (match_dup 10)
17718                                  (float_extend:XF (match_dup 13))))
17719    (set (match_operand:XF 0 "register_operand" "")
17720         (plus:XF (match_dup 12) (match_dup 7)))]
17721   "TARGET_USE_FANCY_MATH_387
17722    && flag_unsafe_math_optimizations"
17723 {
17724   int i;
17725
17726   if (optimize_insn_for_size_p ())
17727     FAIL;
17728
17729   for (i = 2; i < 13; i++)
17730     operands[i] = gen_reg_rtx (XFmode);
17731
17732   operands[13]
17733     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17734
17735   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17736 })
17737
17738 (define_expand "expm1<mode>2"
17739   [(use (match_operand:MODEF 0 "register_operand" ""))
17740    (use (match_operand:MODEF 1 "general_operand" ""))]
17741  "TARGET_USE_FANCY_MATH_387
17742    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17743        || TARGET_MIX_SSE_I387)
17744    && flag_unsafe_math_optimizations"
17745 {
17746   rtx op0, op1;
17747
17748   if (optimize_insn_for_size_p ())
17749     FAIL;
17750
17751   op0 = gen_reg_rtx (XFmode);
17752   op1 = gen_reg_rtx (XFmode);
17753
17754   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17755   emit_insn (gen_expm1xf2 (op0, op1));
17756   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17757   DONE;
17758 })
17759
17760 (define_expand "ldexpxf3"
17761   [(set (match_dup 3)
17762         (float:XF (match_operand:SI 2 "register_operand" "")))
17763    (parallel [(set (match_operand:XF 0 " register_operand" "")
17764                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17765                                (match_dup 3)]
17766                               UNSPEC_FSCALE_FRACT))
17767               (set (match_dup 4)
17768                    (unspec:XF [(match_dup 1) (match_dup 3)]
17769                               UNSPEC_FSCALE_EXP))])]
17770   "TARGET_USE_FANCY_MATH_387
17771    && flag_unsafe_math_optimizations"
17772 {
17773   if (optimize_insn_for_size_p ())
17774     FAIL;
17775
17776   operands[3] = gen_reg_rtx (XFmode);
17777   operands[4] = gen_reg_rtx (XFmode);
17778 })
17779
17780 (define_expand "ldexp<mode>3"
17781   [(use (match_operand:MODEF 0 "register_operand" ""))
17782    (use (match_operand:MODEF 1 "general_operand" ""))
17783    (use (match_operand:SI 2 "register_operand" ""))]
17784  "TARGET_USE_FANCY_MATH_387
17785    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17786        || TARGET_MIX_SSE_I387)
17787    && flag_unsafe_math_optimizations"
17788 {
17789   rtx op0, op1;
17790
17791   if (optimize_insn_for_size_p ())
17792     FAIL;
17793
17794   op0 = gen_reg_rtx (XFmode);
17795   op1 = gen_reg_rtx (XFmode);
17796
17797   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17798   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17799   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17800   DONE;
17801 })
17802
17803 (define_expand "scalbxf3"
17804   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17805                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17806                                (match_operand:XF 2 "register_operand" "")]
17807                               UNSPEC_FSCALE_FRACT))
17808               (set (match_dup 3)
17809                    (unspec:XF [(match_dup 1) (match_dup 2)]
17810                               UNSPEC_FSCALE_EXP))])]
17811   "TARGET_USE_FANCY_MATH_387
17812    && flag_unsafe_math_optimizations"
17813 {
17814   if (optimize_insn_for_size_p ())
17815     FAIL;
17816
17817   operands[3] = gen_reg_rtx (XFmode);
17818 })
17819
17820 (define_expand "scalb<mode>3"
17821   [(use (match_operand:MODEF 0 "register_operand" ""))
17822    (use (match_operand:MODEF 1 "general_operand" ""))
17823    (use (match_operand:MODEF 2 "register_operand" ""))]
17824  "TARGET_USE_FANCY_MATH_387
17825    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17826        || TARGET_MIX_SSE_I387)
17827    && flag_unsafe_math_optimizations"
17828 {
17829   rtx op0, op1, op2;
17830
17831   if (optimize_insn_for_size_p ())
17832     FAIL;
17833
17834   op0 = gen_reg_rtx (XFmode);
17835   op1 = gen_reg_rtx (XFmode);
17836   op2 = gen_reg_rtx (XFmode);
17837
17838   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17839   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17840   emit_insn (gen_scalbxf3 (op0, op1, op2));
17841   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17842   DONE;
17843 })
17844 \f
17845
17846 (define_insn "sse4_1_round<mode>2"
17847   [(set (match_operand:MODEF 0 "register_operand" "=x")
17848         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17849                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17850                       UNSPEC_ROUND))]
17851   "TARGET_ROUND"
17852   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17853   [(set_attr "type" "ssecvt")
17854    (set_attr "prefix_extra" "1")
17855    (set_attr "prefix" "maybe_vex")
17856    (set_attr "mode" "<MODE>")])
17857
17858 (define_insn "rintxf2"
17859   [(set (match_operand:XF 0 "register_operand" "=f")
17860         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17861                    UNSPEC_FRNDINT))]
17862   "TARGET_USE_FANCY_MATH_387
17863    && flag_unsafe_math_optimizations"
17864   "frndint"
17865   [(set_attr "type" "fpspc")
17866    (set_attr "mode" "XF")])
17867
17868 (define_expand "rint<mode>2"
17869   [(use (match_operand:MODEF 0 "register_operand" ""))
17870    (use (match_operand:MODEF 1 "register_operand" ""))]
17871   "(TARGET_USE_FANCY_MATH_387
17872     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17873         || TARGET_MIX_SSE_I387)
17874     && flag_unsafe_math_optimizations)
17875    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17876        && !flag_trapping_math)"
17877 {
17878   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17879       && !flag_trapping_math)
17880     {
17881       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17882         FAIL;
17883       if (TARGET_ROUND)
17884         emit_insn (gen_sse4_1_round<mode>2
17885                    (operands[0], operands[1], GEN_INT (0x04)));
17886       else
17887         ix86_expand_rint (operand0, operand1);
17888     }
17889   else
17890     {
17891       rtx op0 = gen_reg_rtx (XFmode);
17892       rtx op1 = gen_reg_rtx (XFmode);
17893
17894       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17895       emit_insn (gen_rintxf2 (op0, op1));
17896
17897       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17898     }
17899   DONE;
17900 })
17901
17902 (define_expand "round<mode>2"
17903   [(match_operand:MODEF 0 "register_operand" "")
17904    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17905   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17906    && !flag_trapping_math && !flag_rounding_math"
17907 {
17908   if (optimize_insn_for_size_p ())
17909     FAIL;
17910   if (TARGET_64BIT || (<MODE>mode != DFmode))
17911     ix86_expand_round (operand0, operand1);
17912   else
17913     ix86_expand_rounddf_32 (operand0, operand1);
17914   DONE;
17915 })
17916
17917 (define_insn_and_split "*fistdi2_1"
17918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17919         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17920                    UNSPEC_FIST))]
17921   "TARGET_USE_FANCY_MATH_387
17922    && !(reload_completed || reload_in_progress)"
17923   "#"
17924   "&& 1"
17925   [(const_int 0)]
17926 {
17927   if (memory_operand (operands[0], VOIDmode))
17928     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17929   else
17930     {
17931       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17932       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17933                                          operands[2]));
17934     }
17935   DONE;
17936 }
17937   [(set_attr "type" "fpspc")
17938    (set_attr "mode" "DI")])
17939
17940 (define_insn "fistdi2"
17941   [(set (match_operand:DI 0 "memory_operand" "=m")
17942         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17943                    UNSPEC_FIST))
17944    (clobber (match_scratch:XF 2 "=&1f"))]
17945   "TARGET_USE_FANCY_MATH_387"
17946   "* return output_fix_trunc (insn, operands, 0);"
17947   [(set_attr "type" "fpspc")
17948    (set_attr "mode" "DI")])
17949
17950 (define_insn "fistdi2_with_temp"
17951   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17952         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17953                    UNSPEC_FIST))
17954    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17955    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17956   "TARGET_USE_FANCY_MATH_387"
17957   "#"
17958   [(set_attr "type" "fpspc")
17959    (set_attr "mode" "DI")])
17960
17961 (define_split
17962   [(set (match_operand:DI 0 "register_operand" "")
17963         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17964                    UNSPEC_FIST))
17965    (clobber (match_operand:DI 2 "memory_operand" ""))
17966    (clobber (match_scratch 3 ""))]
17967   "reload_completed"
17968   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17969               (clobber (match_dup 3))])
17970    (set (match_dup 0) (match_dup 2))]
17971   "")
17972
17973 (define_split
17974   [(set (match_operand:DI 0 "memory_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 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17981               (clobber (match_dup 3))])]
17982   "")
17983
17984 (define_insn_and_split "*fist<mode>2_1"
17985   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17986         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17987                            UNSPEC_FIST))]
17988   "TARGET_USE_FANCY_MATH_387
17989    && !(reload_completed || reload_in_progress)"
17990   "#"
17991   "&& 1"
17992   [(const_int 0)]
17993 {
17994   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17995   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17996                                         operands[2]));
17997   DONE;
17998 }
17999   [(set_attr "type" "fpspc")
18000    (set_attr "mode" "<MODE>")])
18001
18002 (define_insn "fist<mode>2"
18003   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18004         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18005                            UNSPEC_FIST))]
18006   "TARGET_USE_FANCY_MATH_387"
18007   "* return output_fix_trunc (insn, operands, 0);"
18008   [(set_attr "type" "fpspc")
18009    (set_attr "mode" "<MODE>")])
18010
18011 (define_insn "fist<mode>2_with_temp"
18012   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18013         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18014                            UNSPEC_FIST))
18015    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18016   "TARGET_USE_FANCY_MATH_387"
18017   "#"
18018   [(set_attr "type" "fpspc")
18019    (set_attr "mode" "<MODE>")])
18020
18021 (define_split
18022   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18023         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18024                            UNSPEC_FIST))
18025    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18026   "reload_completed"
18027   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18028    (set (match_dup 0) (match_dup 2))]
18029   "")
18030
18031 (define_split
18032   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18033         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18034                            UNSPEC_FIST))
18035    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18036   "reload_completed"
18037   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18038   "")
18039
18040 (define_expand "lrintxf<mode>2"
18041   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18042      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18043                       UNSPEC_FIST))]
18044   "TARGET_USE_FANCY_MATH_387"
18045   "")
18046
18047 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18048   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18049      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18050                         UNSPEC_FIX_NOTRUNC))]
18051   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18052    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18053   "")
18054
18055 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18056   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18057    (match_operand:MODEF 1 "register_operand" "")]
18058   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18059    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18060    && !flag_trapping_math && !flag_rounding_math"
18061 {
18062   if (optimize_insn_for_size_p ())
18063     FAIL;
18064   ix86_expand_lround (operand0, operand1);
18065   DONE;
18066 })
18067
18068 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18069 (define_insn_and_split "frndintxf2_floor"
18070   [(set (match_operand:XF 0 "register_operand" "")
18071         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18072          UNSPEC_FRNDINT_FLOOR))
18073    (clobber (reg:CC FLAGS_REG))]
18074   "TARGET_USE_FANCY_MATH_387
18075    && flag_unsafe_math_optimizations
18076    && !(reload_completed || reload_in_progress)"
18077   "#"
18078   "&& 1"
18079   [(const_int 0)]
18080 {
18081   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18082
18083   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18084   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18085
18086   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18087                                         operands[2], operands[3]));
18088   DONE;
18089 }
18090   [(set_attr "type" "frndint")
18091    (set_attr "i387_cw" "floor")
18092    (set_attr "mode" "XF")])
18093
18094 (define_insn "frndintxf2_floor_i387"
18095   [(set (match_operand:XF 0 "register_operand" "=f")
18096         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18097          UNSPEC_FRNDINT_FLOOR))
18098    (use (match_operand:HI 2 "memory_operand" "m"))
18099    (use (match_operand:HI 3 "memory_operand" "m"))]
18100   "TARGET_USE_FANCY_MATH_387
18101    && flag_unsafe_math_optimizations"
18102   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18103   [(set_attr "type" "frndint")
18104    (set_attr "i387_cw" "floor")
18105    (set_attr "mode" "XF")])
18106
18107 (define_expand "floorxf2"
18108   [(use (match_operand:XF 0 "register_operand" ""))
18109    (use (match_operand:XF 1 "register_operand" ""))]
18110   "TARGET_USE_FANCY_MATH_387
18111    && flag_unsafe_math_optimizations"
18112 {
18113   if (optimize_insn_for_size_p ())
18114     FAIL;
18115   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18116   DONE;
18117 })
18118
18119 (define_expand "floor<mode>2"
18120   [(use (match_operand:MODEF 0 "register_operand" ""))
18121    (use (match_operand:MODEF 1 "register_operand" ""))]
18122   "(TARGET_USE_FANCY_MATH_387
18123     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18124         || TARGET_MIX_SSE_I387)
18125     && flag_unsafe_math_optimizations)
18126    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18127        && !flag_trapping_math)"
18128 {
18129   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18130       && !flag_trapping_math
18131       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18132     {
18133       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18134         FAIL;
18135       if (TARGET_ROUND)
18136         emit_insn (gen_sse4_1_round<mode>2
18137                    (operands[0], operands[1], GEN_INT (0x01)));
18138       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18139         ix86_expand_floorceil (operand0, operand1, true);
18140       else
18141         ix86_expand_floorceildf_32 (operand0, operand1, true);
18142     }
18143   else
18144     {
18145       rtx op0, op1;
18146
18147       if (optimize_insn_for_size_p ())
18148         FAIL;
18149
18150       op0 = gen_reg_rtx (XFmode);
18151       op1 = gen_reg_rtx (XFmode);
18152       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18153       emit_insn (gen_frndintxf2_floor (op0, op1));
18154
18155       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18156     }
18157   DONE;
18158 })
18159
18160 (define_insn_and_split "*fist<mode>2_floor_1"
18161   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18162         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18163          UNSPEC_FIST_FLOOR))
18164    (clobber (reg:CC FLAGS_REG))]
18165   "TARGET_USE_FANCY_MATH_387
18166    && flag_unsafe_math_optimizations
18167    && !(reload_completed || reload_in_progress)"
18168   "#"
18169   "&& 1"
18170   [(const_int 0)]
18171 {
18172   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18173
18174   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18175   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18176   if (memory_operand (operands[0], VOIDmode))
18177     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18178                                       operands[2], operands[3]));
18179   else
18180     {
18181       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18182       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18183                                                   operands[2], operands[3],
18184                                                   operands[4]));
18185     }
18186   DONE;
18187 }
18188   [(set_attr "type" "fistp")
18189    (set_attr "i387_cw" "floor")
18190    (set_attr "mode" "<MODE>")])
18191
18192 (define_insn "fistdi2_floor"
18193   [(set (match_operand:DI 0 "memory_operand" "=m")
18194         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18195          UNSPEC_FIST_FLOOR))
18196    (use (match_operand:HI 2 "memory_operand" "m"))
18197    (use (match_operand:HI 3 "memory_operand" "m"))
18198    (clobber (match_scratch:XF 4 "=&1f"))]
18199   "TARGET_USE_FANCY_MATH_387
18200    && flag_unsafe_math_optimizations"
18201   "* return output_fix_trunc (insn, operands, 0);"
18202   [(set_attr "type" "fistp")
18203    (set_attr "i387_cw" "floor")
18204    (set_attr "mode" "DI")])
18205
18206 (define_insn "fistdi2_floor_with_temp"
18207   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18208         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18209          UNSPEC_FIST_FLOOR))
18210    (use (match_operand:HI 2 "memory_operand" "m,m"))
18211    (use (match_operand:HI 3 "memory_operand" "m,m"))
18212    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18213    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18214   "TARGET_USE_FANCY_MATH_387
18215    && flag_unsafe_math_optimizations"
18216   "#"
18217   [(set_attr "type" "fistp")
18218    (set_attr "i387_cw" "floor")
18219    (set_attr "mode" "DI")])
18220
18221 (define_split
18222   [(set (match_operand:DI 0 "register_operand" "")
18223         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18224          UNSPEC_FIST_FLOOR))
18225    (use (match_operand:HI 2 "memory_operand" ""))
18226    (use (match_operand:HI 3 "memory_operand" ""))
18227    (clobber (match_operand:DI 4 "memory_operand" ""))
18228    (clobber (match_scratch 5 ""))]
18229   "reload_completed"
18230   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18231               (use (match_dup 2))
18232               (use (match_dup 3))
18233               (clobber (match_dup 5))])
18234    (set (match_dup 0) (match_dup 4))]
18235   "")
18236
18237 (define_split
18238   [(set (match_operand:DI 0 "memory_operand" "")
18239         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18240          UNSPEC_FIST_FLOOR))
18241    (use (match_operand:HI 2 "memory_operand" ""))
18242    (use (match_operand:HI 3 "memory_operand" ""))
18243    (clobber (match_operand:DI 4 "memory_operand" ""))
18244    (clobber (match_scratch 5 ""))]
18245   "reload_completed"
18246   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18247               (use (match_dup 2))
18248               (use (match_dup 3))
18249               (clobber (match_dup 5))])]
18250   "")
18251
18252 (define_insn "fist<mode>2_floor"
18253   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18254         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18255          UNSPEC_FIST_FLOOR))
18256    (use (match_operand:HI 2 "memory_operand" "m"))
18257    (use (match_operand:HI 3 "memory_operand" "m"))]
18258   "TARGET_USE_FANCY_MATH_387
18259    && flag_unsafe_math_optimizations"
18260   "* return output_fix_trunc (insn, operands, 0);"
18261   [(set_attr "type" "fistp")
18262    (set_attr "i387_cw" "floor")
18263    (set_attr "mode" "<MODE>")])
18264
18265 (define_insn "fist<mode>2_floor_with_temp"
18266   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18267         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18268          UNSPEC_FIST_FLOOR))
18269    (use (match_operand:HI 2 "memory_operand" "m,m"))
18270    (use (match_operand:HI 3 "memory_operand" "m,m"))
18271    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18272   "TARGET_USE_FANCY_MATH_387
18273    && flag_unsafe_math_optimizations"
18274   "#"
18275   [(set_attr "type" "fistp")
18276    (set_attr "i387_cw" "floor")
18277    (set_attr "mode" "<MODE>")])
18278
18279 (define_split
18280   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18281         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18282          UNSPEC_FIST_FLOOR))
18283    (use (match_operand:HI 2 "memory_operand" ""))
18284    (use (match_operand:HI 3 "memory_operand" ""))
18285    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18286   "reload_completed"
18287   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18288                                   UNSPEC_FIST_FLOOR))
18289               (use (match_dup 2))
18290               (use (match_dup 3))])
18291    (set (match_dup 0) (match_dup 4))]
18292   "")
18293
18294 (define_split
18295   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18296         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18297          UNSPEC_FIST_FLOOR))
18298    (use (match_operand:HI 2 "memory_operand" ""))
18299    (use (match_operand:HI 3 "memory_operand" ""))
18300    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18301   "reload_completed"
18302   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18303                                   UNSPEC_FIST_FLOOR))
18304               (use (match_dup 2))
18305               (use (match_dup 3))])]
18306   "")
18307
18308 (define_expand "lfloorxf<mode>2"
18309   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18310                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18311                     UNSPEC_FIST_FLOOR))
18312               (clobber (reg:CC FLAGS_REG))])]
18313   "TARGET_USE_FANCY_MATH_387
18314    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18315    && flag_unsafe_math_optimizations"
18316   "")
18317
18318 (define_expand "lfloor<mode>di2"
18319   [(match_operand:DI 0 "nonimmediate_operand" "")
18320    (match_operand:MODEF 1 "register_operand" "")]
18321   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18322    && !flag_trapping_math"
18323 {
18324   if (optimize_insn_for_size_p ())
18325     FAIL;
18326   ix86_expand_lfloorceil (operand0, operand1, true);
18327   DONE;
18328 })
18329
18330 (define_expand "lfloor<mode>si2"
18331   [(match_operand:SI 0 "nonimmediate_operand" "")
18332    (match_operand:MODEF 1 "register_operand" "")]
18333   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18334    && !flag_trapping_math"
18335 {
18336   if (optimize_insn_for_size_p () && TARGET_64BIT)
18337     FAIL;
18338   ix86_expand_lfloorceil (operand0, operand1, true);
18339   DONE;
18340 })
18341
18342 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18343 (define_insn_and_split "frndintxf2_ceil"
18344   [(set (match_operand:XF 0 "register_operand" "")
18345         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18346          UNSPEC_FRNDINT_CEIL))
18347    (clobber (reg:CC FLAGS_REG))]
18348   "TARGET_USE_FANCY_MATH_387
18349    && flag_unsafe_math_optimizations
18350    && !(reload_completed || reload_in_progress)"
18351   "#"
18352   "&& 1"
18353   [(const_int 0)]
18354 {
18355   ix86_optimize_mode_switching[I387_CEIL] = 1;
18356
18357   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18358   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18359
18360   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18361                                        operands[2], operands[3]));
18362   DONE;
18363 }
18364   [(set_attr "type" "frndint")
18365    (set_attr "i387_cw" "ceil")
18366    (set_attr "mode" "XF")])
18367
18368 (define_insn "frndintxf2_ceil_i387"
18369   [(set (match_operand:XF 0 "register_operand" "=f")
18370         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18371          UNSPEC_FRNDINT_CEIL))
18372    (use (match_operand:HI 2 "memory_operand" "m"))
18373    (use (match_operand:HI 3 "memory_operand" "m"))]
18374   "TARGET_USE_FANCY_MATH_387
18375    && flag_unsafe_math_optimizations"
18376   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18377   [(set_attr "type" "frndint")
18378    (set_attr "i387_cw" "ceil")
18379    (set_attr "mode" "XF")])
18380
18381 (define_expand "ceilxf2"
18382   [(use (match_operand:XF 0 "register_operand" ""))
18383    (use (match_operand:XF 1 "register_operand" ""))]
18384   "TARGET_USE_FANCY_MATH_387
18385    && flag_unsafe_math_optimizations"
18386 {
18387   if (optimize_insn_for_size_p ())
18388     FAIL;
18389   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18390   DONE;
18391 })
18392
18393 (define_expand "ceil<mode>2"
18394   [(use (match_operand:MODEF 0 "register_operand" ""))
18395    (use (match_operand:MODEF 1 "register_operand" ""))]
18396   "(TARGET_USE_FANCY_MATH_387
18397     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18398         || TARGET_MIX_SSE_I387)
18399     && flag_unsafe_math_optimizations)
18400    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18401        && !flag_trapping_math)"
18402 {
18403   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18404       && !flag_trapping_math
18405       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18406     {
18407       if (TARGET_ROUND)
18408         emit_insn (gen_sse4_1_round<mode>2
18409                    (operands[0], operands[1], GEN_INT (0x02)));
18410       else if (optimize_insn_for_size_p ())
18411         FAIL;
18412       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18413         ix86_expand_floorceil (operand0, operand1, false);
18414       else
18415         ix86_expand_floorceildf_32 (operand0, operand1, false);
18416     }
18417   else
18418     {
18419       rtx op0, op1;
18420
18421       if (optimize_insn_for_size_p ())
18422         FAIL;
18423
18424       op0 = gen_reg_rtx (XFmode);
18425       op1 = gen_reg_rtx (XFmode);
18426       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18427       emit_insn (gen_frndintxf2_ceil (op0, op1));
18428
18429       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18430     }
18431   DONE;
18432 })
18433
18434 (define_insn_and_split "*fist<mode>2_ceil_1"
18435   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18436         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18437          UNSPEC_FIST_CEIL))
18438    (clobber (reg:CC FLAGS_REG))]
18439   "TARGET_USE_FANCY_MATH_387
18440    && flag_unsafe_math_optimizations
18441    && !(reload_completed || reload_in_progress)"
18442   "#"
18443   "&& 1"
18444   [(const_int 0)]
18445 {
18446   ix86_optimize_mode_switching[I387_CEIL] = 1;
18447
18448   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18449   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18450   if (memory_operand (operands[0], VOIDmode))
18451     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18452                                      operands[2], operands[3]));
18453   else
18454     {
18455       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18456       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18457                                                  operands[2], operands[3],
18458                                                  operands[4]));
18459     }
18460   DONE;
18461 }
18462   [(set_attr "type" "fistp")
18463    (set_attr "i387_cw" "ceil")
18464    (set_attr "mode" "<MODE>")])
18465
18466 (define_insn "fistdi2_ceil"
18467   [(set (match_operand:DI 0 "memory_operand" "=m")
18468         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18469          UNSPEC_FIST_CEIL))
18470    (use (match_operand:HI 2 "memory_operand" "m"))
18471    (use (match_operand:HI 3 "memory_operand" "m"))
18472    (clobber (match_scratch:XF 4 "=&1f"))]
18473   "TARGET_USE_FANCY_MATH_387
18474    && flag_unsafe_math_optimizations"
18475   "* return output_fix_trunc (insn, operands, 0);"
18476   [(set_attr "type" "fistp")
18477    (set_attr "i387_cw" "ceil")
18478    (set_attr "mode" "DI")])
18479
18480 (define_insn "fistdi2_ceil_with_temp"
18481   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18482         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18483          UNSPEC_FIST_CEIL))
18484    (use (match_operand:HI 2 "memory_operand" "m,m"))
18485    (use (match_operand:HI 3 "memory_operand" "m,m"))
18486    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18487    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18488   "TARGET_USE_FANCY_MATH_387
18489    && flag_unsafe_math_optimizations"
18490   "#"
18491   [(set_attr "type" "fistp")
18492    (set_attr "i387_cw" "ceil")
18493    (set_attr "mode" "DI")])
18494
18495 (define_split
18496   [(set (match_operand:DI 0 "register_operand" "")
18497         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18498          UNSPEC_FIST_CEIL))
18499    (use (match_operand:HI 2 "memory_operand" ""))
18500    (use (match_operand:HI 3 "memory_operand" ""))
18501    (clobber (match_operand:DI 4 "memory_operand" ""))
18502    (clobber (match_scratch 5 ""))]
18503   "reload_completed"
18504   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18505               (use (match_dup 2))
18506               (use (match_dup 3))
18507               (clobber (match_dup 5))])
18508    (set (match_dup 0) (match_dup 4))]
18509   "")
18510
18511 (define_split
18512   [(set (match_operand:DI 0 "memory_operand" "")
18513         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18514          UNSPEC_FIST_CEIL))
18515    (use (match_operand:HI 2 "memory_operand" ""))
18516    (use (match_operand:HI 3 "memory_operand" ""))
18517    (clobber (match_operand:DI 4 "memory_operand" ""))
18518    (clobber (match_scratch 5 ""))]
18519   "reload_completed"
18520   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18521               (use (match_dup 2))
18522               (use (match_dup 3))
18523               (clobber (match_dup 5))])]
18524   "")
18525
18526 (define_insn "fist<mode>2_ceil"
18527   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18528         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18529          UNSPEC_FIST_CEIL))
18530    (use (match_operand:HI 2 "memory_operand" "m"))
18531    (use (match_operand:HI 3 "memory_operand" "m"))]
18532   "TARGET_USE_FANCY_MATH_387
18533    && flag_unsafe_math_optimizations"
18534   "* return output_fix_trunc (insn, operands, 0);"
18535   [(set_attr "type" "fistp")
18536    (set_attr "i387_cw" "ceil")
18537    (set_attr "mode" "<MODE>")])
18538
18539 (define_insn "fist<mode>2_ceil_with_temp"
18540   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18541         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18542          UNSPEC_FIST_CEIL))
18543    (use (match_operand:HI 2 "memory_operand" "m,m"))
18544    (use (match_operand:HI 3 "memory_operand" "m,m"))
18545    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18546   "TARGET_USE_FANCY_MATH_387
18547    && flag_unsafe_math_optimizations"
18548   "#"
18549   [(set_attr "type" "fistp")
18550    (set_attr "i387_cw" "ceil")
18551    (set_attr "mode" "<MODE>")])
18552
18553 (define_split
18554   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18555         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18556          UNSPEC_FIST_CEIL))
18557    (use (match_operand:HI 2 "memory_operand" ""))
18558    (use (match_operand:HI 3 "memory_operand" ""))
18559    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18560   "reload_completed"
18561   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18562                                   UNSPEC_FIST_CEIL))
18563               (use (match_dup 2))
18564               (use (match_dup 3))])
18565    (set (match_dup 0) (match_dup 4))]
18566   "")
18567
18568 (define_split
18569   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18570         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18571          UNSPEC_FIST_CEIL))
18572    (use (match_operand:HI 2 "memory_operand" ""))
18573    (use (match_operand:HI 3 "memory_operand" ""))
18574    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18575   "reload_completed"
18576   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18577                                   UNSPEC_FIST_CEIL))
18578               (use (match_dup 2))
18579               (use (match_dup 3))])]
18580   "")
18581
18582 (define_expand "lceilxf<mode>2"
18583   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18584                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18585                     UNSPEC_FIST_CEIL))
18586               (clobber (reg:CC FLAGS_REG))])]
18587   "TARGET_USE_FANCY_MATH_387
18588    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18589    && flag_unsafe_math_optimizations"
18590   "")
18591
18592 (define_expand "lceil<mode>di2"
18593   [(match_operand:DI 0 "nonimmediate_operand" "")
18594    (match_operand:MODEF 1 "register_operand" "")]
18595   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18596    && !flag_trapping_math"
18597 {
18598   ix86_expand_lfloorceil (operand0, operand1, false);
18599   DONE;
18600 })
18601
18602 (define_expand "lceil<mode>si2"
18603   [(match_operand:SI 0 "nonimmediate_operand" "")
18604    (match_operand:MODEF 1 "register_operand" "")]
18605   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18606    && !flag_trapping_math"
18607 {
18608   ix86_expand_lfloorceil (operand0, operand1, false);
18609   DONE;
18610 })
18611
18612 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18613 (define_insn_and_split "frndintxf2_trunc"
18614   [(set (match_operand:XF 0 "register_operand" "")
18615         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18616          UNSPEC_FRNDINT_TRUNC))
18617    (clobber (reg:CC FLAGS_REG))]
18618   "TARGET_USE_FANCY_MATH_387
18619    && flag_unsafe_math_optimizations
18620    && !(reload_completed || reload_in_progress)"
18621   "#"
18622   "&& 1"
18623   [(const_int 0)]
18624 {
18625   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18626
18627   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18628   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18629
18630   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18631                                         operands[2], operands[3]));
18632   DONE;
18633 }
18634   [(set_attr "type" "frndint")
18635    (set_attr "i387_cw" "trunc")
18636    (set_attr "mode" "XF")])
18637
18638 (define_insn "frndintxf2_trunc_i387"
18639   [(set (match_operand:XF 0 "register_operand" "=f")
18640         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18641          UNSPEC_FRNDINT_TRUNC))
18642    (use (match_operand:HI 2 "memory_operand" "m"))
18643    (use (match_operand:HI 3 "memory_operand" "m"))]
18644   "TARGET_USE_FANCY_MATH_387
18645    && flag_unsafe_math_optimizations"
18646   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18647   [(set_attr "type" "frndint")
18648    (set_attr "i387_cw" "trunc")
18649    (set_attr "mode" "XF")])
18650
18651 (define_expand "btruncxf2"
18652   [(use (match_operand:XF 0 "register_operand" ""))
18653    (use (match_operand:XF 1 "register_operand" ""))]
18654   "TARGET_USE_FANCY_MATH_387
18655    && flag_unsafe_math_optimizations"
18656 {
18657   if (optimize_insn_for_size_p ())
18658     FAIL;
18659   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18660   DONE;
18661 })
18662
18663 (define_expand "btrunc<mode>2"
18664   [(use (match_operand:MODEF 0 "register_operand" ""))
18665    (use (match_operand:MODEF 1 "register_operand" ""))]
18666   "(TARGET_USE_FANCY_MATH_387
18667     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18668         || TARGET_MIX_SSE_I387)
18669     && flag_unsafe_math_optimizations)
18670    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18671        && !flag_trapping_math)"
18672 {
18673   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18674       && !flag_trapping_math
18675       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18676     {
18677       if (TARGET_ROUND)
18678         emit_insn (gen_sse4_1_round<mode>2
18679                    (operands[0], operands[1], GEN_INT (0x03)));
18680       else if (optimize_insn_for_size_p ())
18681         FAIL;
18682       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18683         ix86_expand_trunc (operand0, operand1);
18684       else
18685         ix86_expand_truncdf_32 (operand0, operand1);
18686     }
18687   else
18688     {
18689       rtx op0, op1;
18690
18691       if (optimize_insn_for_size_p ())
18692         FAIL;
18693
18694       op0 = gen_reg_rtx (XFmode);
18695       op1 = gen_reg_rtx (XFmode);
18696       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18697       emit_insn (gen_frndintxf2_trunc (op0, op1));
18698
18699       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18700     }
18701   DONE;
18702 })
18703
18704 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18705 (define_insn_and_split "frndintxf2_mask_pm"
18706   [(set (match_operand:XF 0 "register_operand" "")
18707         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18708          UNSPEC_FRNDINT_MASK_PM))
18709    (clobber (reg:CC FLAGS_REG))]
18710   "TARGET_USE_FANCY_MATH_387
18711    && flag_unsafe_math_optimizations
18712    && !(reload_completed || reload_in_progress)"
18713   "#"
18714   "&& 1"
18715   [(const_int 0)]
18716 {
18717   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18718
18719   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18720   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18721
18722   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18723                                           operands[2], operands[3]));
18724   DONE;
18725 }
18726   [(set_attr "type" "frndint")
18727    (set_attr "i387_cw" "mask_pm")
18728    (set_attr "mode" "XF")])
18729
18730 (define_insn "frndintxf2_mask_pm_i387"
18731   [(set (match_operand:XF 0 "register_operand" "=f")
18732         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18733          UNSPEC_FRNDINT_MASK_PM))
18734    (use (match_operand:HI 2 "memory_operand" "m"))
18735    (use (match_operand:HI 3 "memory_operand" "m"))]
18736   "TARGET_USE_FANCY_MATH_387
18737    && flag_unsafe_math_optimizations"
18738   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18739   [(set_attr "type" "frndint")
18740    (set_attr "i387_cw" "mask_pm")
18741    (set_attr "mode" "XF")])
18742
18743 (define_expand "nearbyintxf2"
18744   [(use (match_operand:XF 0 "register_operand" ""))
18745    (use (match_operand:XF 1 "register_operand" ""))]
18746   "TARGET_USE_FANCY_MATH_387
18747    && flag_unsafe_math_optimizations"
18748 {
18749   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18750
18751   DONE;
18752 })
18753
18754 (define_expand "nearbyint<mode>2"
18755   [(use (match_operand:MODEF 0 "register_operand" ""))
18756    (use (match_operand:MODEF 1 "register_operand" ""))]
18757   "TARGET_USE_FANCY_MATH_387
18758    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18759        || TARGET_MIX_SSE_I387)
18760    && flag_unsafe_math_optimizations"
18761 {
18762   rtx op0 = gen_reg_rtx (XFmode);
18763   rtx op1 = gen_reg_rtx (XFmode);
18764
18765   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18766   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18767
18768   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18769   DONE;
18770 })
18771
18772 (define_insn "fxam<mode>2_i387"
18773   [(set (match_operand:HI 0 "register_operand" "=a")
18774         (unspec:HI
18775           [(match_operand:X87MODEF 1 "register_operand" "f")]
18776           UNSPEC_FXAM))]
18777   "TARGET_USE_FANCY_MATH_387"
18778   "fxam\n\tfnstsw\t%0"
18779   [(set_attr "type" "multi")
18780    (set_attr "unit" "i387")
18781    (set_attr "mode" "<MODE>")])
18782
18783 (define_expand "isinf<mode>2"
18784   [(use (match_operand:SI 0 "register_operand" ""))
18785    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18786   "TARGET_USE_FANCY_MATH_387
18787    && TARGET_C99_FUNCTIONS
18788    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18789 {
18790   rtx mask = GEN_INT (0x45);
18791   rtx val = GEN_INT (0x05);
18792
18793   rtx cond;
18794
18795   rtx scratch = gen_reg_rtx (HImode);
18796   rtx res = gen_reg_rtx (QImode);
18797
18798   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18799   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18800   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18801   cond = gen_rtx_fmt_ee (EQ, QImode,
18802                          gen_rtx_REG (CCmode, FLAGS_REG),
18803                          const0_rtx);
18804   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18805   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18806   DONE;
18807 })
18808
18809 (define_expand "signbit<mode>2"
18810   [(use (match_operand:SI 0 "register_operand" ""))
18811    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18812   "TARGET_USE_FANCY_MATH_387
18813    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18814 {
18815   rtx mask = GEN_INT (0x0200);
18816
18817   rtx scratch = gen_reg_rtx (HImode);
18818
18819   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18820   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18821   DONE;
18822 })
18823 \f
18824 ;; Block operation instructions
18825
18826 (define_insn "cld"
18827   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18828   ""
18829   "cld"
18830   [(set_attr "length" "1")
18831    (set_attr "length_immediate" "0")
18832    (set_attr "modrm" "0")])
18833
18834 (define_expand "movmemsi"
18835   [(use (match_operand:BLK 0 "memory_operand" ""))
18836    (use (match_operand:BLK 1 "memory_operand" ""))
18837    (use (match_operand:SI 2 "nonmemory_operand" ""))
18838    (use (match_operand:SI 3 "const_int_operand" ""))
18839    (use (match_operand:SI 4 "const_int_operand" ""))
18840    (use (match_operand:SI 5 "const_int_operand" ""))]
18841   ""
18842 {
18843  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18844                          operands[4], operands[5]))
18845    DONE;
18846  else
18847    FAIL;
18848 })
18849
18850 (define_expand "movmemdi"
18851   [(use (match_operand:BLK 0 "memory_operand" ""))
18852    (use (match_operand:BLK 1 "memory_operand" ""))
18853    (use (match_operand:DI 2 "nonmemory_operand" ""))
18854    (use (match_operand:DI 3 "const_int_operand" ""))
18855    (use (match_operand:SI 4 "const_int_operand" ""))
18856    (use (match_operand:SI 5 "const_int_operand" ""))]
18857   "TARGET_64BIT"
18858 {
18859  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18860                          operands[4], operands[5]))
18861    DONE;
18862  else
18863    FAIL;
18864 })
18865
18866 ;; Most CPUs don't like single string operations
18867 ;; Handle this case here to simplify previous expander.
18868
18869 (define_expand "strmov"
18870   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18871    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18872    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18873               (clobber (reg:CC FLAGS_REG))])
18874    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18875               (clobber (reg:CC FLAGS_REG))])]
18876   ""
18877 {
18878   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18879
18880   /* If .md ever supports :P for Pmode, these can be directly
18881      in the pattern above.  */
18882   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18883   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18884
18885   /* Can't use this if the user has appropriated esi or edi.  */
18886   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18887       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18888     {
18889       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18890                                       operands[2], operands[3],
18891                                       operands[5], operands[6]));
18892       DONE;
18893     }
18894
18895   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18896 })
18897
18898 (define_expand "strmov_singleop"
18899   [(parallel [(set (match_operand 1 "memory_operand" "")
18900                    (match_operand 3 "memory_operand" ""))
18901               (set (match_operand 0 "register_operand" "")
18902                    (match_operand 4 "" ""))
18903               (set (match_operand 2 "register_operand" "")
18904                    (match_operand 5 "" ""))])]
18905   ""
18906   "ix86_current_function_needs_cld = 1;")
18907
18908 (define_insn "*strmovdi_rex_1"
18909   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18910         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18911    (set (match_operand:DI 0 "register_operand" "=D")
18912         (plus:DI (match_dup 2)
18913                  (const_int 8)))
18914    (set (match_operand:DI 1 "register_operand" "=S")
18915         (plus:DI (match_dup 3)
18916                  (const_int 8)))]
18917   "TARGET_64BIT"
18918   "movsq"
18919   [(set_attr "type" "str")
18920    (set_attr "mode" "DI")
18921    (set_attr "memory" "both")])
18922
18923 (define_insn "*strmovsi_1"
18924   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18925         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18926    (set (match_operand:SI 0 "register_operand" "=D")
18927         (plus:SI (match_dup 2)
18928                  (const_int 4)))
18929    (set (match_operand:SI 1 "register_operand" "=S")
18930         (plus:SI (match_dup 3)
18931                  (const_int 4)))]
18932   "!TARGET_64BIT"
18933   "movs{l|d}"
18934   [(set_attr "type" "str")
18935    (set_attr "mode" "SI")
18936    (set_attr "memory" "both")])
18937
18938 (define_insn "*strmovsi_rex_1"
18939   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18940         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18941    (set (match_operand:DI 0 "register_operand" "=D")
18942         (plus:DI (match_dup 2)
18943                  (const_int 4)))
18944    (set (match_operand:DI 1 "register_operand" "=S")
18945         (plus:DI (match_dup 3)
18946                  (const_int 4)))]
18947   "TARGET_64BIT"
18948   "movs{l|d}"
18949   [(set_attr "type" "str")
18950    (set_attr "mode" "SI")
18951    (set_attr "memory" "both")])
18952
18953 (define_insn "*strmovhi_1"
18954   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18955         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18956    (set (match_operand:SI 0 "register_operand" "=D")
18957         (plus:SI (match_dup 2)
18958                  (const_int 2)))
18959    (set (match_operand:SI 1 "register_operand" "=S")
18960         (plus:SI (match_dup 3)
18961                  (const_int 2)))]
18962   "!TARGET_64BIT"
18963   "movsw"
18964   [(set_attr "type" "str")
18965    (set_attr "memory" "both")
18966    (set_attr "mode" "HI")])
18967
18968 (define_insn "*strmovhi_rex_1"
18969   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18970         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18971    (set (match_operand:DI 0 "register_operand" "=D")
18972         (plus:DI (match_dup 2)
18973                  (const_int 2)))
18974    (set (match_operand:DI 1 "register_operand" "=S")
18975         (plus:DI (match_dup 3)
18976                  (const_int 2)))]
18977   "TARGET_64BIT"
18978   "movsw"
18979   [(set_attr "type" "str")
18980    (set_attr "memory" "both")
18981    (set_attr "mode" "HI")])
18982
18983 (define_insn "*strmovqi_1"
18984   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18985         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18986    (set (match_operand:SI 0 "register_operand" "=D")
18987         (plus:SI (match_dup 2)
18988                  (const_int 1)))
18989    (set (match_operand:SI 1 "register_operand" "=S")
18990         (plus:SI (match_dup 3)
18991                  (const_int 1)))]
18992   "!TARGET_64BIT"
18993   "movsb"
18994   [(set_attr "type" "str")
18995    (set_attr "memory" "both")
18996    (set_attr "mode" "QI")])
18997
18998 (define_insn "*strmovqi_rex_1"
18999   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19000         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19001    (set (match_operand:DI 0 "register_operand" "=D")
19002         (plus:DI (match_dup 2)
19003                  (const_int 1)))
19004    (set (match_operand:DI 1 "register_operand" "=S")
19005         (plus:DI (match_dup 3)
19006                  (const_int 1)))]
19007   "TARGET_64BIT"
19008   "movsb"
19009   [(set_attr "type" "str")
19010    (set_attr "memory" "both")
19011    (set_attr "mode" "QI")])
19012
19013 (define_expand "rep_mov"
19014   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19015               (set (match_operand 0 "register_operand" "")
19016                    (match_operand 5 "" ""))
19017               (set (match_operand 2 "register_operand" "")
19018                    (match_operand 6 "" ""))
19019               (set (match_operand 1 "memory_operand" "")
19020                    (match_operand 3 "memory_operand" ""))
19021               (use (match_dup 4))])]
19022   ""
19023   "ix86_current_function_needs_cld = 1;")
19024
19025 (define_insn "*rep_movdi_rex64"
19026   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19027    (set (match_operand:DI 0 "register_operand" "=D")
19028         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19029                             (const_int 3))
19030                  (match_operand:DI 3 "register_operand" "0")))
19031    (set (match_operand:DI 1 "register_operand" "=S")
19032         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19033                  (match_operand:DI 4 "register_operand" "1")))
19034    (set (mem:BLK (match_dup 3))
19035         (mem:BLK (match_dup 4)))
19036    (use (match_dup 5))]
19037   "TARGET_64BIT"
19038   "rep movsq"
19039   [(set_attr "type" "str")
19040    (set_attr "prefix_rep" "1")
19041    (set_attr "memory" "both")
19042    (set_attr "mode" "DI")])
19043
19044 (define_insn "*rep_movsi"
19045   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19046    (set (match_operand:SI 0 "register_operand" "=D")
19047         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19048                             (const_int 2))
19049                  (match_operand:SI 3 "register_operand" "0")))
19050    (set (match_operand:SI 1 "register_operand" "=S")
19051         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19052                  (match_operand:SI 4 "register_operand" "1")))
19053    (set (mem:BLK (match_dup 3))
19054         (mem:BLK (match_dup 4)))
19055    (use (match_dup 5))]
19056   "!TARGET_64BIT"
19057   "rep movs{l|d}"
19058   [(set_attr "type" "str")
19059    (set_attr "prefix_rep" "1")
19060    (set_attr "memory" "both")
19061    (set_attr "mode" "SI")])
19062
19063 (define_insn "*rep_movsi_rex64"
19064   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19065    (set (match_operand:DI 0 "register_operand" "=D")
19066         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19067                             (const_int 2))
19068                  (match_operand:DI 3 "register_operand" "0")))
19069    (set (match_operand:DI 1 "register_operand" "=S")
19070         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19071                  (match_operand:DI 4 "register_operand" "1")))
19072    (set (mem:BLK (match_dup 3))
19073         (mem:BLK (match_dup 4)))
19074    (use (match_dup 5))]
19075   "TARGET_64BIT"
19076   "rep movs{l|d}"
19077   [(set_attr "type" "str")
19078    (set_attr "prefix_rep" "1")
19079    (set_attr "memory" "both")
19080    (set_attr "mode" "SI")])
19081
19082 (define_insn "*rep_movqi"
19083   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19084    (set (match_operand:SI 0 "register_operand" "=D")
19085         (plus:SI (match_operand:SI 3 "register_operand" "0")
19086                  (match_operand:SI 5 "register_operand" "2")))
19087    (set (match_operand:SI 1 "register_operand" "=S")
19088         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19089    (set (mem:BLK (match_dup 3))
19090         (mem:BLK (match_dup 4)))
19091    (use (match_dup 5))]
19092   "!TARGET_64BIT"
19093   "rep movsb"
19094   [(set_attr "type" "str")
19095    (set_attr "prefix_rep" "1")
19096    (set_attr "memory" "both")
19097    (set_attr "mode" "SI")])
19098
19099 (define_insn "*rep_movqi_rex64"
19100   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19101    (set (match_operand:DI 0 "register_operand" "=D")
19102         (plus:DI (match_operand:DI 3 "register_operand" "0")
19103                  (match_operand:DI 5 "register_operand" "2")))
19104    (set (match_operand:DI 1 "register_operand" "=S")
19105         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19106    (set (mem:BLK (match_dup 3))
19107         (mem:BLK (match_dup 4)))
19108    (use (match_dup 5))]
19109   "TARGET_64BIT"
19110   "rep movsb"
19111   [(set_attr "type" "str")
19112    (set_attr "prefix_rep" "1")
19113    (set_attr "memory" "both")
19114    (set_attr "mode" "SI")])
19115
19116 (define_expand "setmemsi"
19117    [(use (match_operand:BLK 0 "memory_operand" ""))
19118     (use (match_operand:SI 1 "nonmemory_operand" ""))
19119     (use (match_operand 2 "const_int_operand" ""))
19120     (use (match_operand 3 "const_int_operand" ""))
19121     (use (match_operand:SI 4 "const_int_operand" ""))
19122     (use (match_operand:SI 5 "const_int_operand" ""))]
19123   ""
19124 {
19125  if (ix86_expand_setmem (operands[0], operands[1],
19126                          operands[2], operands[3],
19127                          operands[4], operands[5]))
19128    DONE;
19129  else
19130    FAIL;
19131 })
19132
19133 (define_expand "setmemdi"
19134    [(use (match_operand:BLK 0 "memory_operand" ""))
19135     (use (match_operand:DI 1 "nonmemory_operand" ""))
19136     (use (match_operand 2 "const_int_operand" ""))
19137     (use (match_operand 3 "const_int_operand" ""))
19138     (use (match_operand 4 "const_int_operand" ""))
19139     (use (match_operand 5 "const_int_operand" ""))]
19140   "TARGET_64BIT"
19141 {
19142  if (ix86_expand_setmem (operands[0], operands[1],
19143                          operands[2], operands[3],
19144                          operands[4], operands[5]))
19145    DONE;
19146  else
19147    FAIL;
19148 })
19149
19150 ;; Most CPUs don't like single string operations
19151 ;; Handle this case here to simplify previous expander.
19152
19153 (define_expand "strset"
19154   [(set (match_operand 1 "memory_operand" "")
19155         (match_operand 2 "register_operand" ""))
19156    (parallel [(set (match_operand 0 "register_operand" "")
19157                    (match_dup 3))
19158               (clobber (reg:CC FLAGS_REG))])]
19159   ""
19160 {
19161   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19162     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19163
19164   /* If .md ever supports :P for Pmode, this can be directly
19165      in the pattern above.  */
19166   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19167                               GEN_INT (GET_MODE_SIZE (GET_MODE
19168                                                       (operands[2]))));
19169   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19170     {
19171       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19172                                       operands[3]));
19173       DONE;
19174     }
19175 })
19176
19177 (define_expand "strset_singleop"
19178   [(parallel [(set (match_operand 1 "memory_operand" "")
19179                    (match_operand 2 "register_operand" ""))
19180               (set (match_operand 0 "register_operand" "")
19181                    (match_operand 3 "" ""))])]
19182   ""
19183   "ix86_current_function_needs_cld = 1;")
19184
19185 (define_insn "*strsetdi_rex_1"
19186   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19187         (match_operand:DI 2 "register_operand" "a"))
19188    (set (match_operand:DI 0 "register_operand" "=D")
19189         (plus:DI (match_dup 1)
19190                  (const_int 8)))]
19191   "TARGET_64BIT"
19192   "stosq"
19193   [(set_attr "type" "str")
19194    (set_attr "memory" "store")
19195    (set_attr "mode" "DI")])
19196
19197 (define_insn "*strsetsi_1"
19198   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19199         (match_operand:SI 2 "register_operand" "a"))
19200    (set (match_operand:SI 0 "register_operand" "=D")
19201         (plus:SI (match_dup 1)
19202                  (const_int 4)))]
19203   "!TARGET_64BIT"
19204   "stos{l|d}"
19205   [(set_attr "type" "str")
19206    (set_attr "memory" "store")
19207    (set_attr "mode" "SI")])
19208
19209 (define_insn "*strsetsi_rex_1"
19210   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19211         (match_operand:SI 2 "register_operand" "a"))
19212    (set (match_operand:DI 0 "register_operand" "=D")
19213         (plus:DI (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 "*strsethi_1"
19222   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19223         (match_operand:HI 2 "register_operand" "a"))
19224    (set (match_operand:SI 0 "register_operand" "=D")
19225         (plus:SI (match_dup 1)
19226                  (const_int 2)))]
19227   "!TARGET_64BIT"
19228   "stosw"
19229   [(set_attr "type" "str")
19230    (set_attr "memory" "store")
19231    (set_attr "mode" "HI")])
19232
19233 (define_insn "*strsethi_rex_1"
19234   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19235         (match_operand:HI 2 "register_operand" "a"))
19236    (set (match_operand:DI 0 "register_operand" "=D")
19237         (plus:DI (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 "*strsetqi_1"
19246   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19247         (match_operand:QI 2 "register_operand" "a"))
19248    (set (match_operand:SI 0 "register_operand" "=D")
19249         (plus:SI (match_dup 1)
19250                  (const_int 1)))]
19251   "!TARGET_64BIT"
19252   "stosb"
19253   [(set_attr "type" "str")
19254    (set_attr "memory" "store")
19255    (set_attr "mode" "QI")])
19256
19257 (define_insn "*strsetqi_rex_1"
19258   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19259         (match_operand:QI 2 "register_operand" "a"))
19260    (set (match_operand:DI 0 "register_operand" "=D")
19261         (plus:DI (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_expand "rep_stos"
19270   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19271               (set (match_operand 0 "register_operand" "")
19272                    (match_operand 4 "" ""))
19273               (set (match_operand 2 "memory_operand" "") (const_int 0))
19274               (use (match_operand 3 "register_operand" ""))
19275               (use (match_dup 1))])]
19276   ""
19277   "ix86_current_function_needs_cld = 1;")
19278
19279 (define_insn "*rep_stosdi_rex64"
19280   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19281    (set (match_operand:DI 0 "register_operand" "=D")
19282         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19283                             (const_int 3))
19284                  (match_operand:DI 3 "register_operand" "0")))
19285    (set (mem:BLK (match_dup 3))
19286         (const_int 0))
19287    (use (match_operand:DI 2 "register_operand" "a"))
19288    (use (match_dup 4))]
19289   "TARGET_64BIT"
19290   "rep stosq"
19291   [(set_attr "type" "str")
19292    (set_attr "prefix_rep" "1")
19293    (set_attr "memory" "store")
19294    (set_attr "mode" "DI")])
19295
19296 (define_insn "*rep_stossi"
19297   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19298    (set (match_operand:SI 0 "register_operand" "=D")
19299         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19300                             (const_int 2))
19301                  (match_operand:SI 3 "register_operand" "0")))
19302    (set (mem:BLK (match_dup 3))
19303         (const_int 0))
19304    (use (match_operand:SI 2 "register_operand" "a"))
19305    (use (match_dup 4))]
19306   "!TARGET_64BIT"
19307   "rep stos{l|d}"
19308   [(set_attr "type" "str")
19309    (set_attr "prefix_rep" "1")
19310    (set_attr "memory" "store")
19311    (set_attr "mode" "SI")])
19312
19313 (define_insn "*rep_stossi_rex64"
19314   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19315    (set (match_operand:DI 0 "register_operand" "=D")
19316         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19317                             (const_int 2))
19318                  (match_operand:DI 3 "register_operand" "0")))
19319    (set (mem:BLK (match_dup 3))
19320         (const_int 0))
19321    (use (match_operand:SI 2 "register_operand" "a"))
19322    (use (match_dup 4))]
19323   "TARGET_64BIT"
19324   "rep stos{l|d}"
19325   [(set_attr "type" "str")
19326    (set_attr "prefix_rep" "1")
19327    (set_attr "memory" "store")
19328    (set_attr "mode" "SI")])
19329
19330 (define_insn "*rep_stosqi"
19331   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19332    (set (match_operand:SI 0 "register_operand" "=D")
19333         (plus:SI (match_operand:SI 3 "register_operand" "0")
19334                  (match_operand:SI 4 "register_operand" "1")))
19335    (set (mem:BLK (match_dup 3))
19336         (const_int 0))
19337    (use (match_operand:QI 2 "register_operand" "a"))
19338    (use (match_dup 4))]
19339   "!TARGET_64BIT"
19340   "rep stosb"
19341   [(set_attr "type" "str")
19342    (set_attr "prefix_rep" "1")
19343    (set_attr "memory" "store")
19344    (set_attr "mode" "QI")])
19345
19346 (define_insn "*rep_stosqi_rex64"
19347   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19348    (set (match_operand:DI 0 "register_operand" "=D")
19349         (plus:DI (match_operand:DI 3 "register_operand" "0")
19350                  (match_operand:DI 4 "register_operand" "1")))
19351    (set (mem:BLK (match_dup 3))
19352         (const_int 0))
19353    (use (match_operand:QI 2 "register_operand" "a"))
19354    (use (match_dup 4))]
19355   "TARGET_64BIT"
19356   "rep stosb"
19357   [(set_attr "type" "str")
19358    (set_attr "prefix_rep" "1")
19359    (set_attr "memory" "store")
19360    (set_attr "mode" "QI")])
19361
19362 (define_expand "cmpstrnsi"
19363   [(set (match_operand:SI 0 "register_operand" "")
19364         (compare:SI (match_operand:BLK 1 "general_operand" "")
19365                     (match_operand:BLK 2 "general_operand" "")))
19366    (use (match_operand 3 "general_operand" ""))
19367    (use (match_operand 4 "immediate_operand" ""))]
19368   ""
19369 {
19370   rtx addr1, addr2, out, outlow, count, countreg, align;
19371
19372   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19373     FAIL;
19374
19375   /* Can't use this if the user has appropriated esi or edi.  */
19376   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19377     FAIL;
19378
19379   out = operands[0];
19380   if (!REG_P (out))
19381     out = gen_reg_rtx (SImode);
19382
19383   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19384   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19385   if (addr1 != XEXP (operands[1], 0))
19386     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19387   if (addr2 != XEXP (operands[2], 0))
19388     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19389
19390   count = operands[3];
19391   countreg = ix86_zero_extend_to_Pmode (count);
19392
19393   /* %%% Iff we are testing strict equality, we can use known alignment
19394      to good advantage.  This may be possible with combine, particularly
19395      once cc0 is dead.  */
19396   align = operands[4];
19397
19398   if (CONST_INT_P (count))
19399     {
19400       if (INTVAL (count) == 0)
19401         {
19402           emit_move_insn (operands[0], const0_rtx);
19403           DONE;
19404         }
19405       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19406                                      operands[1], operands[2]));
19407     }
19408   else
19409     {
19410       if (TARGET_64BIT)
19411         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19412       else
19413         emit_insn (gen_cmpsi_1 (countreg, countreg));
19414       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19415                                   operands[1], operands[2]));
19416     }
19417
19418   outlow = gen_lowpart (QImode, out);
19419   emit_insn (gen_cmpintqi (outlow));
19420   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19421
19422   if (operands[0] != out)
19423     emit_move_insn (operands[0], out);
19424
19425   DONE;
19426 })
19427
19428 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19429
19430 (define_expand "cmpintqi"
19431   [(set (match_dup 1)
19432         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19433    (set (match_dup 2)
19434         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19435    (parallel [(set (match_operand:QI 0 "register_operand" "")
19436                    (minus:QI (match_dup 1)
19437                              (match_dup 2)))
19438               (clobber (reg:CC FLAGS_REG))])]
19439   ""
19440   "operands[1] = gen_reg_rtx (QImode);
19441    operands[2] = gen_reg_rtx (QImode);")
19442
19443 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19444 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19445
19446 (define_expand "cmpstrnqi_nz_1"
19447   [(parallel [(set (reg:CC FLAGS_REG)
19448                    (compare:CC (match_operand 4 "memory_operand" "")
19449                                (match_operand 5 "memory_operand" "")))
19450               (use (match_operand 2 "register_operand" ""))
19451               (use (match_operand:SI 3 "immediate_operand" ""))
19452               (clobber (match_operand 0 "register_operand" ""))
19453               (clobber (match_operand 1 "register_operand" ""))
19454               (clobber (match_dup 2))])]
19455   ""
19456   "ix86_current_function_needs_cld = 1;")
19457
19458 (define_insn "*cmpstrnqi_nz_1"
19459   [(set (reg:CC FLAGS_REG)
19460         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19461                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19462    (use (match_operand:SI 6 "register_operand" "2"))
19463    (use (match_operand:SI 3 "immediate_operand" "i"))
19464    (clobber (match_operand:SI 0 "register_operand" "=S"))
19465    (clobber (match_operand:SI 1 "register_operand" "=D"))
19466    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19467   "!TARGET_64BIT"
19468   "repz cmpsb"
19469   [(set_attr "type" "str")
19470    (set_attr "mode" "QI")
19471    (set_attr "prefix_rep" "1")])
19472
19473 (define_insn "*cmpstrnqi_nz_rex_1"
19474   [(set (reg:CC FLAGS_REG)
19475         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19476                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19477    (use (match_operand:DI 6 "register_operand" "2"))
19478    (use (match_operand:SI 3 "immediate_operand" "i"))
19479    (clobber (match_operand:DI 0 "register_operand" "=S"))
19480    (clobber (match_operand:DI 1 "register_operand" "=D"))
19481    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19482   "TARGET_64BIT"
19483   "repz cmpsb"
19484   [(set_attr "type" "str")
19485    (set_attr "mode" "QI")
19486    (set_attr "prefix_rep" "1")])
19487
19488 ;; The same, but the count is not known to not be zero.
19489
19490 (define_expand "cmpstrnqi_1"
19491   [(parallel [(set (reg:CC FLAGS_REG)
19492                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19493                                      (const_int 0))
19494                   (compare:CC (match_operand 4 "memory_operand" "")
19495                               (match_operand 5 "memory_operand" ""))
19496                   (const_int 0)))
19497               (use (match_operand:SI 3 "immediate_operand" ""))
19498               (use (reg:CC FLAGS_REG))
19499               (clobber (match_operand 0 "register_operand" ""))
19500               (clobber (match_operand 1 "register_operand" ""))
19501               (clobber (match_dup 2))])]
19502   ""
19503   "ix86_current_function_needs_cld = 1;")
19504
19505 (define_insn "*cmpstrnqi_1"
19506   [(set (reg:CC FLAGS_REG)
19507         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19508                              (const_int 0))
19509           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19510                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19511           (const_int 0)))
19512    (use (match_operand:SI 3 "immediate_operand" "i"))
19513    (use (reg:CC FLAGS_REG))
19514    (clobber (match_operand:SI 0 "register_operand" "=S"))
19515    (clobber (match_operand:SI 1 "register_operand" "=D"))
19516    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19517   "!TARGET_64BIT"
19518   "repz cmpsb"
19519   [(set_attr "type" "str")
19520    (set_attr "mode" "QI")
19521    (set_attr "prefix_rep" "1")])
19522
19523 (define_insn "*cmpstrnqi_rex_1"
19524   [(set (reg:CC FLAGS_REG)
19525         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19526                              (const_int 0))
19527           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19528                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19529           (const_int 0)))
19530    (use (match_operand:SI 3 "immediate_operand" "i"))
19531    (use (reg:CC FLAGS_REG))
19532    (clobber (match_operand:DI 0 "register_operand" "=S"))
19533    (clobber (match_operand:DI 1 "register_operand" "=D"))
19534    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19535   "TARGET_64BIT"
19536   "repz cmpsb"
19537   [(set_attr "type" "str")
19538    (set_attr "mode" "QI")
19539    (set_attr "prefix_rep" "1")])
19540
19541 (define_expand "strlensi"
19542   [(set (match_operand:SI 0 "register_operand" "")
19543         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19544                     (match_operand:QI 2 "immediate_operand" "")
19545                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19546   ""
19547 {
19548  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19549    DONE;
19550  else
19551    FAIL;
19552 })
19553
19554 (define_expand "strlendi"
19555   [(set (match_operand:DI 0 "register_operand" "")
19556         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19557                     (match_operand:QI 2 "immediate_operand" "")
19558                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19559   ""
19560 {
19561  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19562    DONE;
19563  else
19564    FAIL;
19565 })
19566
19567 (define_expand "strlenqi_1"
19568   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19569               (clobber (match_operand 1 "register_operand" ""))
19570               (clobber (reg:CC FLAGS_REG))])]
19571   ""
19572   "ix86_current_function_needs_cld = 1;")
19573
19574 (define_insn "*strlenqi_1"
19575   [(set (match_operand:SI 0 "register_operand" "=&c")
19576         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19577                     (match_operand:QI 2 "register_operand" "a")
19578                     (match_operand:SI 3 "immediate_operand" "i")
19579                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19580    (clobber (match_operand:SI 1 "register_operand" "=D"))
19581    (clobber (reg:CC FLAGS_REG))]
19582   "!TARGET_64BIT"
19583   "repnz scasb"
19584   [(set_attr "type" "str")
19585    (set_attr "mode" "QI")
19586    (set_attr "prefix_rep" "1")])
19587
19588 (define_insn "*strlenqi_rex_1"
19589   [(set (match_operand:DI 0 "register_operand" "=&c")
19590         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19591                     (match_operand:QI 2 "register_operand" "a")
19592                     (match_operand:DI 3 "immediate_operand" "i")
19593                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19594    (clobber (match_operand:DI 1 "register_operand" "=D"))
19595    (clobber (reg:CC FLAGS_REG))]
19596   "TARGET_64BIT"
19597   "repnz scasb"
19598   [(set_attr "type" "str")
19599    (set_attr "mode" "QI")
19600    (set_attr "prefix_rep" "1")])
19601
19602 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19603 ;; handled in combine, but it is not currently up to the task.
19604 ;; When used for their truth value, the cmpstrn* expanders generate
19605 ;; code like this:
19606 ;;
19607 ;;   repz cmpsb
19608 ;;   seta       %al
19609 ;;   setb       %dl
19610 ;;   cmpb       %al, %dl
19611 ;;   jcc        label
19612 ;;
19613 ;; The intermediate three instructions are unnecessary.
19614
19615 ;; This one handles cmpstrn*_nz_1...
19616 (define_peephole2
19617   [(parallel[
19618      (set (reg:CC FLAGS_REG)
19619           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19620                       (mem:BLK (match_operand 5 "register_operand" ""))))
19621      (use (match_operand 6 "register_operand" ""))
19622      (use (match_operand:SI 3 "immediate_operand" ""))
19623      (clobber (match_operand 0 "register_operand" ""))
19624      (clobber (match_operand 1 "register_operand" ""))
19625      (clobber (match_operand 2 "register_operand" ""))])
19626    (set (match_operand:QI 7 "register_operand" "")
19627         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19628    (set (match_operand:QI 8 "register_operand" "")
19629         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19630    (set (reg FLAGS_REG)
19631         (compare (match_dup 7) (match_dup 8)))
19632   ]
19633   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19634   [(parallel[
19635      (set (reg:CC FLAGS_REG)
19636           (compare:CC (mem:BLK (match_dup 4))
19637                       (mem:BLK (match_dup 5))))
19638      (use (match_dup 6))
19639      (use (match_dup 3))
19640      (clobber (match_dup 0))
19641      (clobber (match_dup 1))
19642      (clobber (match_dup 2))])]
19643   "")
19644
19645 ;; ...and this one handles cmpstrn*_1.
19646 (define_peephole2
19647   [(parallel[
19648      (set (reg:CC FLAGS_REG)
19649           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19650                                (const_int 0))
19651             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19652                         (mem:BLK (match_operand 5 "register_operand" "")))
19653             (const_int 0)))
19654      (use (match_operand:SI 3 "immediate_operand" ""))
19655      (use (reg:CC FLAGS_REG))
19656      (clobber (match_operand 0 "register_operand" ""))
19657      (clobber (match_operand 1 "register_operand" ""))
19658      (clobber (match_operand 2 "register_operand" ""))])
19659    (set (match_operand:QI 7 "register_operand" "")
19660         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19661    (set (match_operand:QI 8 "register_operand" "")
19662         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19663    (set (reg FLAGS_REG)
19664         (compare (match_dup 7) (match_dup 8)))
19665   ]
19666   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19667   [(parallel[
19668      (set (reg:CC FLAGS_REG)
19669           (if_then_else:CC (ne (match_dup 6)
19670                                (const_int 0))
19671             (compare:CC (mem:BLK (match_dup 4))
19672                         (mem:BLK (match_dup 5)))
19673             (const_int 0)))
19674      (use (match_dup 3))
19675      (use (reg:CC FLAGS_REG))
19676      (clobber (match_dup 0))
19677      (clobber (match_dup 1))
19678      (clobber (match_dup 2))])]
19679   "")
19680
19681
19682 \f
19683 ;; Conditional move instructions.
19684
19685 (define_expand "movdicc"
19686   [(set (match_operand:DI 0 "register_operand" "")
19687         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19688                          (match_operand:DI 2 "general_operand" "")
19689                          (match_operand:DI 3 "general_operand" "")))]
19690   "TARGET_64BIT"
19691   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19692
19693 (define_insn "x86_movdicc_0_m1_rex64"
19694   [(set (match_operand:DI 0 "register_operand" "=r")
19695         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19696           (const_int -1)
19697           (const_int 0)))
19698    (clobber (reg:CC FLAGS_REG))]
19699   "TARGET_64BIT"
19700   "sbb{q}\t%0, %0"
19701   ; Since we don't have the proper number of operands for an alu insn,
19702   ; fill in all the blanks.
19703   [(set_attr "type" "alu")
19704    (set_attr "pent_pair" "pu")
19705    (set_attr "memory" "none")
19706    (set_attr "imm_disp" "false")
19707    (set_attr "mode" "DI")
19708    (set_attr "length_immediate" "0")])
19709
19710 (define_insn "*x86_movdicc_0_m1_se"
19711   [(set (match_operand:DI 0 "register_operand" "=r")
19712         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19713                          (const_int 1)
19714                          (const_int 0)))
19715    (clobber (reg:CC FLAGS_REG))]
19716   ""
19717   "sbb{q}\t%0, %0"
19718   [(set_attr "type" "alu")
19719    (set_attr "pent_pair" "pu")
19720    (set_attr "memory" "none")
19721    (set_attr "imm_disp" "false")
19722    (set_attr "mode" "DI")
19723    (set_attr "length_immediate" "0")])
19724
19725 (define_insn "*movdicc_c_rex64"
19726   [(set (match_operand:DI 0 "register_operand" "=r,r")
19727         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19728                                 [(reg FLAGS_REG) (const_int 0)])
19729                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19730                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19731   "TARGET_64BIT && TARGET_CMOVE
19732    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19733   "@
19734    cmov%O2%C1\t{%2, %0|%0, %2}
19735    cmov%O2%c1\t{%3, %0|%0, %3}"
19736   [(set_attr "type" "icmov")
19737    (set_attr "mode" "DI")])
19738
19739 (define_expand "movsicc"
19740   [(set (match_operand:SI 0 "register_operand" "")
19741         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19742                          (match_operand:SI 2 "general_operand" "")
19743                          (match_operand:SI 3 "general_operand" "")))]
19744   ""
19745   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19746
19747 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19748 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19749 ;; So just document what we're doing explicitly.
19750
19751 (define_insn "x86_movsicc_0_m1"
19752   [(set (match_operand:SI 0 "register_operand" "=r")
19753         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19754           (const_int -1)
19755           (const_int 0)))
19756    (clobber (reg:CC FLAGS_REG))]
19757   ""
19758   "sbb{l}\t%0, %0"
19759   ; Since we don't have the proper number of operands for an alu insn,
19760   ; fill in all the blanks.
19761   [(set_attr "type" "alu")
19762    (set_attr "pent_pair" "pu")
19763    (set_attr "memory" "none")
19764    (set_attr "imm_disp" "false")
19765    (set_attr "mode" "SI")
19766    (set_attr "length_immediate" "0")])
19767
19768 (define_insn "*x86_movsicc_0_m1_se"
19769   [(set (match_operand:SI 0 "register_operand" "=r")
19770         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19771                          (const_int 1)
19772                          (const_int 0)))
19773    (clobber (reg:CC FLAGS_REG))]
19774   ""
19775   "sbb{l}\t%0, %0"
19776   [(set_attr "type" "alu")
19777    (set_attr "pent_pair" "pu")
19778    (set_attr "memory" "none")
19779    (set_attr "imm_disp" "false")
19780    (set_attr "mode" "SI")
19781    (set_attr "length_immediate" "0")])
19782
19783 (define_insn "*movsicc_noc"
19784   [(set (match_operand:SI 0 "register_operand" "=r,r")
19785         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19786                                 [(reg FLAGS_REG) (const_int 0)])
19787                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19788                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19789   "TARGET_CMOVE
19790    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19791   "@
19792    cmov%O2%C1\t{%2, %0|%0, %2}
19793    cmov%O2%c1\t{%3, %0|%0, %3}"
19794   [(set_attr "type" "icmov")
19795    (set_attr "mode" "SI")])
19796
19797 (define_expand "movhicc"
19798   [(set (match_operand:HI 0 "register_operand" "")
19799         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19800                          (match_operand:HI 2 "general_operand" "")
19801                          (match_operand:HI 3 "general_operand" "")))]
19802   "TARGET_HIMODE_MATH"
19803   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19804
19805 (define_insn "*movhicc_noc"
19806   [(set (match_operand:HI 0 "register_operand" "=r,r")
19807         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19808                                 [(reg FLAGS_REG) (const_int 0)])
19809                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19810                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19811   "TARGET_CMOVE
19812    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19813   "@
19814    cmov%O2%C1\t{%2, %0|%0, %2}
19815    cmov%O2%c1\t{%3, %0|%0, %3}"
19816   [(set_attr "type" "icmov")
19817    (set_attr "mode" "HI")])
19818
19819 (define_expand "movqicc"
19820   [(set (match_operand:QI 0 "register_operand" "")
19821         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19822                          (match_operand:QI 2 "general_operand" "")
19823                          (match_operand:QI 3 "general_operand" "")))]
19824   "TARGET_QIMODE_MATH"
19825   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19826
19827 (define_insn_and_split "*movqicc_noc"
19828   [(set (match_operand:QI 0 "register_operand" "=r,r")
19829         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19830                                 [(match_operand 4 "flags_reg_operand" "")
19831                                  (const_int 0)])
19832                       (match_operand:QI 2 "register_operand" "r,0")
19833                       (match_operand:QI 3 "register_operand" "0,r")))]
19834   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19835   "#"
19836   "&& reload_completed"
19837   [(set (match_dup 0)
19838         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19839                       (match_dup 2)
19840                       (match_dup 3)))]
19841   "operands[0] = gen_lowpart (SImode, operands[0]);
19842    operands[2] = gen_lowpart (SImode, operands[2]);
19843    operands[3] = gen_lowpart (SImode, operands[3]);"
19844   [(set_attr "type" "icmov")
19845    (set_attr "mode" "SI")])
19846
19847 (define_expand "mov<mode>cc"
19848   [(set (match_operand:X87MODEF 0 "register_operand" "")
19849         (if_then_else:X87MODEF
19850           (match_operand 1 "comparison_operator" "")
19851           (match_operand:X87MODEF 2 "register_operand" "")
19852           (match_operand:X87MODEF 3 "register_operand" "")))]
19853   "(TARGET_80387 && TARGET_CMOVE)
19854    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19855   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19856
19857 (define_insn "*movsfcc_1_387"
19858   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19859         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19860                                 [(reg FLAGS_REG) (const_int 0)])
19861                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19862                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19863   "TARGET_80387 && TARGET_CMOVE
19864    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19865   "@
19866    fcmov%F1\t{%2, %0|%0, %2}
19867    fcmov%f1\t{%3, %0|%0, %3}
19868    cmov%O2%C1\t{%2, %0|%0, %2}
19869    cmov%O2%c1\t{%3, %0|%0, %3}"
19870   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19871    (set_attr "mode" "SF,SF,SI,SI")])
19872
19873 (define_insn "*movdfcc_1"
19874   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19875         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19876                                 [(reg FLAGS_REG) (const_int 0)])
19877                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19878                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19879   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19880    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19881   "@
19882    fcmov%F1\t{%2, %0|%0, %2}
19883    fcmov%f1\t{%3, %0|%0, %3}
19884    #
19885    #"
19886   [(set_attr "type" "fcmov,fcmov,multi,multi")
19887    (set_attr "mode" "DF")])
19888
19889 (define_insn "*movdfcc_1_rex64"
19890   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19891         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19892                                 [(reg FLAGS_REG) (const_int 0)])
19893                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19894                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19895   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19896    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19897   "@
19898    fcmov%F1\t{%2, %0|%0, %2}
19899    fcmov%f1\t{%3, %0|%0, %3}
19900    cmov%O2%C1\t{%2, %0|%0, %2}
19901    cmov%O2%c1\t{%3, %0|%0, %3}"
19902   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19903    (set_attr "mode" "DF")])
19904
19905 (define_split
19906   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19907         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19908                                 [(match_operand 4 "flags_reg_operand" "")
19909                                  (const_int 0)])
19910                       (match_operand:DF 2 "nonimmediate_operand" "")
19911                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19912   "!TARGET_64BIT && reload_completed"
19913   [(set (match_dup 2)
19914         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19915                       (match_dup 5)
19916                       (match_dup 6)))
19917    (set (match_dup 3)
19918         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19919                       (match_dup 7)
19920                       (match_dup 8)))]
19921   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19922    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19923
19924 (define_insn "*movxfcc_1"
19925   [(set (match_operand:XF 0 "register_operand" "=f,f")
19926         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19927                                 [(reg FLAGS_REG) (const_int 0)])
19928                       (match_operand:XF 2 "register_operand" "f,0")
19929                       (match_operand:XF 3 "register_operand" "0,f")))]
19930   "TARGET_80387 && TARGET_CMOVE"
19931   "@
19932    fcmov%F1\t{%2, %0|%0, %2}
19933    fcmov%f1\t{%3, %0|%0, %3}"
19934   [(set_attr "type" "fcmov")
19935    (set_attr "mode" "XF")])
19936
19937 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19938 ;; the scalar versions to have only XMM registers as operands.
19939
19940 ;; SSE5 conditional move
19941 (define_insn "*sse5_pcmov_<mode>"
19942   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19943         (if_then_else:MODEF
19944           (match_operand:MODEF 1 "register_operand" "x,0")
19945           (match_operand:MODEF 2 "register_operand" "0,x")
19946           (match_operand:MODEF 3 "register_operand" "x,x")))]
19947   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19948   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19949   [(set_attr "type" "sse4arg")])
19950
19951 ;; These versions of the min/max patterns are intentionally ignorant of
19952 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19953 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19954 ;; are undefined in this condition, we're certain this is correct.
19955
19956 (define_insn "*avx_<code><mode>3"
19957   [(set (match_operand:MODEF 0 "register_operand" "=x")
19958         (smaxmin:MODEF
19959           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19960           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19961   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19962   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19963   [(set_attr "type" "sseadd")
19964    (set_attr "prefix" "vex")
19965    (set_attr "mode" "<MODE>")])
19966
19967 (define_insn "<code><mode>3"
19968   [(set (match_operand:MODEF 0 "register_operand" "=x")
19969         (smaxmin:MODEF
19970           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19971           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19972   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19973   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19974   [(set_attr "type" "sseadd")
19975    (set_attr "mode" "<MODE>")])
19976
19977 ;; These versions of the min/max patterns implement exactly the operations
19978 ;;   min = (op1 < op2 ? op1 : op2)
19979 ;;   max = (!(op1 < op2) ? op1 : op2)
19980 ;; Their operands are not commutative, and thus they may be used in the
19981 ;; presence of -0.0 and NaN.
19982
19983 (define_insn "*avx_ieee_smin<mode>3"
19984   [(set (match_operand:MODEF 0 "register_operand" "=x")
19985         (unspec:MODEF
19986           [(match_operand:MODEF 1 "register_operand" "x")
19987            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19988          UNSPEC_IEEE_MIN))]
19989   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19990   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19991   [(set_attr "type" "sseadd")
19992    (set_attr "prefix" "vex")
19993    (set_attr "mode" "<MODE>")])
19994
19995 (define_insn "*ieee_smin<mode>3"
19996   [(set (match_operand:MODEF 0 "register_operand" "=x")
19997         (unspec:MODEF
19998           [(match_operand:MODEF 1 "register_operand" "0")
19999            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20000          UNSPEC_IEEE_MIN))]
20001   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20002   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20003   [(set_attr "type" "sseadd")
20004    (set_attr "mode" "<MODE>")])
20005
20006 (define_insn "*avx_ieee_smax<mode>3"
20007   [(set (match_operand:MODEF 0 "register_operand" "=x")
20008         (unspec:MODEF
20009           [(match_operand:MODEF 1 "register_operand" "0")
20010            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20011          UNSPEC_IEEE_MAX))]
20012   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20013   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20014   [(set_attr "type" "sseadd")
20015    (set_attr "prefix" "vex")
20016    (set_attr "mode" "<MODE>")])
20017
20018 (define_insn "*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   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20025   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20026   [(set_attr "type" "sseadd")
20027    (set_attr "mode" "<MODE>")])
20028
20029 ;; Make two stack loads independent:
20030 ;;   fld aa              fld aa
20031 ;;   fld %st(0)     ->   fld bb
20032 ;;   fmul bb             fmul %st(1), %st
20033 ;;
20034 ;; Actually we only match the last two instructions for simplicity.
20035 (define_peephole2
20036   [(set (match_operand 0 "fp_register_operand" "")
20037         (match_operand 1 "fp_register_operand" ""))
20038    (set (match_dup 0)
20039         (match_operator 2 "binary_fp_operator"
20040            [(match_dup 0)
20041             (match_operand 3 "memory_operand" "")]))]
20042   "REGNO (operands[0]) != REGNO (operands[1])"
20043   [(set (match_dup 0) (match_dup 3))
20044    (set (match_dup 0) (match_dup 4))]
20045
20046   ;; The % modifier is not operational anymore in peephole2's, so we have to
20047   ;; swap the operands manually in the case of addition and multiplication.
20048   "if (COMMUTATIVE_ARITH_P (operands[2]))
20049      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20050                                  operands[0], operands[1]);
20051    else
20052      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20053                                  operands[1], operands[0]);")
20054
20055 ;; Conditional addition patterns
20056 (define_expand "add<mode>cc"
20057   [(match_operand:SWI 0 "register_operand" "")
20058    (match_operand 1 "comparison_operator" "")
20059    (match_operand:SWI 2 "register_operand" "")
20060    (match_operand:SWI 3 "const_int_operand" "")]
20061   ""
20062   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20063
20064 \f
20065 ;; Misc patterns (?)
20066
20067 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20068 ;; Otherwise there will be nothing to keep
20069 ;;
20070 ;; [(set (reg ebp) (reg esp))]
20071 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20072 ;;  (clobber (eflags)]
20073 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20074 ;;
20075 ;; in proper program order.
20076 (define_insn "pro_epilogue_adjust_stack_1"
20077   [(set (match_operand:SI 0 "register_operand" "=r,r")
20078         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20079                  (match_operand:SI 2 "immediate_operand" "i,i")))
20080    (clobber (reg:CC FLAGS_REG))
20081    (clobber (mem:BLK (scratch)))]
20082   "!TARGET_64BIT"
20083 {
20084   switch (get_attr_type (insn))
20085     {
20086     case TYPE_IMOV:
20087       return "mov{l}\t{%1, %0|%0, %1}";
20088
20089     case TYPE_ALU:
20090       if (CONST_INT_P (operands[2])
20091           && (INTVAL (operands[2]) == 128
20092               || (INTVAL (operands[2]) < 0
20093                   && INTVAL (operands[2]) != -128)))
20094         {
20095           operands[2] = GEN_INT (-INTVAL (operands[2]));
20096           return "sub{l}\t{%2, %0|%0, %2}";
20097         }
20098       return "add{l}\t{%2, %0|%0, %2}";
20099
20100     case TYPE_LEA:
20101       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20102       return "lea{l}\t{%a2, %0|%0, %a2}";
20103
20104     default:
20105       gcc_unreachable ();
20106     }
20107 }
20108   [(set (attr "type")
20109         (cond [(eq_attr "alternative" "0")
20110                  (const_string "alu")
20111                (match_operand:SI 2 "const0_operand" "")
20112                  (const_string "imov")
20113               ]
20114               (const_string "lea")))
20115    (set_attr "mode" "SI")])
20116
20117 (define_insn "pro_epilogue_adjust_stack_rex64"
20118   [(set (match_operand:DI 0 "register_operand" "=r,r")
20119         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20120                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20121    (clobber (reg:CC FLAGS_REG))
20122    (clobber (mem:BLK (scratch)))]
20123   "TARGET_64BIT"
20124 {
20125   switch (get_attr_type (insn))
20126     {
20127     case TYPE_IMOV:
20128       return "mov{q}\t{%1, %0|%0, %1}";
20129
20130     case TYPE_ALU:
20131       if (CONST_INT_P (operands[2])
20132           /* Avoid overflows.  */
20133           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20134           && (INTVAL (operands[2]) == 128
20135               || (INTVAL (operands[2]) < 0
20136                   && INTVAL (operands[2]) != -128)))
20137         {
20138           operands[2] = GEN_INT (-INTVAL (operands[2]));
20139           return "sub{q}\t{%2, %0|%0, %2}";
20140         }
20141       return "add{q}\t{%2, %0|%0, %2}";
20142
20143     case TYPE_LEA:
20144       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20145       return "lea{q}\t{%a2, %0|%0, %a2}";
20146
20147     default:
20148       gcc_unreachable ();
20149     }
20150 }
20151   [(set (attr "type")
20152         (cond [(eq_attr "alternative" "0")
20153                  (const_string "alu")
20154                (match_operand:DI 2 "const0_operand" "")
20155                  (const_string "imov")
20156               ]
20157               (const_string "lea")))
20158    (set_attr "mode" "DI")])
20159
20160 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20161   [(set (match_operand:DI 0 "register_operand" "=r,r")
20162         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20163                  (match_operand:DI 3 "immediate_operand" "i,i")))
20164    (use (match_operand:DI 2 "register_operand" "r,r"))
20165    (clobber (reg:CC FLAGS_REG))
20166    (clobber (mem:BLK (scratch)))]
20167   "TARGET_64BIT"
20168 {
20169   switch (get_attr_type (insn))
20170     {
20171     case TYPE_ALU:
20172       return "add{q}\t{%2, %0|%0, %2}";
20173
20174     case TYPE_LEA:
20175       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20176       return "lea{q}\t{%a2, %0|%0, %a2}";
20177
20178     default:
20179       gcc_unreachable ();
20180     }
20181 }
20182   [(set_attr "type" "alu,lea")
20183    (set_attr "mode" "DI")])
20184
20185 (define_insn "allocate_stack_worker_32"
20186   [(set (match_operand:SI 0 "register_operand" "=a")
20187         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20188                             UNSPECV_STACK_PROBE))
20189    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20190    (clobber (reg:CC FLAGS_REG))]
20191   "!TARGET_64BIT && TARGET_STACK_PROBE"
20192   "call\t___chkstk"
20193   [(set_attr "type" "multi")
20194    (set_attr "length" "5")])
20195
20196 (define_insn "allocate_stack_worker_64"
20197   [(set (match_operand:DI 0 "register_operand" "=a")
20198         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20199                             UNSPECV_STACK_PROBE))
20200    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20201    (clobber (reg:DI R10_REG))
20202    (clobber (reg:DI R11_REG))
20203    (clobber (reg:CC FLAGS_REG))]
20204   "TARGET_64BIT && TARGET_STACK_PROBE"
20205   "call\t___chkstk"
20206   [(set_attr "type" "multi")
20207    (set_attr "length" "5")])
20208
20209 (define_expand "allocate_stack"
20210   [(match_operand 0 "register_operand" "")
20211    (match_operand 1 "general_operand" "")]
20212   "TARGET_STACK_PROBE"
20213 {
20214   rtx x;
20215
20216 #ifndef CHECK_STACK_LIMIT
20217 #define CHECK_STACK_LIMIT 0
20218 #endif
20219
20220   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20221       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20222     {
20223       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20224                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20225       if (x != stack_pointer_rtx)
20226         emit_move_insn (stack_pointer_rtx, x);
20227     }
20228   else
20229     {
20230       x = copy_to_mode_reg (Pmode, operands[1]);
20231       if (TARGET_64BIT)
20232         x = gen_allocate_stack_worker_64 (x, x);
20233       else
20234         x = gen_allocate_stack_worker_32 (x, x);
20235       emit_insn (x);
20236     }
20237
20238   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20239   DONE;
20240 })
20241
20242 (define_expand "builtin_setjmp_receiver"
20243   [(label_ref (match_operand 0 "" ""))]
20244   "!TARGET_64BIT && flag_pic"
20245 {
20246 #if TARGET_MACHO
20247   if (TARGET_MACHO)
20248     {
20249       rtx xops[3];
20250       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20251       rtx label_rtx = gen_label_rtx ();
20252       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20253       xops[0] = xops[1] = picreg;
20254       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20255       ix86_expand_binary_operator (MINUS, SImode, xops);
20256     }
20257   else
20258 #endif
20259     emit_insn (gen_set_got (pic_offset_table_rtx));
20260   DONE;
20261 })
20262 \f
20263 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20264
20265 (define_split
20266   [(set (match_operand 0 "register_operand" "")
20267         (match_operator 3 "promotable_binary_operator"
20268            [(match_operand 1 "register_operand" "")
20269             (match_operand 2 "aligned_operand" "")]))
20270    (clobber (reg:CC FLAGS_REG))]
20271   "! TARGET_PARTIAL_REG_STALL && reload_completed
20272    && ((GET_MODE (operands[0]) == HImode
20273         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20274             /* ??? next two lines just !satisfies_constraint_K (...) */
20275             || !CONST_INT_P (operands[2])
20276             || satisfies_constraint_K (operands[2])))
20277        || (GET_MODE (operands[0]) == QImode
20278            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20279   [(parallel [(set (match_dup 0)
20280                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20281               (clobber (reg:CC FLAGS_REG))])]
20282   "operands[0] = gen_lowpart (SImode, operands[0]);
20283    operands[1] = gen_lowpart (SImode, operands[1]);
20284    if (GET_CODE (operands[3]) != ASHIFT)
20285      operands[2] = gen_lowpart (SImode, operands[2]);
20286    PUT_MODE (operands[3], SImode);")
20287
20288 ; Promote the QImode tests, as i386 has encoding of the AND
20289 ; instruction with 32-bit sign-extended immediate and thus the
20290 ; instruction size is unchanged, except in the %eax case for
20291 ; which it is increased by one byte, hence the ! optimize_size.
20292 (define_split
20293   [(set (match_operand 0 "flags_reg_operand" "")
20294         (match_operator 2 "compare_operator"
20295           [(and (match_operand 3 "aligned_operand" "")
20296                 (match_operand 4 "const_int_operand" ""))
20297            (const_int 0)]))
20298    (set (match_operand 1 "register_operand" "")
20299         (and (match_dup 3) (match_dup 4)))]
20300   "! TARGET_PARTIAL_REG_STALL && reload_completed
20301    && optimize_insn_for_speed_p ()
20302    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20303        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20304    /* Ensure that the operand will remain sign-extended immediate.  */
20305    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20306   [(parallel [(set (match_dup 0)
20307                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20308                                     (const_int 0)]))
20309               (set (match_dup 1)
20310                    (and:SI (match_dup 3) (match_dup 4)))])]
20311 {
20312   operands[4]
20313     = gen_int_mode (INTVAL (operands[4])
20314                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20315   operands[1] = gen_lowpart (SImode, operands[1]);
20316   operands[3] = gen_lowpart (SImode, operands[3]);
20317 })
20318
20319 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20320 ; the TEST instruction with 32-bit sign-extended immediate and thus
20321 ; the instruction size would at least double, which is not what we
20322 ; want even with ! optimize_size.
20323 (define_split
20324   [(set (match_operand 0 "flags_reg_operand" "")
20325         (match_operator 1 "compare_operator"
20326           [(and (match_operand:HI 2 "aligned_operand" "")
20327                 (match_operand:HI 3 "const_int_operand" ""))
20328            (const_int 0)]))]
20329   "! TARGET_PARTIAL_REG_STALL && reload_completed
20330    && ! TARGET_FAST_PREFIX
20331    && optimize_insn_for_speed_p ()
20332    /* Ensure that the operand will remain sign-extended immediate.  */
20333    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20334   [(set (match_dup 0)
20335         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20336                          (const_int 0)]))]
20337 {
20338   operands[3]
20339     = gen_int_mode (INTVAL (operands[3])
20340                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20341   operands[2] = gen_lowpart (SImode, operands[2]);
20342 })
20343
20344 (define_split
20345   [(set (match_operand 0 "register_operand" "")
20346         (neg (match_operand 1 "register_operand" "")))
20347    (clobber (reg:CC FLAGS_REG))]
20348   "! TARGET_PARTIAL_REG_STALL && reload_completed
20349    && (GET_MODE (operands[0]) == HImode
20350        || (GET_MODE (operands[0]) == QImode
20351            && (TARGET_PROMOTE_QImode
20352                || optimize_insn_for_size_p ())))"
20353   [(parallel [(set (match_dup 0)
20354                    (neg:SI (match_dup 1)))
20355               (clobber (reg:CC FLAGS_REG))])]
20356   "operands[0] = gen_lowpart (SImode, operands[0]);
20357    operands[1] = gen_lowpart (SImode, operands[1]);")
20358
20359 (define_split
20360   [(set (match_operand 0 "register_operand" "")
20361         (not (match_operand 1 "register_operand" "")))]
20362   "! TARGET_PARTIAL_REG_STALL && reload_completed
20363    && (GET_MODE (operands[0]) == HImode
20364        || (GET_MODE (operands[0]) == QImode
20365            && (TARGET_PROMOTE_QImode
20366                || optimize_insn_for_size_p ())))"
20367   [(set (match_dup 0)
20368         (not:SI (match_dup 1)))]
20369   "operands[0] = gen_lowpart (SImode, operands[0]);
20370    operands[1] = gen_lowpart (SImode, operands[1]);")
20371
20372 (define_split
20373   [(set (match_operand 0 "register_operand" "")
20374         (if_then_else (match_operator 1 "comparison_operator"
20375                                 [(reg FLAGS_REG) (const_int 0)])
20376                       (match_operand 2 "register_operand" "")
20377                       (match_operand 3 "register_operand" "")))]
20378   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20379    && (GET_MODE (operands[0]) == HImode
20380        || (GET_MODE (operands[0]) == QImode
20381            && (TARGET_PROMOTE_QImode
20382                || optimize_insn_for_size_p ())))"
20383   [(set (match_dup 0)
20384         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20385   "operands[0] = gen_lowpart (SImode, operands[0]);
20386    operands[2] = gen_lowpart (SImode, operands[2]);
20387    operands[3] = gen_lowpart (SImode, operands[3]);")
20388
20389 \f
20390 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20391 ;; transform a complex memory operation into two memory to register operations.
20392
20393 ;; Don't push memory operands
20394 (define_peephole2
20395   [(set (match_operand:SI 0 "push_operand" "")
20396         (match_operand:SI 1 "memory_operand" ""))
20397    (match_scratch:SI 2 "r")]
20398   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20399    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20400   [(set (match_dup 2) (match_dup 1))
20401    (set (match_dup 0) (match_dup 2))]
20402   "")
20403
20404 (define_peephole2
20405   [(set (match_operand:DI 0 "push_operand" "")
20406         (match_operand:DI 1 "memory_operand" ""))
20407    (match_scratch:DI 2 "r")]
20408   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20409    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20410   [(set (match_dup 2) (match_dup 1))
20411    (set (match_dup 0) (match_dup 2))]
20412   "")
20413
20414 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20415 ;; SImode pushes.
20416 (define_peephole2
20417   [(set (match_operand:SF 0 "push_operand" "")
20418         (match_operand:SF 1 "memory_operand" ""))
20419    (match_scratch:SF 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 (define_peephole2
20427   [(set (match_operand:HI 0 "push_operand" "")
20428         (match_operand:HI 1 "memory_operand" ""))
20429    (match_scratch:HI 2 "r")]
20430   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20431    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20432   [(set (match_dup 2) (match_dup 1))
20433    (set (match_dup 0) (match_dup 2))]
20434   "")
20435
20436 (define_peephole2
20437   [(set (match_operand:QI 0 "push_operand" "")
20438         (match_operand:QI 1 "memory_operand" ""))
20439    (match_scratch:QI 2 "q")]
20440   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20441    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20442   [(set (match_dup 2) (match_dup 1))
20443    (set (match_dup 0) (match_dup 2))]
20444   "")
20445
20446 ;; Don't move an immediate directly to memory when the instruction
20447 ;; gets too big.
20448 (define_peephole2
20449   [(match_scratch:SI 1 "r")
20450    (set (match_operand:SI 0 "memory_operand" "")
20451         (const_int 0))]
20452   "optimize_insn_for_speed_p ()
20453    && ! TARGET_USE_MOV0
20454    && TARGET_SPLIT_LONG_MOVES
20455    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20456    && peep2_regno_dead_p (0, FLAGS_REG)"
20457   [(parallel [(set (match_dup 1) (const_int 0))
20458               (clobber (reg:CC FLAGS_REG))])
20459    (set (match_dup 0) (match_dup 1))]
20460   "")
20461
20462 (define_peephole2
20463   [(match_scratch:HI 1 "r")
20464    (set (match_operand:HI 0 "memory_operand" "")
20465         (const_int 0))]
20466   "optimize_insn_for_speed_p ()
20467    && ! TARGET_USE_MOV0
20468    && TARGET_SPLIT_LONG_MOVES
20469    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20470    && peep2_regno_dead_p (0, FLAGS_REG)"
20471   [(parallel [(set (match_dup 2) (const_int 0))
20472               (clobber (reg:CC FLAGS_REG))])
20473    (set (match_dup 0) (match_dup 1))]
20474   "operands[2] = gen_lowpart (SImode, operands[1]);")
20475
20476 (define_peephole2
20477   [(match_scratch:QI 1 "q")
20478    (set (match_operand:QI 0 "memory_operand" "")
20479         (const_int 0))]
20480   "optimize_insn_for_speed_p ()
20481    && ! TARGET_USE_MOV0
20482    && TARGET_SPLIT_LONG_MOVES
20483    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20484    && peep2_regno_dead_p (0, FLAGS_REG)"
20485   [(parallel [(set (match_dup 2) (const_int 0))
20486               (clobber (reg:CC FLAGS_REG))])
20487    (set (match_dup 0) (match_dup 1))]
20488   "operands[2] = gen_lowpart (SImode, operands[1]);")
20489
20490 (define_peephole2
20491   [(match_scratch:SI 2 "r")
20492    (set (match_operand:SI 0 "memory_operand" "")
20493         (match_operand:SI 1 "immediate_operand" ""))]
20494   "optimize_insn_for_speed_p ()
20495    && TARGET_SPLIT_LONG_MOVES
20496    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20497   [(set (match_dup 2) (match_dup 1))
20498    (set (match_dup 0) (match_dup 2))]
20499   "")
20500
20501 (define_peephole2
20502   [(match_scratch:HI 2 "r")
20503    (set (match_operand:HI 0 "memory_operand" "")
20504         (match_operand:HI 1 "immediate_operand" ""))]
20505   "optimize_insn_for_speed_p ()
20506    && TARGET_SPLIT_LONG_MOVES
20507    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20508   [(set (match_dup 2) (match_dup 1))
20509    (set (match_dup 0) (match_dup 2))]
20510   "")
20511
20512 (define_peephole2
20513   [(match_scratch:QI 2 "q")
20514    (set (match_operand:QI 0 "memory_operand" "")
20515         (match_operand:QI 1 "immediate_operand" ""))]
20516   "optimize_insn_for_speed_p ()
20517    && TARGET_SPLIT_LONG_MOVES
20518    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20519   [(set (match_dup 2) (match_dup 1))
20520    (set (match_dup 0) (match_dup 2))]
20521   "")
20522
20523 ;; Don't compare memory with zero, load and use a test instead.
20524 (define_peephole2
20525   [(set (match_operand 0 "flags_reg_operand" "")
20526         (match_operator 1 "compare_operator"
20527           [(match_operand:SI 2 "memory_operand" "")
20528            (const_int 0)]))
20529    (match_scratch:SI 3 "r")]
20530   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20531   [(set (match_dup 3) (match_dup 2))
20532    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20533   "")
20534
20535 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20536 ;; Don't split NOTs with a displacement operand, because resulting XOR
20537 ;; will not be pairable anyway.
20538 ;;
20539 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20540 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20541 ;; so this split helps here as well.
20542 ;;
20543 ;; Note: Can't do this as a regular split because we can't get proper
20544 ;; lifetime information then.
20545
20546 (define_peephole2
20547   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20548         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20549   "optimize_insn_for_speed_p ()
20550    && ((TARGET_NOT_UNPAIRABLE
20551         && (!MEM_P (operands[0])
20552             || !memory_displacement_operand (operands[0], SImode)))
20553        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20554    && peep2_regno_dead_p (0, FLAGS_REG)"
20555   [(parallel [(set (match_dup 0)
20556                    (xor:SI (match_dup 1) (const_int -1)))
20557               (clobber (reg:CC FLAGS_REG))])]
20558   "")
20559
20560 (define_peephole2
20561   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20562         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20563   "optimize_insn_for_speed_p ()
20564    && ((TARGET_NOT_UNPAIRABLE
20565         && (!MEM_P (operands[0])
20566             || !memory_displacement_operand (operands[0], HImode)))
20567        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20568    && peep2_regno_dead_p (0, FLAGS_REG)"
20569   [(parallel [(set (match_dup 0)
20570                    (xor:HI (match_dup 1) (const_int -1)))
20571               (clobber (reg:CC FLAGS_REG))])]
20572   "")
20573
20574 (define_peephole2
20575   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20576         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20577   "optimize_insn_for_speed_p ()
20578    && ((TARGET_NOT_UNPAIRABLE
20579         && (!MEM_P (operands[0])
20580             || !memory_displacement_operand (operands[0], QImode)))
20581        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20582    && peep2_regno_dead_p (0, FLAGS_REG)"
20583   [(parallel [(set (match_dup 0)
20584                    (xor:QI (match_dup 1) (const_int -1)))
20585               (clobber (reg:CC FLAGS_REG))])]
20586   "")
20587
20588 ;; Non pairable "test imm, reg" instructions can be translated to
20589 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20590 ;; byte opcode instead of two, have a short form for byte operands),
20591 ;; so do it for other CPUs as well.  Given that the value was dead,
20592 ;; this should not create any new dependencies.  Pass on the sub-word
20593 ;; versions if we're concerned about partial register stalls.
20594
20595 (define_peephole2
20596   [(set (match_operand 0 "flags_reg_operand" "")
20597         (match_operator 1 "compare_operator"
20598           [(and:SI (match_operand:SI 2 "register_operand" "")
20599                    (match_operand:SI 3 "immediate_operand" ""))
20600            (const_int 0)]))]
20601   "ix86_match_ccmode (insn, CCNOmode)
20602    && (true_regnum (operands[2]) != AX_REG
20603        || satisfies_constraint_K (operands[3]))
20604    && peep2_reg_dead_p (1, operands[2])"
20605   [(parallel
20606      [(set (match_dup 0)
20607            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20608                             (const_int 0)]))
20609       (set (match_dup 2)
20610            (and:SI (match_dup 2) (match_dup 3)))])]
20611   "")
20612
20613 ;; We don't need to handle HImode case, because it will be promoted to SImode
20614 ;; on ! TARGET_PARTIAL_REG_STALL
20615
20616 (define_peephole2
20617   [(set (match_operand 0 "flags_reg_operand" "")
20618         (match_operator 1 "compare_operator"
20619           [(and:QI (match_operand:QI 2 "register_operand" "")
20620                    (match_operand:QI 3 "immediate_operand" ""))
20621            (const_int 0)]))]
20622   "! TARGET_PARTIAL_REG_STALL
20623    && ix86_match_ccmode (insn, CCNOmode)
20624    && true_regnum (operands[2]) != AX_REG
20625    && peep2_reg_dead_p (1, operands[2])"
20626   [(parallel
20627      [(set (match_dup 0)
20628            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20629                             (const_int 0)]))
20630       (set (match_dup 2)
20631            (and:QI (match_dup 2) (match_dup 3)))])]
20632   "")
20633
20634 (define_peephole2
20635   [(set (match_operand 0 "flags_reg_operand" "")
20636         (match_operator 1 "compare_operator"
20637           [(and:SI
20638              (zero_extract:SI
20639                (match_operand 2 "ext_register_operand" "")
20640                (const_int 8)
20641                (const_int 8))
20642              (match_operand 3 "const_int_operand" ""))
20643            (const_int 0)]))]
20644   "! TARGET_PARTIAL_REG_STALL
20645    && ix86_match_ccmode (insn, CCNOmode)
20646    && true_regnum (operands[2]) != AX_REG
20647    && peep2_reg_dead_p (1, operands[2])"
20648   [(parallel [(set (match_dup 0)
20649                    (match_op_dup 1
20650                      [(and:SI
20651                         (zero_extract:SI
20652                           (match_dup 2)
20653                           (const_int 8)
20654                           (const_int 8))
20655                         (match_dup 3))
20656                       (const_int 0)]))
20657               (set (zero_extract:SI (match_dup 2)
20658                                     (const_int 8)
20659                                     (const_int 8))
20660                    (and:SI
20661                      (zero_extract:SI
20662                        (match_dup 2)
20663                        (const_int 8)
20664                        (const_int 8))
20665                      (match_dup 3)))])]
20666   "")
20667
20668 ;; Don't do logical operations with memory inputs.
20669 (define_peephole2
20670   [(match_scratch:SI 2 "r")
20671    (parallel [(set (match_operand:SI 0 "register_operand" "")
20672                    (match_operator:SI 3 "arith_or_logical_operator"
20673                      [(match_dup 0)
20674                       (match_operand:SI 1 "memory_operand" "")]))
20675               (clobber (reg:CC FLAGS_REG))])]
20676   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20677   [(set (match_dup 2) (match_dup 1))
20678    (parallel [(set (match_dup 0)
20679                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20680               (clobber (reg:CC FLAGS_REG))])]
20681   "")
20682
20683 (define_peephole2
20684   [(match_scratch:SI 2 "r")
20685    (parallel [(set (match_operand:SI 0 "register_operand" "")
20686                    (match_operator:SI 3 "arith_or_logical_operator"
20687                      [(match_operand:SI 1 "memory_operand" "")
20688                       (match_dup 0)]))
20689               (clobber (reg:CC FLAGS_REG))])]
20690   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20691   [(set (match_dup 2) (match_dup 1))
20692    (parallel [(set (match_dup 0)
20693                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20694               (clobber (reg:CC FLAGS_REG))])]
20695   "")
20696
20697 ; Don't do logical operations with memory outputs
20698 ;
20699 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20700 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20701 ; the same decoder scheduling characteristics as the original.
20702
20703 (define_peephole2
20704   [(match_scratch:SI 2 "r")
20705    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20706                    (match_operator:SI 3 "arith_or_logical_operator"
20707                      [(match_dup 0)
20708                       (match_operand:SI 1 "nonmemory_operand" "")]))
20709               (clobber (reg:CC FLAGS_REG))])]
20710   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20711   [(set (match_dup 2) (match_dup 0))
20712    (parallel [(set (match_dup 2)
20713                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20714               (clobber (reg:CC FLAGS_REG))])
20715    (set (match_dup 0) (match_dup 2))]
20716   "")
20717
20718 (define_peephole2
20719   [(match_scratch:SI 2 "r")
20720    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20721                    (match_operator:SI 3 "arith_or_logical_operator"
20722                      [(match_operand:SI 1 "nonmemory_operand" "")
20723                       (match_dup 0)]))
20724               (clobber (reg:CC FLAGS_REG))])]
20725   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20726   [(set (match_dup 2) (match_dup 0))
20727    (parallel [(set (match_dup 2)
20728                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20729               (clobber (reg:CC FLAGS_REG))])
20730    (set (match_dup 0) (match_dup 2))]
20731   "")
20732
20733 ;; Attempt to always use XOR for zeroing registers.
20734 (define_peephole2
20735   [(set (match_operand 0 "register_operand" "")
20736         (match_operand 1 "const0_operand" ""))]
20737   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20738    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20739    && GENERAL_REG_P (operands[0])
20740    && peep2_regno_dead_p (0, FLAGS_REG)"
20741   [(parallel [(set (match_dup 0) (const_int 0))
20742               (clobber (reg:CC FLAGS_REG))])]
20743 {
20744   operands[0] = gen_lowpart (word_mode, operands[0]);
20745 })
20746
20747 (define_peephole2
20748   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20749         (const_int 0))]
20750   "(GET_MODE (operands[0]) == QImode
20751     || GET_MODE (operands[0]) == HImode)
20752    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20753    && peep2_regno_dead_p (0, FLAGS_REG)"
20754   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20755               (clobber (reg:CC FLAGS_REG))])])
20756
20757 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20758 (define_peephole2
20759   [(set (match_operand 0 "register_operand" "")
20760         (const_int -1))]
20761   "(GET_MODE (operands[0]) == HImode
20762     || GET_MODE (operands[0]) == SImode
20763     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20764    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20765    && peep2_regno_dead_p (0, FLAGS_REG)"
20766   [(parallel [(set (match_dup 0) (const_int -1))
20767               (clobber (reg:CC FLAGS_REG))])]
20768   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20769                               operands[0]);")
20770
20771 ;; Attempt to convert simple leas to adds. These can be created by
20772 ;; move expanders.
20773 (define_peephole2
20774   [(set (match_operand:SI 0 "register_operand" "")
20775         (plus:SI (match_dup 0)
20776                  (match_operand:SI 1 "nonmemory_operand" "")))]
20777   "peep2_regno_dead_p (0, FLAGS_REG)"
20778   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20779               (clobber (reg:CC FLAGS_REG))])]
20780   "")
20781
20782 (define_peephole2
20783   [(set (match_operand:SI 0 "register_operand" "")
20784         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20785                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20786   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20787   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20788               (clobber (reg:CC FLAGS_REG))])]
20789   "operands[2] = gen_lowpart (SImode, operands[2]);")
20790
20791 (define_peephole2
20792   [(set (match_operand:DI 0 "register_operand" "")
20793         (plus:DI (match_dup 0)
20794                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20795   "peep2_regno_dead_p (0, FLAGS_REG)"
20796   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20797               (clobber (reg:CC FLAGS_REG))])]
20798   "")
20799
20800 (define_peephole2
20801   [(set (match_operand:SI 0 "register_operand" "")
20802         (mult:SI (match_dup 0)
20803                  (match_operand:SI 1 "const_int_operand" "")))]
20804   "exact_log2 (INTVAL (operands[1])) >= 0
20805    && peep2_regno_dead_p (0, FLAGS_REG)"
20806   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20807               (clobber (reg:CC FLAGS_REG))])]
20808   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20809
20810 (define_peephole2
20811   [(set (match_operand:DI 0 "register_operand" "")
20812         (mult:DI (match_dup 0)
20813                  (match_operand:DI 1 "const_int_operand" "")))]
20814   "exact_log2 (INTVAL (operands[1])) >= 0
20815    && peep2_regno_dead_p (0, FLAGS_REG)"
20816   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20817               (clobber (reg:CC FLAGS_REG))])]
20818   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20819
20820 (define_peephole2
20821   [(set (match_operand:SI 0 "register_operand" "")
20822         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20823                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20824   "exact_log2 (INTVAL (operands[2])) >= 0
20825    && REGNO (operands[0]) == REGNO (operands[1])
20826    && peep2_regno_dead_p (0, FLAGS_REG)"
20827   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20828               (clobber (reg:CC FLAGS_REG))])]
20829   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20830
20831 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20832 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20833 ;; many CPUs it is also faster, since special hardware to avoid esp
20834 ;; dependencies is present.
20835
20836 ;; While some of these conversions may be done using splitters, we use peepholes
20837 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20838
20839 ;; Convert prologue esp subtractions to push.
20840 ;; We need register to push.  In order to keep verify_flow_info happy we have
20841 ;; two choices
20842 ;; - use scratch and clobber it in order to avoid dependencies
20843 ;; - use already live register
20844 ;; We can't use the second way right now, since there is no reliable way how to
20845 ;; verify that given register is live.  First choice will also most likely in
20846 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20847 ;; call clobbered registers are dead.  We may want to use base pointer as an
20848 ;; alternative when no register is available later.
20849
20850 (define_peephole2
20851   [(match_scratch:SI 0 "r")
20852    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20853               (clobber (reg:CC FLAGS_REG))
20854               (clobber (mem:BLK (scratch)))])]
20855   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20856   [(clobber (match_dup 0))
20857    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20858               (clobber (mem:BLK (scratch)))])])
20859
20860 (define_peephole2
20861   [(match_scratch:SI 0 "r")
20862    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20863               (clobber (reg:CC FLAGS_REG))
20864               (clobber (mem:BLK (scratch)))])]
20865   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20866   [(clobber (match_dup 0))
20867    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20868    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20869               (clobber (mem:BLK (scratch)))])])
20870
20871 ;; Convert esp subtractions to push.
20872 (define_peephole2
20873   [(match_scratch:SI 0 "r")
20874    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20875               (clobber (reg:CC FLAGS_REG))])]
20876   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20877   [(clobber (match_dup 0))
20878    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20879
20880 (define_peephole2
20881   [(match_scratch:SI 0 "r")
20882    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20883               (clobber (reg:CC FLAGS_REG))])]
20884   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20885   [(clobber (match_dup 0))
20886    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20887    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20888
20889 ;; Convert epilogue deallocator to pop.
20890 (define_peephole2
20891   [(match_scratch:SI 0 "r")
20892    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20893               (clobber (reg:CC FLAGS_REG))
20894               (clobber (mem:BLK (scratch)))])]
20895   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20896   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20897               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20898               (clobber (mem:BLK (scratch)))])]
20899   "")
20900
20901 ;; Two pops case is tricky, since pop causes dependency on destination register.
20902 ;; We use two registers if available.
20903 (define_peephole2
20904   [(match_scratch:SI 0 "r")
20905    (match_scratch:SI 1 "r")
20906    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20907               (clobber (reg:CC FLAGS_REG))
20908               (clobber (mem:BLK (scratch)))])]
20909   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20910   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20911               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20912               (clobber (mem:BLK (scratch)))])
20913    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20914               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20915   "")
20916
20917 (define_peephole2
20918   [(match_scratch:SI 0 "r")
20919    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20920               (clobber (reg:CC FLAGS_REG))
20921               (clobber (mem:BLK (scratch)))])]
20922   "optimize_insn_for_size_p ()"
20923   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20924               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20925               (clobber (mem:BLK (scratch)))])
20926    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20927               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20928   "")
20929
20930 ;; Convert esp additions to pop.
20931 (define_peephole2
20932   [(match_scratch:SI 0 "r")
20933    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20934               (clobber (reg:CC FLAGS_REG))])]
20935   ""
20936   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20937               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20938   "")
20939
20940 ;; Two pops case is tricky, since pop causes dependency on destination register.
20941 ;; We use two registers if available.
20942 (define_peephole2
20943   [(match_scratch:SI 0 "r")
20944    (match_scratch:SI 1 "r")
20945    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
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    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20951               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20952   "")
20953
20954 (define_peephole2
20955   [(match_scratch:SI 0 "r")
20956    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20957               (clobber (reg:CC FLAGS_REG))])]
20958   "optimize_insn_for_size_p ()"
20959   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20960               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20961    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20962               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20963   "")
20964 \f
20965 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20966 ;; required and register dies.  Similarly for 128 to -128.
20967 (define_peephole2
20968   [(set (match_operand 0 "flags_reg_operand" "")
20969         (match_operator 1 "compare_operator"
20970           [(match_operand 2 "register_operand" "")
20971            (match_operand 3 "const_int_operand" "")]))]
20972   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20973      && incdec_operand (operands[3], GET_MODE (operands[3])))
20974     || (!TARGET_FUSE_CMP_AND_BRANCH
20975         && INTVAL (operands[3]) == 128))
20976    && ix86_match_ccmode (insn, CCGCmode)
20977    && peep2_reg_dead_p (1, operands[2])"
20978   [(parallel [(set (match_dup 0)
20979                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20980               (clobber (match_dup 2))])]
20981   "")
20982 \f
20983 (define_peephole2
20984   [(match_scratch:DI 0 "r")
20985    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20986               (clobber (reg:CC FLAGS_REG))
20987               (clobber (mem:BLK (scratch)))])]
20988   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20989   [(clobber (match_dup 0))
20990    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20991               (clobber (mem:BLK (scratch)))])])
20992
20993 (define_peephole2
20994   [(match_scratch:DI 0 "r")
20995    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20996               (clobber (reg:CC FLAGS_REG))
20997               (clobber (mem:BLK (scratch)))])]
20998   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20999   [(clobber (match_dup 0))
21000    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21001    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21002               (clobber (mem:BLK (scratch)))])])
21003
21004 ;; Convert esp subtractions to push.
21005 (define_peephole2
21006   [(match_scratch:DI 0 "r")
21007    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21008               (clobber (reg:CC FLAGS_REG))])]
21009   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21010   [(clobber (match_dup 0))
21011    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21012
21013 (define_peephole2
21014   [(match_scratch:DI 0 "r")
21015    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21016               (clobber (reg:CC FLAGS_REG))])]
21017   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21018   [(clobber (match_dup 0))
21019    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21020    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21021
21022 ;; Convert epilogue deallocator to pop.
21023 (define_peephole2
21024   [(match_scratch:DI 0 "r")
21025    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21026               (clobber (reg:CC FLAGS_REG))
21027               (clobber (mem:BLK (scratch)))])]
21028   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21029   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21030               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21031               (clobber (mem:BLK (scratch)))])]
21032   "")
21033
21034 ;; Two pops case is tricky, since pop causes dependency on destination register.
21035 ;; We use two registers if available.
21036 (define_peephole2
21037   [(match_scratch:DI 0 "r")
21038    (match_scratch:DI 1 "r")
21039    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21040               (clobber (reg:CC FLAGS_REG))
21041               (clobber (mem:BLK (scratch)))])]
21042   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21043   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21044               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21045               (clobber (mem:BLK (scratch)))])
21046    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21047               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21048   "")
21049
21050 (define_peephole2
21051   [(match_scratch:DI 0 "r")
21052    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21053               (clobber (reg:CC FLAGS_REG))
21054               (clobber (mem:BLK (scratch)))])]
21055   "optimize_insn_for_size_p ()"
21056   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21057               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21058               (clobber (mem:BLK (scratch)))])
21059    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21060               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21061   "")
21062
21063 ;; Convert esp additions to pop.
21064 (define_peephole2
21065   [(match_scratch:DI 0 "r")
21066    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21067               (clobber (reg:CC FLAGS_REG))])]
21068   ""
21069   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21070               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21071   "")
21072
21073 ;; Two pops case is tricky, since pop causes dependency on destination register.
21074 ;; We use two registers if available.
21075 (define_peephole2
21076   [(match_scratch:DI 0 "r")
21077    (match_scratch:DI 1 "r")
21078    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
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    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21084               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21085   "")
21086
21087 (define_peephole2
21088   [(match_scratch:DI 0 "r")
21089    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21090               (clobber (reg:CC FLAGS_REG))])]
21091   "optimize_insn_for_size_p ()"
21092   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21093               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21094    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21095               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21096   "")
21097 \f
21098 ;; Convert imul by three, five and nine into lea
21099 (define_peephole2
21100   [(parallel
21101     [(set (match_operand:SI 0 "register_operand" "")
21102           (mult:SI (match_operand:SI 1 "register_operand" "")
21103                    (match_operand:SI 2 "const_int_operand" "")))
21104      (clobber (reg:CC FLAGS_REG))])]
21105   "INTVAL (operands[2]) == 3
21106    || INTVAL (operands[2]) == 5
21107    || INTVAL (operands[2]) == 9"
21108   [(set (match_dup 0)
21109         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21110                  (match_dup 1)))]
21111   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21112
21113 (define_peephole2
21114   [(parallel
21115     [(set (match_operand:SI 0 "register_operand" "")
21116           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21117                    (match_operand:SI 2 "const_int_operand" "")))
21118      (clobber (reg:CC FLAGS_REG))])]
21119   "optimize_insn_for_speed_p ()
21120    && (INTVAL (operands[2]) == 3
21121        || INTVAL (operands[2]) == 5
21122        || INTVAL (operands[2]) == 9)"
21123   [(set (match_dup 0) (match_dup 1))
21124    (set (match_dup 0)
21125         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21126                  (match_dup 0)))]
21127   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21128
21129 (define_peephole2
21130   [(parallel
21131     [(set (match_operand:DI 0 "register_operand" "")
21132           (mult:DI (match_operand:DI 1 "register_operand" "")
21133                    (match_operand:DI 2 "const_int_operand" "")))
21134      (clobber (reg:CC FLAGS_REG))])]
21135   "TARGET_64BIT
21136    && (INTVAL (operands[2]) == 3
21137        || INTVAL (operands[2]) == 5
21138        || INTVAL (operands[2]) == 9)"
21139   [(set (match_dup 0)
21140         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21141                  (match_dup 1)))]
21142   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21143
21144 (define_peephole2
21145   [(parallel
21146     [(set (match_operand:DI 0 "register_operand" "")
21147           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21148                    (match_operand:DI 2 "const_int_operand" "")))
21149      (clobber (reg:CC FLAGS_REG))])]
21150   "TARGET_64BIT
21151    && optimize_insn_for_speed_p ()
21152    && (INTVAL (operands[2]) == 3
21153        || INTVAL (operands[2]) == 5
21154        || INTVAL (operands[2]) == 9)"
21155   [(set (match_dup 0) (match_dup 1))
21156    (set (match_dup 0)
21157         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21158                  (match_dup 0)))]
21159   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21160
21161 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21162 ;; imul $32bit_imm, reg, reg is direct decoded.
21163 (define_peephole2
21164   [(match_scratch:DI 3 "r")
21165    (parallel [(set (match_operand:DI 0 "register_operand" "")
21166                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21167                             (match_operand:DI 2 "immediate_operand" "")))
21168               (clobber (reg:CC FLAGS_REG))])]
21169   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21170    && !satisfies_constraint_K (operands[2])"
21171   [(set (match_dup 3) (match_dup 1))
21172    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21173               (clobber (reg:CC FLAGS_REG))])]
21174 "")
21175
21176 (define_peephole2
21177   [(match_scratch:SI 3 "r")
21178    (parallel [(set (match_operand:SI 0 "register_operand" "")
21179                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21180                             (match_operand:SI 2 "immediate_operand" "")))
21181               (clobber (reg:CC FLAGS_REG))])]
21182   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21183    && !satisfies_constraint_K (operands[2])"
21184   [(set (match_dup 3) (match_dup 1))
21185    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21186               (clobber (reg:CC FLAGS_REG))])]
21187 "")
21188
21189 (define_peephole2
21190   [(match_scratch:SI 3 "r")
21191    (parallel [(set (match_operand:DI 0 "register_operand" "")
21192                    (zero_extend:DI
21193                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21194                               (match_operand:SI 2 "immediate_operand" ""))))
21195               (clobber (reg:CC FLAGS_REG))])]
21196   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21197    && !satisfies_constraint_K (operands[2])"
21198   [(set (match_dup 3) (match_dup 1))
21199    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21200               (clobber (reg:CC FLAGS_REG))])]
21201 "")
21202
21203 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21204 ;; Convert it into imul reg, reg
21205 ;; It would be better to force assembler to encode instruction using long
21206 ;; immediate, but there is apparently no way to do so.
21207 (define_peephole2
21208   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21209                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21210                             (match_operand:DI 2 "const_int_operand" "")))
21211               (clobber (reg:CC FLAGS_REG))])
21212    (match_scratch:DI 3 "r")]
21213   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21214    && satisfies_constraint_K (operands[2])"
21215   [(set (match_dup 3) (match_dup 2))
21216    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21217               (clobber (reg:CC FLAGS_REG))])]
21218 {
21219   if (!rtx_equal_p (operands[0], operands[1]))
21220     emit_move_insn (operands[0], operands[1]);
21221 })
21222
21223 (define_peephole2
21224   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21225                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21226                             (match_operand:SI 2 "const_int_operand" "")))
21227               (clobber (reg:CC FLAGS_REG))])
21228    (match_scratch:SI 3 "r")]
21229   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21230    && satisfies_constraint_K (operands[2])"
21231   [(set (match_dup 3) (match_dup 2))
21232    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21233               (clobber (reg:CC FLAGS_REG))])]
21234 {
21235   if (!rtx_equal_p (operands[0], operands[1]))
21236     emit_move_insn (operands[0], operands[1]);
21237 })
21238
21239 (define_peephole2
21240   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21241                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21242                             (match_operand:HI 2 "immediate_operand" "")))
21243               (clobber (reg:CC FLAGS_REG))])
21244    (match_scratch:HI 3 "r")]
21245   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21246   [(set (match_dup 3) (match_dup 2))
21247    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21248               (clobber (reg:CC FLAGS_REG))])]
21249 {
21250   if (!rtx_equal_p (operands[0], operands[1]))
21251     emit_move_insn (operands[0], operands[1]);
21252 })
21253
21254 ;; After splitting up read-modify operations, array accesses with memory
21255 ;; operands might end up in form:
21256 ;;  sall    $2, %eax
21257 ;;  movl    4(%esp), %edx
21258 ;;  addl    %edx, %eax
21259 ;; instead of pre-splitting:
21260 ;;  sall    $2, %eax
21261 ;;  addl    4(%esp), %eax
21262 ;; Turn it into:
21263 ;;  movl    4(%esp), %edx
21264 ;;  leal    (%edx,%eax,4), %eax
21265
21266 (define_peephole2
21267   [(parallel [(set (match_operand 0 "register_operand" "")
21268                    (ashift (match_operand 1 "register_operand" "")
21269                            (match_operand 2 "const_int_operand" "")))
21270                (clobber (reg:CC FLAGS_REG))])
21271    (set (match_operand 3 "register_operand")
21272         (match_operand 4 "x86_64_general_operand" ""))
21273    (parallel [(set (match_operand 5 "register_operand" "")
21274                    (plus (match_operand 6 "register_operand" "")
21275                          (match_operand 7 "register_operand" "")))
21276                    (clobber (reg:CC FLAGS_REG))])]
21277   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21278    /* Validate MODE for lea.  */
21279    && ((!TARGET_PARTIAL_REG_STALL
21280         && (GET_MODE (operands[0]) == QImode
21281             || GET_MODE (operands[0]) == HImode))
21282        || GET_MODE (operands[0]) == SImode
21283        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21284    /* We reorder load and the shift.  */
21285    && !rtx_equal_p (operands[1], operands[3])
21286    && !reg_overlap_mentioned_p (operands[0], operands[4])
21287    /* Last PLUS must consist of operand 0 and 3.  */
21288    && !rtx_equal_p (operands[0], operands[3])
21289    && (rtx_equal_p (operands[3], operands[6])
21290        || rtx_equal_p (operands[3], operands[7]))
21291    && (rtx_equal_p (operands[0], operands[6])
21292        || rtx_equal_p (operands[0], operands[7]))
21293    /* The intermediate operand 0 must die or be same as output.  */
21294    && (rtx_equal_p (operands[0], operands[5])
21295        || peep2_reg_dead_p (3, operands[0]))"
21296   [(set (match_dup 3) (match_dup 4))
21297    (set (match_dup 0) (match_dup 1))]
21298 {
21299   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21300   int scale = 1 << INTVAL (operands[2]);
21301   rtx index = gen_lowpart (Pmode, operands[1]);
21302   rtx base = gen_lowpart (Pmode, operands[3]);
21303   rtx dest = gen_lowpart (mode, operands[5]);
21304
21305   operands[1] = gen_rtx_PLUS (Pmode, base,
21306                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21307   if (mode != Pmode)
21308     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21309   operands[0] = dest;
21310 })
21311 \f
21312 ;; Call-value patterns last so that the wildcard operand does not
21313 ;; disrupt insn-recog's switch tables.
21314
21315 (define_insn "*call_value_pop_0"
21316   [(set (match_operand 0 "" "")
21317         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21318               (match_operand:SI 2 "" "")))
21319    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21320                             (match_operand:SI 3 "immediate_operand" "")))]
21321   "!TARGET_64BIT"
21322 {
21323   if (SIBLING_CALL_P (insn))
21324     return "jmp\t%P1";
21325   else
21326     return "call\t%P1";
21327 }
21328   [(set_attr "type" "callv")])
21329
21330 (define_insn "*call_value_pop_1"
21331   [(set (match_operand 0 "" "")
21332         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21333               (match_operand:SI 2 "" "")))
21334    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21335                             (match_operand:SI 3 "immediate_operand" "i")))]
21336   "!TARGET_64BIT"
21337 {
21338   if (constant_call_address_operand (operands[1], Pmode))
21339     {
21340       if (SIBLING_CALL_P (insn))
21341         return "jmp\t%P1";
21342       else
21343         return "call\t%P1";
21344     }
21345   if (SIBLING_CALL_P (insn))
21346     return "jmp\t%A1";
21347   else
21348     return "call\t%A1";
21349 }
21350   [(set_attr "type" "callv")])
21351
21352 (define_insn "*call_value_0"
21353   [(set (match_operand 0 "" "")
21354         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21355               (match_operand:SI 2 "" "")))]
21356   "!TARGET_64BIT"
21357 {
21358   if (SIBLING_CALL_P (insn))
21359     return "jmp\t%P1";
21360   else
21361     return "call\t%P1";
21362 }
21363   [(set_attr "type" "callv")])
21364
21365 (define_insn "*call_value_0_rex64"
21366   [(set (match_operand 0 "" "")
21367         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21368               (match_operand:DI 2 "const_int_operand" "")))]
21369   "TARGET_64BIT"
21370 {
21371   if (SIBLING_CALL_P (insn))
21372     return "jmp\t%P1";
21373   else
21374     return "call\t%P1";
21375 }
21376   [(set_attr "type" "callv")])
21377
21378 (define_insn "*call_value_0_rex64_ms_sysv"
21379   [(set (match_operand 0 "" "")
21380         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21381               (match_operand:DI 2 "const_int_operand" "")))
21382    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21383    (clobber (reg:DI SI_REG))
21384    (clobber (reg:DI DI_REG))]
21385   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21386 {
21387   if (SIBLING_CALL_P (insn))
21388     return "jmp\t%P1";
21389   else
21390     return "call\t%P1";
21391 }
21392   [(set_attr "type" "callv")])
21393
21394 (define_insn "*call_value_1"
21395   [(set (match_operand 0 "" "")
21396         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21397               (match_operand:SI 2 "" "")))]
21398   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21399 {
21400   if (constant_call_address_operand (operands[1], Pmode))
21401     return "call\t%P1";
21402   return "call\t%A1";
21403 }
21404   [(set_attr "type" "callv")])
21405
21406 (define_insn "*sibcall_value_1"
21407   [(set (match_operand 0 "" "")
21408         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21409               (match_operand:SI 2 "" "")))]
21410   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21411 {
21412   if (constant_call_address_operand (operands[1], Pmode))
21413     return "jmp\t%P1";
21414   return "jmp\t%A1";
21415 }
21416   [(set_attr "type" "callv")])
21417
21418 (define_insn "*call_value_1_rex64"
21419   [(set (match_operand 0 "" "")
21420         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21421               (match_operand:DI 2 "" "")))]
21422   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21423    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21424 {
21425   if (constant_call_address_operand (operands[1], Pmode))
21426     return "call\t%P1";
21427   return "call\t%A1";
21428 }
21429   [(set_attr "type" "callv")])
21430
21431 (define_insn "*call_value_1_rex64_ms_sysv"
21432   [(set (match_operand 0 "" "")
21433         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21434               (match_operand:DI 2 "" "")))
21435    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21436    (clobber (reg:DI SI_REG))
21437    (clobber (reg:DI DI_REG))]
21438   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21439 {
21440   if (constant_call_address_operand (operands[1], Pmode))
21441     return "call\t%P1";
21442   return "call\t%A1";
21443 }
21444   [(set_attr "type" "callv")])
21445
21446 (define_insn "*call_value_1_rex64_large"
21447   [(set (match_operand 0 "" "")
21448         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21449               (match_operand:DI 2 "" "")))]
21450   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21451   "call\t%A1"
21452   [(set_attr "type" "callv")])
21453
21454 (define_insn "*sibcall_value_1_rex64"
21455   [(set (match_operand 0 "" "")
21456         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21457               (match_operand:DI 2 "" "")))]
21458   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21459   "jmp\t%P1"
21460   [(set_attr "type" "callv")])
21461
21462 (define_insn "*sibcall_value_1_rex64_v"
21463   [(set (match_operand 0 "" "")
21464         (call (mem:QI (reg:DI R11_REG))
21465               (match_operand:DI 1 "" "")))]
21466   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21467   "jmp\t{*%%}r11"
21468   [(set_attr "type" "callv")])
21469 \f
21470 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21471 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21472 ;; caught for use by garbage collectors and the like.  Using an insn that
21473 ;; maps to SIGILL makes it more likely the program will rightfully die.
21474 ;; Keeping with tradition, "6" is in honor of #UD.
21475 (define_insn "trap"
21476   [(trap_if (const_int 1) (const_int 6))]
21477   ""
21478   { return ASM_SHORT "0x0b0f"; }
21479   [(set_attr "length" "2")])
21480
21481 (define_expand "sse_prologue_save"
21482   [(parallel [(set (match_operand:BLK 0 "" "")
21483                    (unspec:BLK [(reg:DI 21)
21484                                 (reg:DI 22)
21485                                 (reg:DI 23)
21486                                 (reg:DI 24)
21487                                 (reg:DI 25)
21488                                 (reg:DI 26)
21489                                 (reg:DI 27)
21490                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21491               (use (match_operand:DI 1 "register_operand" ""))
21492               (use (match_operand:DI 2 "immediate_operand" ""))
21493               (use (label_ref:DI (match_operand 3 "" "")))])]
21494   "TARGET_64BIT"
21495   "")
21496
21497 (define_insn "*sse_prologue_save_insn"
21498   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21499                           (match_operand:DI 4 "const_int_operand" "n")))
21500         (unspec:BLK [(reg:DI 21)
21501                      (reg:DI 22)
21502                      (reg:DI 23)
21503                      (reg:DI 24)
21504                      (reg:DI 25)
21505                      (reg:DI 26)
21506                      (reg:DI 27)
21507                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21508    (use (match_operand:DI 1 "register_operand" "r"))
21509    (use (match_operand:DI 2 "const_int_operand" "i"))
21510    (use (label_ref:DI (match_operand 3 "" "X")))]
21511   "TARGET_64BIT
21512    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21513    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21514 {
21515   int i;
21516   operands[0] = gen_rtx_MEM (Pmode,
21517                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21518   /* VEX instruction with a REX prefix will #UD.  */
21519   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21520     gcc_unreachable ();
21521
21522   output_asm_insn ("jmp\t%A1", operands);
21523   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21524     {
21525       operands[4] = adjust_address (operands[0], DImode, i*16);
21526       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21527       PUT_MODE (operands[4], TImode);
21528       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21529         output_asm_insn ("rex", operands);
21530       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21531     }
21532   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21533                                      CODE_LABEL_NUMBER (operands[3]));
21534   return "";
21535 }
21536   [(set_attr "type" "other")
21537    (set_attr "length_immediate" "0")
21538    (set_attr "length_address" "0")
21539    (set (attr "length")
21540      (if_then_else
21541        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21542        (const_string "34")
21543        (const_string "42")))
21544    (set_attr "memory" "store")
21545    (set_attr "modrm" "0")
21546    (set_attr "prefix" "maybe_vex")
21547    (set_attr "mode" "DI")])
21548
21549 (define_expand "prefetch"
21550   [(prefetch (match_operand 0 "address_operand" "")
21551              (match_operand:SI 1 "const_int_operand" "")
21552              (match_operand:SI 2 "const_int_operand" ""))]
21553   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21554 {
21555   int rw = INTVAL (operands[1]);
21556   int locality = INTVAL (operands[2]);
21557
21558   gcc_assert (rw == 0 || rw == 1);
21559   gcc_assert (locality >= 0 && locality <= 3);
21560   gcc_assert (GET_MODE (operands[0]) == Pmode
21561               || GET_MODE (operands[0]) == VOIDmode);
21562
21563   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21564      supported by SSE counterpart or the SSE prefetch is not available
21565      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21566      of locality.  */
21567   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21568     operands[2] = GEN_INT (3);
21569   else
21570     operands[1] = const0_rtx;
21571 })
21572
21573 (define_insn "*prefetch_sse"
21574   [(prefetch (match_operand:SI 0 "address_operand" "p")
21575              (const_int 0)
21576              (match_operand:SI 1 "const_int_operand" ""))]
21577   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21578 {
21579   static const char * const patterns[4] = {
21580    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21581   };
21582
21583   int locality = INTVAL (operands[1]);
21584   gcc_assert (locality >= 0 && locality <= 3);
21585
21586   return patterns[locality];
21587 }
21588   [(set_attr "type" "sse")
21589    (set_attr "memory" "none")])
21590
21591 (define_insn "*prefetch_sse_rex"
21592   [(prefetch (match_operand:DI 0 "address_operand" "p")
21593              (const_int 0)
21594              (match_operand:SI 1 "const_int_operand" ""))]
21595   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21596 {
21597   static const char * const patterns[4] = {
21598    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21599   };
21600
21601   int locality = INTVAL (operands[1]);
21602   gcc_assert (locality >= 0 && locality <= 3);
21603
21604   return patterns[locality];
21605 }
21606   [(set_attr "type" "sse")
21607    (set_attr "memory" "none")])
21608
21609 (define_insn "*prefetch_3dnow"
21610   [(prefetch (match_operand:SI 0 "address_operand" "p")
21611              (match_operand:SI 1 "const_int_operand" "n")
21612              (const_int 3))]
21613   "TARGET_3DNOW && !TARGET_64BIT"
21614 {
21615   if (INTVAL (operands[1]) == 0)
21616     return "prefetch\t%a0";
21617   else
21618     return "prefetchw\t%a0";
21619 }
21620   [(set_attr "type" "mmx")
21621    (set_attr "memory" "none")])
21622
21623 (define_insn "*prefetch_3dnow_rex"
21624   [(prefetch (match_operand:DI 0 "address_operand" "p")
21625              (match_operand:SI 1 "const_int_operand" "n")
21626              (const_int 3))]
21627   "TARGET_3DNOW && TARGET_64BIT"
21628 {
21629   if (INTVAL (operands[1]) == 0)
21630     return "prefetch\t%a0";
21631   else
21632     return "prefetchw\t%a0";
21633 }
21634   [(set_attr "type" "mmx")
21635    (set_attr "memory" "none")])
21636
21637 (define_expand "stack_protect_set"
21638   [(match_operand 0 "memory_operand" "")
21639    (match_operand 1 "memory_operand" "")]
21640   ""
21641 {
21642 #ifdef TARGET_THREAD_SSP_OFFSET
21643   if (TARGET_64BIT)
21644     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21645                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21646   else
21647     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21648                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21649 #else
21650   if (TARGET_64BIT)
21651     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21652   else
21653     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21654 #endif
21655   DONE;
21656 })
21657
21658 (define_insn "stack_protect_set_si"
21659   [(set (match_operand:SI 0 "memory_operand" "=m")
21660         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21661    (set (match_scratch:SI 2 "=&r") (const_int 0))
21662    (clobber (reg:CC FLAGS_REG))]
21663   ""
21664   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21665   [(set_attr "type" "multi")])
21666
21667 (define_insn "stack_protect_set_di"
21668   [(set (match_operand:DI 0 "memory_operand" "=m")
21669         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21670    (set (match_scratch:DI 2 "=&r") (const_int 0))
21671    (clobber (reg:CC FLAGS_REG))]
21672   "TARGET_64BIT"
21673   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21674   [(set_attr "type" "multi")])
21675
21676 (define_insn "stack_tls_protect_set_si"
21677   [(set (match_operand:SI 0 "memory_operand" "=m")
21678         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21679    (set (match_scratch:SI 2 "=&r") (const_int 0))
21680    (clobber (reg:CC FLAGS_REG))]
21681   ""
21682   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21683   [(set_attr "type" "multi")])
21684
21685 (define_insn "stack_tls_protect_set_di"
21686   [(set (match_operand:DI 0 "memory_operand" "=m")
21687         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21688    (set (match_scratch:DI 2 "=&r") (const_int 0))
21689    (clobber (reg:CC FLAGS_REG))]
21690   "TARGET_64BIT"
21691   {
21692      /* The kernel uses a different segment register for performance reasons; a
21693         system call would not have to trash the userspace segment register,
21694         which would be expensive */
21695      if (ix86_cmodel != CM_KERNEL)
21696         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21697      else
21698         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21699   }
21700   [(set_attr "type" "multi")])
21701
21702 (define_expand "stack_protect_test"
21703   [(match_operand 0 "memory_operand" "")
21704    (match_operand 1 "memory_operand" "")
21705    (match_operand 2 "" "")]
21706   ""
21707 {
21708   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21709   ix86_compare_op0 = operands[0];
21710   ix86_compare_op1 = operands[1];
21711   ix86_compare_emitted = flags;
21712
21713 #ifdef TARGET_THREAD_SSP_OFFSET
21714   if (TARGET_64BIT)
21715     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21716                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21717   else
21718     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21719                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21720 #else
21721   if (TARGET_64BIT)
21722     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21723   else
21724     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21725 #endif
21726   emit_jump_insn (gen_beq (operands[2]));
21727   DONE;
21728 })
21729
21730 (define_insn "stack_protect_test_si"
21731   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21732         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21733                      (match_operand:SI 2 "memory_operand" "m")]
21734                     UNSPEC_SP_TEST))
21735    (clobber (match_scratch:SI 3 "=&r"))]
21736   ""
21737   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21738   [(set_attr "type" "multi")])
21739
21740 (define_insn "stack_protect_test_di"
21741   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21742         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21743                      (match_operand:DI 2 "memory_operand" "m")]
21744                     UNSPEC_SP_TEST))
21745    (clobber (match_scratch:DI 3 "=&r"))]
21746   "TARGET_64BIT"
21747   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21748   [(set_attr "type" "multi")])
21749
21750 (define_insn "stack_tls_protect_test_si"
21751   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21752         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21753                      (match_operand:SI 2 "const_int_operand" "i")]
21754                     UNSPEC_SP_TLS_TEST))
21755    (clobber (match_scratch:SI 3 "=r"))]
21756   ""
21757   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21758   [(set_attr "type" "multi")])
21759
21760 (define_insn "stack_tls_protect_test_di"
21761   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21762         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21763                      (match_operand:DI 2 "const_int_operand" "i")]
21764                     UNSPEC_SP_TLS_TEST))
21765    (clobber (match_scratch:DI 3 "=r"))]
21766   "TARGET_64BIT"
21767   {
21768      /* The kernel uses a different segment register for performance reasons; a
21769         system call would not have to trash the userspace segment register,
21770         which would be expensive */
21771      if (ix86_cmodel != CM_KERNEL)
21772         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21773      else
21774         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21775   }
21776   [(set_attr "type" "multi")])
21777
21778 (define_mode_iterator CRC32MODE [QI HI SI])
21779 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21780 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21781
21782 (define_insn "sse4_2_crc32<mode>"
21783   [(set (match_operand:SI 0 "register_operand" "=r")
21784         (unspec:SI
21785           [(match_operand:SI 1 "register_operand" "0")
21786            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21787           UNSPEC_CRC32))]
21788   "TARGET_SSE4_2"
21789   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21790   [(set_attr "type" "sselog1")
21791    (set_attr "prefix_rep" "1")
21792    (set_attr "prefix_extra" "1")
21793    (set_attr "mode" "SI")])
21794
21795 (define_insn "sse4_2_crc32di"
21796   [(set (match_operand:DI 0 "register_operand" "=r")
21797         (unspec:DI
21798           [(match_operand:DI 1 "register_operand" "0")
21799            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21800           UNSPEC_CRC32))]
21801   "TARGET_SSE4_2 && TARGET_64BIT"
21802   "crc32q\t{%2, %0|%0, %2}"
21803   [(set_attr "type" "sselog1")
21804    (set_attr "prefix_rep" "1")
21805    (set_attr "prefix_extra" "1")
21806    (set_attr "mode" "DI")])
21807
21808 (include "mmx.md")
21809 (include "sse.md")
21810 (include "sync.md")