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    (UNSPEC_MEMORY_BLOCKAGE      18)
72
73    ; TLS support
74    (UNSPEC_TP                   20)
75    (UNSPEC_TLS_GD               21)
76    (UNSPEC_TLS_LD_BASE          22)
77    (UNSPEC_TLSDESC              23)
78
79    ; Other random patterns
80    (UNSPEC_SCAS                 30)
81    (UNSPEC_FNSTSW               31)
82    (UNSPEC_SAHF                 32)
83    (UNSPEC_FSTCW                33)
84    (UNSPEC_ADD_CARRY            34)
85    (UNSPEC_FLDCW                35)
86    (UNSPEC_REP                  36)
87    (UNSPEC_EH_RETURN            37)
88    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
89    (UNSPEC_TRUNC_NOOP           39)
90
91    ; For SSE/MMX support:
92    (UNSPEC_FIX_NOTRUNC          40)
93    (UNSPEC_MASKMOV              41)
94    (UNSPEC_MOVMSK               42)
95    (UNSPEC_MOVNT                43)
96    (UNSPEC_MOVU                 44)
97    (UNSPEC_RCP                  45)
98    (UNSPEC_RSQRT                46)
99    (UNSPEC_SFENCE               47)
100    (UNSPEC_PFRCP                49)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109    (UNSPEC_MS_TO_SYSV_CALL      48)
110
111    ; Generic math support
112    (UNSPEC_COPYSIGN             50)
113    (UNSPEC_IEEE_MIN             51)     ; not commutative
114    (UNSPEC_IEEE_MAX             52)     ; not commutative
115
116    ; x87 Floating point
117    (UNSPEC_SIN                  60)
118    (UNSPEC_COS                  61)
119    (UNSPEC_FPATAN               62)
120    (UNSPEC_FYL2X                63)
121    (UNSPEC_FYL2XP1              64)
122    (UNSPEC_FRNDINT              65)
123    (UNSPEC_FIST                 66)
124    (UNSPEC_F2XM1                67)
125    (UNSPEC_TAN                  68)
126    (UNSPEC_FXAM                 69)
127
128    ; x87 Rounding
129    (UNSPEC_FRNDINT_FLOOR        70)
130    (UNSPEC_FRNDINT_CEIL         71)
131    (UNSPEC_FRNDINT_TRUNC        72)
132    (UNSPEC_FRNDINT_MASK_PM      73)
133    (UNSPEC_FIST_FLOOR           74)
134    (UNSPEC_FIST_CEIL            75)
135
136    ; x87 Double output FP
137    (UNSPEC_SINCOS_COS           80)
138    (UNSPEC_SINCOS_SIN           81)
139    (UNSPEC_XTRACT_FRACT         84)
140    (UNSPEC_XTRACT_EXP           85)
141    (UNSPEC_FSCALE_FRACT         86)
142    (UNSPEC_FSCALE_EXP           87)
143    (UNSPEC_FPREM_F              88)
144    (UNSPEC_FPREM_U              89)
145    (UNSPEC_FPREM1_F             90)
146    (UNSPEC_FPREM1_U             91)
147
148    (UNSPEC_C2_FLAG              95)
149
150    ; SSP patterns
151    (UNSPEC_SP_SET               100)
152    (UNSPEC_SP_TEST              101)
153    (UNSPEC_SP_TLS_SET           102)
154    (UNSPEC_SP_TLS_TEST          103)
155
156    ; SSSE3
157    (UNSPEC_PSHUFB               120)
158    (UNSPEC_PSIGN                121)
159    (UNSPEC_PALIGNR              122)
160
161    ; For SSE4A support
162    (UNSPEC_EXTRQI               130)
163    (UNSPEC_EXTRQ                131)
164    (UNSPEC_INSERTQI             132)
165    (UNSPEC_INSERTQ              133)
166
167    ; For SSE4.1 support
168    (UNSPEC_BLENDV               134)
169    (UNSPEC_INSERTPS             135)
170    (UNSPEC_DP                   136)
171    (UNSPEC_MOVNTDQA             137)
172    (UNSPEC_MPSADBW              138)
173    (UNSPEC_PHMINPOSUW           139)
174    (UNSPEC_PTEST                140)
175    (UNSPEC_ROUND                141)
176
177    ; For SSE4.2 support
178    (UNSPEC_CRC32                143)
179    (UNSPEC_PCMPESTR             144)
180    (UNSPEC_PCMPISTR             145)
181
182    ;; For SSE5
183    (UNSPEC_SSE5_INTRINSIC       150)
184    (UNSPEC_SSE5_UNSIGNED_CMP    151)
185    (UNSPEC_SSE5_TRUEFALSE       152)
186    (UNSPEC_SSE5_PERMUTE         153)
187    (UNSPEC_FRCZ                 154)
188    (UNSPEC_CVTPH2PS             155)
189    (UNSPEC_CVTPS2PH             156)
190
191    ; For AES support
192    (UNSPEC_AESENC               159)
193    (UNSPEC_AESENCLAST           160)
194    (UNSPEC_AESDEC               161)
195    (UNSPEC_AESDECLAST           162)
196    (UNSPEC_AESIMC               163)
197    (UNSPEC_AESKEYGENASSIST      164)
198
199    ; For PCLMUL support
200    (UNSPEC_PCLMUL               165)
201
202    ; For AVX support
203    (UNSPEC_PCMP                 166)
204    (UNSPEC_VPERMIL              167)
205    (UNSPEC_VPERMIL2F128         168)
206    (UNSPEC_MASKLOAD             169)
207    (UNSPEC_MASKSTORE            170)
208    (UNSPEC_CAST                 171)
209    (UNSPEC_VTESTP               172)
210   ])
211
212 (define_constants
213   [(UNSPECV_BLOCKAGE            0)
214    (UNSPECV_STACK_PROBE         1)
215    (UNSPECV_EMMS                2)
216    (UNSPECV_LDMXCSR             3)
217    (UNSPECV_STMXCSR             4)
218    (UNSPECV_FEMMS               5)
219    (UNSPECV_CLFLUSH             6)
220    (UNSPECV_ALIGN               7)
221    (UNSPECV_MONITOR             8)
222    (UNSPECV_MWAIT               9)
223    (UNSPECV_CMPXCHG             10)
224    (UNSPECV_XCHG                12)
225    (UNSPECV_LOCK                13)
226    (UNSPECV_PROLOGUE_USE        14)
227    (UNSPECV_CLD                 15)
228    (UNSPECV_VZEROALL            16)
229    (UNSPECV_VZEROUPPER          17)
230   ])
231
232 ;; Constants to represent pcomtrue/pcomfalse variants
233 (define_constants
234   [(PCOM_FALSE                  0)
235    (PCOM_TRUE                   1)
236    (COM_FALSE_S                 2)
237    (COM_FALSE_P                 3)
238    (COM_TRUE_S                  4)
239    (COM_TRUE_P                  5)
240   ])
241
242 ;; Constants used in the SSE5 pperm instruction
243 (define_constants
244   [(PPERM_SRC                   0x00)   /* copy source */
245    (PPERM_INVERT                0x20)   /* invert source */
246    (PPERM_REVERSE               0x40)   /* bit reverse source */
247    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
248    (PPERM_ZERO                  0x80)   /* all 0's */
249    (PPERM_ONES                  0xa0)   /* all 1's */
250    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
251    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
252    (PPERM_SRC1                  0x00)   /* use first source byte */
253    (PPERM_SRC2                  0x10)   /* use second source byte */
254    ])
255
256 ;; Registers by name.
257 (define_constants
258   [(AX_REG                       0)
259    (DX_REG                       1)
260    (CX_REG                       2)
261    (BX_REG                       3)
262    (SI_REG                       4)
263    (DI_REG                       5)
264    (BP_REG                       6)
265    (SP_REG                       7)
266    (FLAGS_REG                   17)
267    (FPSR_REG                    18)
268    (FPCR_REG                    19)
269    (XMM0_REG                    21)
270    (XMM1_REG                    22)
271    (XMM2_REG                    23)
272    (XMM3_REG                    24)
273    (XMM4_REG                    25)
274    (XMM5_REG                    26)
275    (XMM6_REG                    27)
276    (XMM7_REG                    28)
277    (R10_REG                     39)
278    (R11_REG                     40)
279    (R13_REG                     42)
280    (XMM8_REG                    45)
281    (XMM9_REG                    46)
282    (XMM10_REG                   47)
283    (XMM11_REG                   48)
284    (XMM12_REG                   49)
285    (XMM13_REG                   50)
286    (XMM14_REG                   51)
287    (XMM15_REG                   52)
288   ])
289
290 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
291 ;; from i386.c.
292
293 ;; In C guard expressions, put expressions which may be compile-time
294 ;; constants first.  This allows for better optimization.  For
295 ;; example, write "TARGET_64BIT && reload_completed", not
296 ;; "reload_completed && TARGET_64BIT".
297
298 \f
299 ;; Processor type.
300 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
301                     generic64,amdfam10"
302   (const (symbol_ref "ix86_schedule")))
303
304 ;; A basic instruction type.  Refinements due to arguments to be
305 ;; provided in other attributes.
306 (define_attr "type"
307   "other,multi,
308    alu,alu1,negnot,imov,imovx,lea,
309    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
310    icmp,test,ibr,setcc,icmov,
311    push,pop,call,callv,leave,
312    str,bitmanip,
313    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
314    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
315    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
316    ssemuladd,sse4arg,
317    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
318   (const_string "other"))
319
320 ;; Main data type used by the insn
321 (define_attr "mode"
322   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
323   (const_string "unknown"))
324
325 ;; The CPU unit operations uses.
326 (define_attr "unit" "integer,i387,sse,mmx,unknown"
327   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
328            (const_string "i387")
329          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
330                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
331                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
332            (const_string "sse")
333          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
334            (const_string "mmx")
335          (eq_attr "type" "other")
336            (const_string "unknown")]
337          (const_string "integer")))
338
339 ;; The (bounding maximum) length of an instruction immediate.
340 (define_attr "length_immediate" ""
341   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
342                           bitmanip")
343            (const_int 0)
344          (eq_attr "unit" "i387,sse,mmx")
345            (const_int 0)
346          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
347                           imul,icmp,push,pop")
348            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
349          (eq_attr "type" "imov,test")
350            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
351          (eq_attr "type" "call")
352            (if_then_else (match_operand 0 "constant_call_address_operand" "")
353              (const_int 4)
354              (const_int 0))
355          (eq_attr "type" "callv")
356            (if_then_else (match_operand 1 "constant_call_address_operand" "")
357              (const_int 4)
358              (const_int 0))
359          ;; We don't know the size before shorten_branches.  Expect
360          ;; the instruction to fit for better scheduling.
361          (eq_attr "type" "ibr")
362            (const_int 1)
363          ]
364          (symbol_ref "/* Update immediate_length and other attributes! */
365                       gcc_unreachable (),1")))
366
367 ;; The (bounding maximum) length of an instruction address.
368 (define_attr "length_address" ""
369   (cond [(eq_attr "type" "str,other,multi,fxch")
370            (const_int 0)
371          (and (eq_attr "type" "call")
372               (match_operand 0 "constant_call_address_operand" ""))
373              (const_int 0)
374          (and (eq_attr "type" "callv")
375               (match_operand 1 "constant_call_address_operand" ""))
376              (const_int 0)
377          ]
378          (symbol_ref "ix86_attr_length_address_default (insn)")))
379
380 ;; Set when length prefix is used.
381 (define_attr "prefix_data16" ""
382   (if_then_else (ior (eq_attr "mode" "HI")
383                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
384     (const_int 1)
385     (const_int 0)))
386
387 ;; Set when string REP prefix is used.
388 (define_attr "prefix_rep" ""
389   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
390     (const_int 1)
391     (const_int 0)))
392
393 ;; Set when 0f opcode prefix is used.
394 (define_attr "prefix_0f" ""
395   (if_then_else
396     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
397          (eq_attr "unit" "sse,mmx"))
398     (const_int 1)
399     (const_int 0)))
400
401 ;; Set when REX opcode prefix is used.
402 (define_attr "prefix_rex" ""
403   (cond [(and (eq_attr "mode" "DI")
404               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
405            (const_int 1)
406          (and (eq_attr "mode" "QI")
407               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
408                   (const_int 0)))
409            (const_int 1)
410          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
411              (const_int 0))
412            (const_int 1)
413         ]
414         (const_int 0)))
415
416 ;; There are also additional prefixes in SSSE3.
417 (define_attr "prefix_extra" "" (const_int 0))
418
419 ;; Prefix used: original, VEX or maybe VEX.
420 (define_attr "prefix" "orig,vex,maybe_vex"
421   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
422     (const_string "vex")
423     (const_string "orig")))
424
425 ;; There is a 8bit immediate for VEX.
426 (define_attr "prefix_vex_imm8" "" (const_int 0))
427
428 ;; VEX W bit is used.
429 (define_attr "prefix_vex_w" "" (const_int 0))
430
431 ;; The length of VEX prefix
432 (define_attr "length_vex" ""
433   (if_then_else (eq_attr "prefix_0f" "1")
434     (if_then_else (eq_attr "prefix_vex_w" "1")
435       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
436       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
437     (if_then_else (eq_attr "prefix_vex_w" "1")
438       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
439       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
440
441 ;; Set when modrm byte is used.
442 (define_attr "modrm" ""
443   (cond [(eq_attr "type" "str,leave")
444            (const_int 0)
445          (eq_attr "unit" "i387")
446            (const_int 0)
447          (and (eq_attr "type" "incdec")
448               (ior (match_operand:SI 1 "register_operand" "")
449                    (match_operand:HI 1 "register_operand" "")))
450            (const_int 0)
451          (and (eq_attr "type" "push")
452               (not (match_operand 1 "memory_operand" "")))
453            (const_int 0)
454          (and (eq_attr "type" "pop")
455               (not (match_operand 0 "memory_operand" "")))
456            (const_int 0)
457          (and (eq_attr "type" "imov")
458               (ior (and (match_operand 0 "register_operand" "")
459                         (match_operand 1 "immediate_operand" ""))
460                    (ior (and (match_operand 0 "ax_reg_operand" "")
461                              (match_operand 1 "memory_displacement_only_operand" ""))
462                         (and (match_operand 0 "memory_displacement_only_operand" "")
463                              (match_operand 1 "ax_reg_operand" "")))))
464            (const_int 0)
465          (and (eq_attr "type" "call")
466               (match_operand 0 "constant_call_address_operand" ""))
467              (const_int 0)
468          (and (eq_attr "type" "callv")
469               (match_operand 1 "constant_call_address_operand" ""))
470              (const_int 0)
471          ]
472          (const_int 1)))
473
474 ;; The (bounding maximum) length of an instruction in bytes.
475 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
476 ;; Later we may want to split them and compute proper length as for
477 ;; other insns.
478 (define_attr "length" ""
479   (cond [(eq_attr "type" "other,multi,fistp,frndint")
480            (const_int 16)
481          (eq_attr "type" "fcmp")
482            (const_int 4)
483          (eq_attr "unit" "i387")
484            (plus (const_int 2)
485                  (plus (attr "prefix_data16")
486                        (attr "length_address")))
487          (ior (eq_attr "prefix" "vex")
488               (and (eq_attr "prefix" "maybe_vex")
489                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
490            (plus (attr "length_vex")
491                  (plus (attr "prefix_vex_imm8")
492                        (plus (attr "modrm")
493                              (attr "length_address"))))]
494          (plus (plus (attr "modrm")
495                      (plus (attr "prefix_0f")
496                            (plus (attr "prefix_rex")
497                                  (plus (attr "prefix_extra")
498                                        (const_int 1)))))
499                (plus (attr "prefix_rep")
500                      (plus (attr "prefix_data16")
501                            (plus (attr "length_immediate")
502                                  (attr "length_address")))))))
503
504 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
505 ;; `store' if there is a simple memory reference therein, or `unknown'
506 ;; if the instruction is complex.
507
508 (define_attr "memory" "none,load,store,both,unknown"
509   (cond [(eq_attr "type" "other,multi,str")
510            (const_string "unknown")
511          (eq_attr "type" "lea,fcmov,fpspc")
512            (const_string "none")
513          (eq_attr "type" "fistp,leave")
514            (const_string "both")
515          (eq_attr "type" "frndint")
516            (const_string "load")
517          (eq_attr "type" "push")
518            (if_then_else (match_operand 1 "memory_operand" "")
519              (const_string "both")
520              (const_string "store"))
521          (eq_attr "type" "pop")
522            (if_then_else (match_operand 0 "memory_operand" "")
523              (const_string "both")
524              (const_string "load"))
525          (eq_attr "type" "setcc")
526            (if_then_else (match_operand 0 "memory_operand" "")
527              (const_string "store")
528              (const_string "none"))
529          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
530            (if_then_else (ior (match_operand 0 "memory_operand" "")
531                               (match_operand 1 "memory_operand" ""))
532              (const_string "load")
533              (const_string "none"))
534          (eq_attr "type" "ibr")
535            (if_then_else (match_operand 0 "memory_operand" "")
536              (const_string "load")
537              (const_string "none"))
538          (eq_attr "type" "call")
539            (if_then_else (match_operand 0 "constant_call_address_operand" "")
540              (const_string "none")
541              (const_string "load"))
542          (eq_attr "type" "callv")
543            (if_then_else (match_operand 1 "constant_call_address_operand" "")
544              (const_string "none")
545              (const_string "load"))
546          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
547               (match_operand 1 "memory_operand" ""))
548            (const_string "both")
549          (and (match_operand 0 "memory_operand" "")
550               (match_operand 1 "memory_operand" ""))
551            (const_string "both")
552          (match_operand 0 "memory_operand" "")
553            (const_string "store")
554          (match_operand 1 "memory_operand" "")
555            (const_string "load")
556          (and (eq_attr "type"
557                  "!alu1,negnot,ishift1,
558                    imov,imovx,icmp,test,bitmanip,
559                    fmov,fcmp,fsgn,
560                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
561                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
562               (match_operand 2 "memory_operand" ""))
563            (const_string "load")
564          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
565               (match_operand 3 "memory_operand" ""))
566            (const_string "load")
567         ]
568         (const_string "none")))
569
570 ;; Indicates if an instruction has both an immediate and a displacement.
571
572 (define_attr "imm_disp" "false,true,unknown"
573   (cond [(eq_attr "type" "other,multi")
574            (const_string "unknown")
575          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
576               (and (match_operand 0 "memory_displacement_operand" "")
577                    (match_operand 1 "immediate_operand" "")))
578            (const_string "true")
579          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
580               (and (match_operand 0 "memory_displacement_operand" "")
581                    (match_operand 2 "immediate_operand" "")))
582            (const_string "true")
583         ]
584         (const_string "false")))
585
586 ;; Indicates if an FP operation has an integer source.
587
588 (define_attr "fp_int_src" "false,true"
589   (const_string "false"))
590
591 ;; Defines rounding mode of an FP operation.
592
593 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
594   (const_string "any"))
595
596 ;; Describe a user's asm statement.
597 (define_asm_attributes
598   [(set_attr "length" "128")
599    (set_attr "type" "multi")])
600
601 ;; All integer comparison codes.
602 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
603
604 ;; All floating-point comparison codes.
605 (define_code_iterator fp_cond [unordered ordered
606                                uneq unge ungt unle unlt ltgt ])
607
608 (define_code_iterator plusminus [plus minus])
609
610 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
611
612 ;; Base name for define_insn
613 (define_code_attr plusminus_insn
614   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
615    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
616
617 ;; Base name for insn mnemonic.
618 (define_code_attr plusminus_mnemonic
619   [(plus "add") (ss_plus "adds") (us_plus "addus")
620    (minus "sub") (ss_minus "subs") (us_minus "subus")])
621
622 ;; Mark commutative operators as such in constraints.
623 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
624                         (minus "") (ss_minus "") (us_minus "")])
625
626 ;; Mapping of signed max and min
627 (define_code_iterator smaxmin [smax smin])
628
629 ;; Mapping of unsigned max and min
630 (define_code_iterator umaxmin [umax umin])
631
632 ;; Mapping of signed/unsigned max and min
633 (define_code_iterator maxmin [smax smin umax umin])
634
635 ;; Base name for integer and FP insn mnemonic
636 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
637                                  (umax "maxu") (umin "minu")])
638 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
639
640 ;; Mapping of parallel logic operators
641 (define_code_iterator plogic [and ior xor])
642
643 ;; Base name for insn mnemonic.
644 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
645
646 ;; Mapping of abs neg operators
647 (define_code_iterator absneg [abs neg])
648
649 ;; Base name for x87 insn mnemonic.
650 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
651
652 ;; All single word integer modes.
653 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
654
655 ;; Single word integer modes without QImode.
656 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
657
658 ;; Instruction suffix for integer modes.
659 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
660
661 ;; Register class for integer modes.
662 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
663
664 ;; Immediate operand constraint for integer modes.
665 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
666
667 ;; General operand predicate for integer modes.
668 (define_mode_attr general_operand
669         [(QI "general_operand")
670          (HI "general_operand")
671          (SI "general_operand")
672          (DI "x86_64_general_operand")])
673
674 ;; SSE and x87 SFmode and DFmode floating point modes
675 (define_mode_iterator MODEF [SF DF])
676
677 ;; All x87 floating point modes
678 (define_mode_iterator X87MODEF [SF DF XF])
679
680 ;; All integer modes handled by x87 fisttp operator.
681 (define_mode_iterator X87MODEI [HI SI DI])
682
683 ;; All integer modes handled by integer x87 operators.
684 (define_mode_iterator X87MODEI12 [HI SI])
685
686 ;; All integer modes handled by SSE cvtts?2si* operators.
687 (define_mode_iterator SSEMODEI24 [SI DI])
688
689 ;; SSE asm suffix for floating point modes
690 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
691
692 ;; SSE vector mode corresponding to a scalar mode
693 (define_mode_attr ssevecmode
694   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
695
696 ;; Instruction suffix for REX 64bit operators.
697 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
698
699 ;; This mode iterator allows :P to be used for patterns that operate on
700 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
701 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
702
703 \f
704 ;; Scheduling descriptions
705
706 (include "pentium.md")
707 (include "ppro.md")
708 (include "k6.md")
709 (include "athlon.md")
710 (include "geode.md")
711
712 \f
713 ;; Operand and operator predicates and constraints
714
715 (include "predicates.md")
716 (include "constraints.md")
717
718 \f
719 ;; Compare instructions.
720
721 ;; All compare insns have expanders that save the operands away without
722 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
723 ;; after the cmp) will actually emit the cmpM.
724
725 (define_expand "cmpti"
726   [(set (reg:CC FLAGS_REG)
727         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
728                     (match_operand:TI 1 "x86_64_general_operand" "")))]
729   "TARGET_64BIT"
730 {
731   if (MEM_P (operands[0]) && MEM_P (operands[1]))
732     operands[0] = force_reg (TImode, operands[0]);
733   ix86_compare_op0 = operands[0];
734   ix86_compare_op1 = operands[1];
735   DONE;
736 })
737
738 (define_expand "cmpdi"
739   [(set (reg:CC FLAGS_REG)
740         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
741                     (match_operand:DI 1 "x86_64_general_operand" "")))]
742   ""
743 {
744   if (MEM_P (operands[0]) && MEM_P (operands[1]))
745     operands[0] = force_reg (DImode, operands[0]);
746   ix86_compare_op0 = operands[0];
747   ix86_compare_op1 = operands[1];
748   DONE;
749 })
750
751 (define_expand "cmpsi"
752   [(set (reg:CC FLAGS_REG)
753         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
754                     (match_operand:SI 1 "general_operand" "")))]
755   ""
756 {
757   if (MEM_P (operands[0]) && MEM_P (operands[1]))
758     operands[0] = force_reg (SImode, operands[0]);
759   ix86_compare_op0 = operands[0];
760   ix86_compare_op1 = operands[1];
761   DONE;
762 })
763
764 (define_expand "cmphi"
765   [(set (reg:CC FLAGS_REG)
766         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
767                     (match_operand:HI 1 "general_operand" "")))]
768   ""
769 {
770   if (MEM_P (operands[0]) && MEM_P (operands[1]))
771     operands[0] = force_reg (HImode, operands[0]);
772   ix86_compare_op0 = operands[0];
773   ix86_compare_op1 = operands[1];
774   DONE;
775 })
776
777 (define_expand "cmpqi"
778   [(set (reg:CC FLAGS_REG)
779         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
780                     (match_operand:QI 1 "general_operand" "")))]
781   "TARGET_QIMODE_MATH"
782 {
783   if (MEM_P (operands[0]) && MEM_P (operands[1]))
784     operands[0] = force_reg (QImode, operands[0]);
785   ix86_compare_op0 = operands[0];
786   ix86_compare_op1 = operands[1];
787   DONE;
788 })
789
790 (define_insn "cmpdi_ccno_1_rex64"
791   [(set (reg FLAGS_REG)
792         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
793                  (match_operand:DI 1 "const0_operand" "")))]
794   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
795   "@
796    test{q}\t%0, %0
797    cmp{q}\t{%1, %0|%0, %1}"
798   [(set_attr "type" "test,icmp")
799    (set_attr "length_immediate" "0,1")
800    (set_attr "mode" "DI")])
801
802 (define_insn "*cmpdi_minus_1_rex64"
803   [(set (reg FLAGS_REG)
804         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
805                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
806                  (const_int 0)))]
807   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
808   "cmp{q}\t{%1, %0|%0, %1}"
809   [(set_attr "type" "icmp")
810    (set_attr "mode" "DI")])
811
812 (define_expand "cmpdi_1_rex64"
813   [(set (reg:CC FLAGS_REG)
814         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
815                     (match_operand:DI 1 "general_operand" "")))]
816   "TARGET_64BIT"
817   "")
818
819 (define_insn "cmpdi_1_insn_rex64"
820   [(set (reg FLAGS_REG)
821         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
822                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
823   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
824   "cmp{q}\t{%1, %0|%0, %1}"
825   [(set_attr "type" "icmp")
826    (set_attr "mode" "DI")])
827
828
829 (define_insn "*cmpsi_ccno_1"
830   [(set (reg FLAGS_REG)
831         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
832                  (match_operand:SI 1 "const0_operand" "")))]
833   "ix86_match_ccmode (insn, CCNOmode)"
834   "@
835    test{l}\t%0, %0
836    cmp{l}\t{%1, %0|%0, %1}"
837   [(set_attr "type" "test,icmp")
838    (set_attr "length_immediate" "0,1")
839    (set_attr "mode" "SI")])
840
841 (define_insn "*cmpsi_minus_1"
842   [(set (reg FLAGS_REG)
843         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
844                            (match_operand:SI 1 "general_operand" "ri,mr"))
845                  (const_int 0)))]
846   "ix86_match_ccmode (insn, CCGOCmode)"
847   "cmp{l}\t{%1, %0|%0, %1}"
848   [(set_attr "type" "icmp")
849    (set_attr "mode" "SI")])
850
851 (define_expand "cmpsi_1"
852   [(set (reg:CC FLAGS_REG)
853         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
854                     (match_operand:SI 1 "general_operand" "")))]
855   ""
856   "")
857
858 (define_insn "*cmpsi_1_insn"
859   [(set (reg FLAGS_REG)
860         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
861                  (match_operand:SI 1 "general_operand" "ri,mr")))]
862   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
863     && ix86_match_ccmode (insn, CCmode)"
864   "cmp{l}\t{%1, %0|%0, %1}"
865   [(set_attr "type" "icmp")
866    (set_attr "mode" "SI")])
867
868 (define_insn "*cmphi_ccno_1"
869   [(set (reg FLAGS_REG)
870         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
871                  (match_operand:HI 1 "const0_operand" "")))]
872   "ix86_match_ccmode (insn, CCNOmode)"
873   "@
874    test{w}\t%0, %0
875    cmp{w}\t{%1, %0|%0, %1}"
876   [(set_attr "type" "test,icmp")
877    (set_attr "length_immediate" "0,1")
878    (set_attr "mode" "HI")])
879
880 (define_insn "*cmphi_minus_1"
881   [(set (reg FLAGS_REG)
882         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
883                            (match_operand:HI 1 "general_operand" "rn,mr"))
884                  (const_int 0)))]
885   "ix86_match_ccmode (insn, CCGOCmode)"
886   "cmp{w}\t{%1, %0|%0, %1}"
887   [(set_attr "type" "icmp")
888    (set_attr "mode" "HI")])
889
890 (define_insn "*cmphi_1"
891   [(set (reg FLAGS_REG)
892         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
893                  (match_operand:HI 1 "general_operand" "rn,mr")))]
894   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
895    && ix86_match_ccmode (insn, CCmode)"
896   "cmp{w}\t{%1, %0|%0, %1}"
897   [(set_attr "type" "icmp")
898    (set_attr "mode" "HI")])
899
900 (define_insn "*cmpqi_ccno_1"
901   [(set (reg FLAGS_REG)
902         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
903                  (match_operand:QI 1 "const0_operand" "")))]
904   "ix86_match_ccmode (insn, CCNOmode)"
905   "@
906    test{b}\t%0, %0
907    cmp{b}\t{$0, %0|%0, 0}"
908   [(set_attr "type" "test,icmp")
909    (set_attr "length_immediate" "0,1")
910    (set_attr "mode" "QI")])
911
912 (define_insn "*cmpqi_1"
913   [(set (reg FLAGS_REG)
914         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
915                  (match_operand:QI 1 "general_operand" "qn,mq")))]
916   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
917     && ix86_match_ccmode (insn, CCmode)"
918   "cmp{b}\t{%1, %0|%0, %1}"
919   [(set_attr "type" "icmp")
920    (set_attr "mode" "QI")])
921
922 (define_insn "*cmpqi_minus_1"
923   [(set (reg FLAGS_REG)
924         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
925                            (match_operand:QI 1 "general_operand" "qn,mq"))
926                  (const_int 0)))]
927   "ix86_match_ccmode (insn, CCGOCmode)"
928   "cmp{b}\t{%1, %0|%0, %1}"
929   [(set_attr "type" "icmp")
930    (set_attr "mode" "QI")])
931
932 (define_insn "*cmpqi_ext_1"
933   [(set (reg FLAGS_REG)
934         (compare
935           (match_operand:QI 0 "general_operand" "Qm")
936           (subreg:QI
937             (zero_extract:SI
938               (match_operand 1 "ext_register_operand" "Q")
939               (const_int 8)
940               (const_int 8)) 0)))]
941   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
942   "cmp{b}\t{%h1, %0|%0, %h1}"
943   [(set_attr "type" "icmp")
944    (set_attr "mode" "QI")])
945
946 (define_insn "*cmpqi_ext_1_rex64"
947   [(set (reg FLAGS_REG)
948         (compare
949           (match_operand:QI 0 "register_operand" "Q")
950           (subreg:QI
951             (zero_extract:SI
952               (match_operand 1 "ext_register_operand" "Q")
953               (const_int 8)
954               (const_int 8)) 0)))]
955   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
956   "cmp{b}\t{%h1, %0|%0, %h1}"
957   [(set_attr "type" "icmp")
958    (set_attr "mode" "QI")])
959
960 (define_insn "*cmpqi_ext_2"
961   [(set (reg FLAGS_REG)
962         (compare
963           (subreg:QI
964             (zero_extract:SI
965               (match_operand 0 "ext_register_operand" "Q")
966               (const_int 8)
967               (const_int 8)) 0)
968           (match_operand:QI 1 "const0_operand" "")))]
969   "ix86_match_ccmode (insn, CCNOmode)"
970   "test{b}\t%h0, %h0"
971   [(set_attr "type" "test")
972    (set_attr "length_immediate" "0")
973    (set_attr "mode" "QI")])
974
975 (define_expand "cmpqi_ext_3"
976   [(set (reg:CC FLAGS_REG)
977         (compare:CC
978           (subreg:QI
979             (zero_extract:SI
980               (match_operand 0 "ext_register_operand" "")
981               (const_int 8)
982               (const_int 8)) 0)
983           (match_operand:QI 1 "general_operand" "")))]
984   ""
985   "")
986
987 (define_insn "cmpqi_ext_3_insn"
988   [(set (reg FLAGS_REG)
989         (compare
990           (subreg:QI
991             (zero_extract:SI
992               (match_operand 0 "ext_register_operand" "Q")
993               (const_int 8)
994               (const_int 8)) 0)
995           (match_operand:QI 1 "general_operand" "Qmn")))]
996   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997   "cmp{b}\t{%1, %h0|%h0, %1}"
998   [(set_attr "type" "icmp")
999    (set_attr "mode" "QI")])
1000
1001 (define_insn "cmpqi_ext_3_insn_rex64"
1002   [(set (reg FLAGS_REG)
1003         (compare
1004           (subreg:QI
1005             (zero_extract:SI
1006               (match_operand 0 "ext_register_operand" "Q")
1007               (const_int 8)
1008               (const_int 8)) 0)
1009           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1010   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011   "cmp{b}\t{%1, %h0|%h0, %1}"
1012   [(set_attr "type" "icmp")
1013    (set_attr "mode" "QI")])
1014
1015 (define_insn "*cmpqi_ext_4"
1016   [(set (reg FLAGS_REG)
1017         (compare
1018           (subreg:QI
1019             (zero_extract:SI
1020               (match_operand 0 "ext_register_operand" "Q")
1021               (const_int 8)
1022               (const_int 8)) 0)
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 1 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)))]
1028   "ix86_match_ccmode (insn, CCmode)"
1029   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1030   [(set_attr "type" "icmp")
1031    (set_attr "mode" "QI")])
1032
1033 ;; These implement float point compares.
1034 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1035 ;; which would allow mix and match FP modes on the compares.  Which is what
1036 ;; the old patterns did, but with many more of them.
1037
1038 (define_expand "cmpxf"
1039   [(set (reg:CC FLAGS_REG)
1040         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1041                     (match_operand:XF 1 "nonmemory_operand" "")))]
1042   "TARGET_80387"
1043 {
1044   ix86_compare_op0 = operands[0];
1045   ix86_compare_op1 = operands[1];
1046   DONE;
1047 })
1048
1049 (define_expand "cmp<mode>"
1050   [(set (reg:CC FLAGS_REG)
1051         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1052                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1053   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1054 {
1055   ix86_compare_op0 = operands[0];
1056   ix86_compare_op1 = operands[1];
1057   DONE;
1058 })
1059
1060 ;; FP compares, step 1:
1061 ;; Set the FP condition codes.
1062 ;;
1063 ;; CCFPmode     compare with exceptions
1064 ;; CCFPUmode    compare with no exceptions
1065
1066 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1067 ;; used to manage the reg stack popping would not be preserved.
1068
1069 (define_insn "*cmpfp_0"
1070   [(set (match_operand:HI 0 "register_operand" "=a")
1071         (unspec:HI
1072           [(compare:CCFP
1073              (match_operand 1 "register_operand" "f")
1074              (match_operand 2 "const0_operand" ""))]
1075         UNSPEC_FNSTSW))]
1076   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1077    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078   "* return output_fp_compare (insn, operands, 0, 0);"
1079   [(set_attr "type" "multi")
1080    (set_attr "unit" "i387")
1081    (set (attr "mode")
1082      (cond [(match_operand:SF 1 "" "")
1083               (const_string "SF")
1084             (match_operand:DF 1 "" "")
1085               (const_string "DF")
1086            ]
1087            (const_string "XF")))])
1088
1089 (define_insn_and_split "*cmpfp_0_cc"
1090   [(set (reg:CCFP FLAGS_REG)
1091         (compare:CCFP
1092           (match_operand 1 "register_operand" "f")
1093           (match_operand 2 "const0_operand" "")))
1094    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1095   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096    && TARGET_SAHF && !TARGET_CMOVE
1097    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1098   "#"
1099   "&& reload_completed"
1100   [(set (match_dup 0)
1101         (unspec:HI
1102           [(compare:CCFP (match_dup 1)(match_dup 2))]
1103         UNSPEC_FNSTSW))
1104    (set (reg:CC FLAGS_REG)
1105         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1106   ""
1107   [(set_attr "type" "multi")
1108    (set_attr "unit" "i387")
1109    (set (attr "mode")
1110      (cond [(match_operand:SF 1 "" "")
1111               (const_string "SF")
1112             (match_operand:DF 1 "" "")
1113               (const_string "DF")
1114            ]
1115            (const_string "XF")))])
1116
1117 (define_insn "*cmpfp_xf"
1118   [(set (match_operand:HI 0 "register_operand" "=a")
1119         (unspec:HI
1120           [(compare:CCFP
1121              (match_operand:XF 1 "register_operand" "f")
1122              (match_operand:XF 2 "register_operand" "f"))]
1123           UNSPEC_FNSTSW))]
1124   "TARGET_80387"
1125   "* return output_fp_compare (insn, operands, 0, 0);"
1126   [(set_attr "type" "multi")
1127    (set_attr "unit" "i387")
1128    (set_attr "mode" "XF")])
1129
1130 (define_insn_and_split "*cmpfp_xf_cc"
1131   [(set (reg:CCFP FLAGS_REG)
1132         (compare:CCFP
1133           (match_operand:XF 1 "register_operand" "f")
1134           (match_operand:XF 2 "register_operand" "f")))
1135    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1136   "TARGET_80387
1137    && TARGET_SAHF && !TARGET_CMOVE"
1138   "#"
1139   "&& reload_completed"
1140   [(set (match_dup 0)
1141         (unspec:HI
1142           [(compare:CCFP (match_dup 1)(match_dup 2))]
1143         UNSPEC_FNSTSW))
1144    (set (reg:CC FLAGS_REG)
1145         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1146   ""
1147   [(set_attr "type" "multi")
1148    (set_attr "unit" "i387")
1149    (set_attr "mode" "XF")])
1150
1151 (define_insn "*cmpfp_<mode>"
1152   [(set (match_operand:HI 0 "register_operand" "=a")
1153         (unspec:HI
1154           [(compare:CCFP
1155              (match_operand:MODEF 1 "register_operand" "f")
1156              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1157           UNSPEC_FNSTSW))]
1158   "TARGET_80387"
1159   "* return output_fp_compare (insn, operands, 0, 0);"
1160   [(set_attr "type" "multi")
1161    (set_attr "unit" "i387")
1162    (set_attr "mode" "<MODE>")])
1163
1164 (define_insn_and_split "*cmpfp_<mode>_cc"
1165   [(set (reg:CCFP FLAGS_REG)
1166         (compare:CCFP
1167           (match_operand:MODEF 1 "register_operand" "f")
1168           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1169    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1170   "TARGET_80387
1171    && TARGET_SAHF && !TARGET_CMOVE"
1172   "#"
1173   "&& reload_completed"
1174   [(set (match_dup 0)
1175         (unspec:HI
1176           [(compare:CCFP (match_dup 1)(match_dup 2))]
1177         UNSPEC_FNSTSW))
1178    (set (reg:CC FLAGS_REG)
1179         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1180   ""
1181   [(set_attr "type" "multi")
1182    (set_attr "unit" "i387")
1183    (set_attr "mode" "<MODE>")])
1184
1185 (define_insn "*cmpfp_u"
1186   [(set (match_operand:HI 0 "register_operand" "=a")
1187         (unspec:HI
1188           [(compare:CCFPU
1189              (match_operand 1 "register_operand" "f")
1190              (match_operand 2 "register_operand" "f"))]
1191           UNSPEC_FNSTSW))]
1192   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1193    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1194   "* return output_fp_compare (insn, operands, 0, 1);"
1195   [(set_attr "type" "multi")
1196    (set_attr "unit" "i387")
1197    (set (attr "mode")
1198      (cond [(match_operand:SF 1 "" "")
1199               (const_string "SF")
1200             (match_operand:DF 1 "" "")
1201               (const_string "DF")
1202            ]
1203            (const_string "XF")))])
1204
1205 (define_insn_and_split "*cmpfp_u_cc"
1206   [(set (reg:CCFPU FLAGS_REG)
1207         (compare:CCFPU
1208           (match_operand 1 "register_operand" "f")
1209           (match_operand 2 "register_operand" "f")))
1210    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212    && TARGET_SAHF && !TARGET_CMOVE
1213    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1214   "#"
1215   "&& reload_completed"
1216   [(set (match_dup 0)
1217         (unspec:HI
1218           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1219         UNSPEC_FNSTSW))
1220    (set (reg:CC FLAGS_REG)
1221         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1222   ""
1223   [(set_attr "type" "multi")
1224    (set_attr "unit" "i387")
1225    (set (attr "mode")
1226      (cond [(match_operand:SF 1 "" "")
1227               (const_string "SF")
1228             (match_operand:DF 1 "" "")
1229               (const_string "DF")
1230            ]
1231            (const_string "XF")))])
1232
1233 (define_insn "*cmpfp_<mode>"
1234   [(set (match_operand:HI 0 "register_operand" "=a")
1235         (unspec:HI
1236           [(compare:CCFP
1237              (match_operand 1 "register_operand" "f")
1238              (match_operator 3 "float_operator"
1239                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1240           UNSPEC_FNSTSW))]
1241   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1242    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1243    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1244   "* return output_fp_compare (insn, operands, 0, 0);"
1245   [(set_attr "type" "multi")
1246    (set_attr "unit" "i387")
1247    (set_attr "fp_int_src" "true")
1248    (set_attr "mode" "<MODE>")])
1249
1250 (define_insn_and_split "*cmpfp_<mode>_cc"
1251   [(set (reg:CCFP FLAGS_REG)
1252         (compare:CCFP
1253           (match_operand 1 "register_operand" "f")
1254           (match_operator 3 "float_operator"
1255             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1256    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1257   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1258    && TARGET_SAHF && !TARGET_CMOVE
1259    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1260    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1261   "#"
1262   "&& reload_completed"
1263   [(set (match_dup 0)
1264         (unspec:HI
1265           [(compare:CCFP
1266              (match_dup 1)
1267              (match_op_dup 3 [(match_dup 2)]))]
1268         UNSPEC_FNSTSW))
1269    (set (reg:CC FLAGS_REG)
1270         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1271   ""
1272   [(set_attr "type" "multi")
1273    (set_attr "unit" "i387")
1274    (set_attr "fp_int_src" "true")
1275    (set_attr "mode" "<MODE>")])
1276
1277 ;; FP compares, step 2
1278 ;; Move the fpsw to ax.
1279
1280 (define_insn "x86_fnstsw_1"
1281   [(set (match_operand:HI 0 "register_operand" "=a")
1282         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1283   "TARGET_80387"
1284   "fnstsw\t%0"
1285   [(set_attr "length" "2")
1286    (set_attr "mode" "SI")
1287    (set_attr "unit" "i387")])
1288
1289 ;; FP compares, step 3
1290 ;; Get ax into flags, general case.
1291
1292 (define_insn "x86_sahf_1"
1293   [(set (reg:CC FLAGS_REG)
1294         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1295                    UNSPEC_SAHF))]
1296   "TARGET_SAHF"
1297 {
1298 #ifdef HAVE_AS_IX86_SAHF
1299   return "sahf";
1300 #else
1301   return ".byte\t0x9e";
1302 #endif
1303 }
1304   [(set_attr "length" "1")
1305    (set_attr "athlon_decode" "vector")
1306    (set_attr "amdfam10_decode" "direct")
1307    (set_attr "mode" "SI")])
1308
1309 ;; Pentium Pro can do steps 1 through 3 in one go.
1310 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1311 (define_insn "*cmpfp_i_mixed"
1312   [(set (reg:CCFP FLAGS_REG)
1313         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1314                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1315   "TARGET_MIX_SSE_I387
1316    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1317    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1318   "* return output_fp_compare (insn, operands, 1, 0);"
1319   [(set_attr "type" "fcmp,ssecomi")
1320    (set_attr "prefix" "orig,maybe_vex")
1321    (set (attr "mode")
1322      (if_then_else (match_operand:SF 1 "" "")
1323         (const_string "SF")
1324         (const_string "DF")))
1325    (set_attr "athlon_decode" "vector")
1326    (set_attr "amdfam10_decode" "direct")])
1327
1328 (define_insn "*cmpfp_i_sse"
1329   [(set (reg:CCFP FLAGS_REG)
1330         (compare:CCFP (match_operand 0 "register_operand" "x")
1331                       (match_operand 1 "nonimmediate_operand" "xm")))]
1332   "TARGET_SSE_MATH
1333    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1334    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1335   "* return output_fp_compare (insn, operands, 1, 0);"
1336   [(set_attr "type" "ssecomi")
1337    (set_attr "prefix" "maybe_vex")
1338    (set (attr "mode")
1339      (if_then_else (match_operand:SF 1 "" "")
1340         (const_string "SF")
1341         (const_string "DF")))
1342    (set_attr "athlon_decode" "vector")
1343    (set_attr "amdfam10_decode" "direct")])
1344
1345 (define_insn "*cmpfp_i_i387"
1346   [(set (reg:CCFP FLAGS_REG)
1347         (compare:CCFP (match_operand 0 "register_operand" "f")
1348                       (match_operand 1 "register_operand" "f")))]
1349   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1350    && TARGET_CMOVE
1351    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1352    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1353   "* return output_fp_compare (insn, operands, 1, 0);"
1354   [(set_attr "type" "fcmp")
1355    (set (attr "mode")
1356      (cond [(match_operand:SF 1 "" "")
1357               (const_string "SF")
1358             (match_operand:DF 1 "" "")
1359               (const_string "DF")
1360            ]
1361            (const_string "XF")))
1362    (set_attr "athlon_decode" "vector")
1363    (set_attr "amdfam10_decode" "direct")])
1364
1365 (define_insn "*cmpfp_iu_mixed"
1366   [(set (reg:CCFPU FLAGS_REG)
1367         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1368                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1369   "TARGET_MIX_SSE_I387
1370    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1371    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372   "* return output_fp_compare (insn, operands, 1, 1);"
1373   [(set_attr "type" "fcmp,ssecomi")
1374    (set_attr "prefix" "orig,maybe_vex")
1375    (set (attr "mode")
1376      (if_then_else (match_operand:SF 1 "" "")
1377         (const_string "SF")
1378         (const_string "DF")))
1379    (set_attr "athlon_decode" "vector")
1380    (set_attr "amdfam10_decode" "direct")])
1381
1382 (define_insn "*cmpfp_iu_sse"
1383   [(set (reg:CCFPU FLAGS_REG)
1384         (compare:CCFPU (match_operand 0 "register_operand" "x")
1385                        (match_operand 1 "nonimmediate_operand" "xm")))]
1386   "TARGET_SSE_MATH
1387    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389   "* return output_fp_compare (insn, operands, 1, 1);"
1390   [(set_attr "type" "ssecomi")
1391    (set_attr "prefix" "maybe_vex")
1392    (set (attr "mode")
1393      (if_then_else (match_operand:SF 1 "" "")
1394         (const_string "SF")
1395         (const_string "DF")))
1396    (set_attr "athlon_decode" "vector")
1397    (set_attr "amdfam10_decode" "direct")])
1398
1399 (define_insn "*cmpfp_iu_387"
1400   [(set (reg:CCFPU FLAGS_REG)
1401         (compare:CCFPU (match_operand 0 "register_operand" "f")
1402                        (match_operand 1 "register_operand" "f")))]
1403   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1404    && TARGET_CMOVE
1405    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1406    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1407   "* return output_fp_compare (insn, operands, 1, 1);"
1408   [(set_attr "type" "fcmp")
1409    (set (attr "mode")
1410      (cond [(match_operand:SF 1 "" "")
1411               (const_string "SF")
1412             (match_operand:DF 1 "" "")
1413               (const_string "DF")
1414            ]
1415            (const_string "XF")))
1416    (set_attr "athlon_decode" "vector")
1417    (set_attr "amdfam10_decode" "direct")])
1418 \f
1419 ;; Move instructions.
1420
1421 ;; General case of fullword move.
1422
1423 (define_expand "movsi"
1424   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1425         (match_operand:SI 1 "general_operand" ""))]
1426   ""
1427   "ix86_expand_move (SImode, operands); DONE;")
1428
1429 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1430 ;; general_operand.
1431 ;;
1432 ;; %%% We don't use a post-inc memory reference because x86 is not a
1433 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1434 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1435 ;; targets without our curiosities, and it is just as easy to represent
1436 ;; this differently.
1437
1438 (define_insn "*pushsi2"
1439   [(set (match_operand:SI 0 "push_operand" "=<")
1440         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1441   "!TARGET_64BIT"
1442   "push{l}\t%1"
1443   [(set_attr "type" "push")
1444    (set_attr "mode" "SI")])
1445
1446 ;; For 64BIT abi we always round up to 8 bytes.
1447 (define_insn "*pushsi2_rex64"
1448   [(set (match_operand:SI 0 "push_operand" "=X")
1449         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1450   "TARGET_64BIT"
1451   "push{q}\t%q1"
1452   [(set_attr "type" "push")
1453    (set_attr "mode" "SI")])
1454
1455 (define_insn "*pushsi2_prologue"
1456   [(set (match_operand:SI 0 "push_operand" "=<")
1457         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1458    (clobber (mem:BLK (scratch)))]
1459   "!TARGET_64BIT"
1460   "push{l}\t%1"
1461   [(set_attr "type" "push")
1462    (set_attr "mode" "SI")])
1463
1464 (define_insn "*popsi1_epilogue"
1465   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1466         (mem:SI (reg:SI SP_REG)))
1467    (set (reg:SI SP_REG)
1468         (plus:SI (reg:SI SP_REG) (const_int 4)))
1469    (clobber (mem:BLK (scratch)))]
1470   "!TARGET_64BIT"
1471   "pop{l}\t%0"
1472   [(set_attr "type" "pop")
1473    (set_attr "mode" "SI")])
1474
1475 (define_insn "popsi1"
1476   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1477         (mem:SI (reg:SI SP_REG)))
1478    (set (reg:SI SP_REG)
1479         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1480   "!TARGET_64BIT"
1481   "pop{l}\t%0"
1482   [(set_attr "type" "pop")
1483    (set_attr "mode" "SI")])
1484
1485 (define_insn "*movsi_xor"
1486   [(set (match_operand:SI 0 "register_operand" "=r")
1487         (match_operand:SI 1 "const0_operand" ""))
1488    (clobber (reg:CC FLAGS_REG))]
1489   "reload_completed"
1490   "xor{l}\t%0, %0"
1491   [(set_attr "type" "alu1")
1492    (set_attr "mode" "SI")
1493    (set_attr "length_immediate" "0")])
1494
1495 (define_insn "*movsi_or"
1496   [(set (match_operand:SI 0 "register_operand" "=r")
1497         (match_operand:SI 1 "immediate_operand" "i"))
1498    (clobber (reg:CC FLAGS_REG))]
1499   "reload_completed
1500    && operands[1] == constm1_rtx"
1501 {
1502   operands[1] = constm1_rtx;
1503   return "or{l}\t{%1, %0|%0, %1}";
1504 }
1505   [(set_attr "type" "alu1")
1506    (set_attr "mode" "SI")
1507    (set_attr "length_immediate" "1")])
1508
1509 (define_insn "*movsi_1"
1510   [(set (match_operand:SI 0 "nonimmediate_operand"
1511                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1512         (match_operand:SI 1 "general_operand"
1513                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1514   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1515 {
1516   switch (get_attr_type (insn))
1517     {
1518     case TYPE_SSELOG1:
1519       if (get_attr_mode (insn) == MODE_TI)
1520         return "%vpxor\t%0, %d0";
1521       return "%vxorps\t%0, %d0";
1522
1523     case TYPE_SSEMOV:
1524       switch (get_attr_mode (insn))
1525         {
1526         case MODE_TI:
1527           return "%vmovdqa\t{%1, %0|%0, %1}";
1528         case MODE_V4SF:
1529           return "%vmovaps\t{%1, %0|%0, %1}";
1530         case MODE_SI:
1531           return "%vmovd\t{%1, %0|%0, %1}";
1532         case MODE_SF:
1533           return "%vmovss\t{%1, %0|%0, %1}";
1534         default:
1535           gcc_unreachable ();
1536         }
1537
1538     case TYPE_MMX:
1539       return "pxor\t%0, %0";
1540
1541     case TYPE_MMXMOV:
1542       if (get_attr_mode (insn) == MODE_DI)
1543         return "movq\t{%1, %0|%0, %1}";
1544       return "movd\t{%1, %0|%0, %1}";
1545
1546     case TYPE_LEA:
1547       return "lea{l}\t{%1, %0|%0, %1}";
1548
1549     default:
1550       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1551       return "mov{l}\t{%1, %0|%0, %1}";
1552     }
1553 }
1554   [(set (attr "type")
1555      (cond [(eq_attr "alternative" "2")
1556               (const_string "mmx")
1557             (eq_attr "alternative" "3,4,5")
1558               (const_string "mmxmov")
1559             (eq_attr "alternative" "6")
1560               (const_string "sselog1")
1561             (eq_attr "alternative" "7,8,9,10,11")
1562               (const_string "ssemov")
1563             (match_operand:DI 1 "pic_32bit_operand" "")
1564               (const_string "lea")
1565            ]
1566            (const_string "imov")))
1567    (set (attr "prefix")
1568      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1569        (const_string "orig")
1570        (const_string "maybe_vex")))
1571    (set (attr "mode")
1572      (cond [(eq_attr "alternative" "2,3")
1573               (const_string "DI")
1574             (eq_attr "alternative" "6,7")
1575               (if_then_else
1576                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1577                 (const_string "V4SF")
1578                 (const_string "TI"))
1579             (and (eq_attr "alternative" "8,9,10,11")
1580                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1581               (const_string "SF")
1582            ]
1583            (const_string "SI")))])
1584
1585 ;; Stores and loads of ax to arbitrary constant address.
1586 ;; We fake an second form of instruction to force reload to load address
1587 ;; into register when rax is not available
1588 (define_insn "*movabssi_1_rex64"
1589   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1590         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1591   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1592   "@
1593    movabs{l}\t{%1, %P0|%P0, %1}
1594    mov{l}\t{%1, %a0|%a0, %1}"
1595   [(set_attr "type" "imov")
1596    (set_attr "modrm" "0,*")
1597    (set_attr "length_address" "8,0")
1598    (set_attr "length_immediate" "0,*")
1599    (set_attr "memory" "store")
1600    (set_attr "mode" "SI")])
1601
1602 (define_insn "*movabssi_2_rex64"
1603   [(set (match_operand:SI 0 "register_operand" "=a,r")
1604         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1605   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1606   "@
1607    movabs{l}\t{%P1, %0|%0, %P1}
1608    mov{l}\t{%a1, %0|%0, %a1}"
1609   [(set_attr "type" "imov")
1610    (set_attr "modrm" "0,*")
1611    (set_attr "length_address" "8,0")
1612    (set_attr "length_immediate" "0")
1613    (set_attr "memory" "load")
1614    (set_attr "mode" "SI")])
1615
1616 (define_insn "*swapsi"
1617   [(set (match_operand:SI 0 "register_operand" "+r")
1618         (match_operand:SI 1 "register_operand" "+r"))
1619    (set (match_dup 1)
1620         (match_dup 0))]
1621   ""
1622   "xchg{l}\t%1, %0"
1623   [(set_attr "type" "imov")
1624    (set_attr "mode" "SI")
1625    (set_attr "pent_pair" "np")
1626    (set_attr "athlon_decode" "vector")
1627    (set_attr "amdfam10_decode" "double")])
1628
1629 (define_expand "movhi"
1630   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1631         (match_operand:HI 1 "general_operand" ""))]
1632   ""
1633   "ix86_expand_move (HImode, operands); DONE;")
1634
1635 (define_insn "*pushhi2"
1636   [(set (match_operand:HI 0 "push_operand" "=X")
1637         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1638   "!TARGET_64BIT"
1639   "push{l}\t%k1"
1640   [(set_attr "type" "push")
1641    (set_attr "mode" "SI")])
1642
1643 ;; For 64BIT abi we always round up to 8 bytes.
1644 (define_insn "*pushhi2_rex64"
1645   [(set (match_operand:HI 0 "push_operand" "=X")
1646         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1647   "TARGET_64BIT"
1648   "push{q}\t%q1"
1649   [(set_attr "type" "push")
1650    (set_attr "mode" "DI")])
1651
1652 (define_insn "*movhi_1"
1653   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1654         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1655   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1656 {
1657   switch (get_attr_type (insn))
1658     {
1659     case TYPE_IMOVX:
1660       /* movzwl is faster than movw on p2 due to partial word stalls,
1661          though not as fast as an aligned movl.  */
1662       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1663     default:
1664       if (get_attr_mode (insn) == MODE_SI)
1665         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1666       else
1667         return "mov{w}\t{%1, %0|%0, %1}";
1668     }
1669 }
1670   [(set (attr "type")
1671      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1672               (const_string "imov")
1673             (and (eq_attr "alternative" "0")
1674                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1675                           (const_int 0))
1676                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1677                           (const_int 0))))
1678               (const_string "imov")
1679             (and (eq_attr "alternative" "1,2")
1680                  (match_operand:HI 1 "aligned_operand" ""))
1681               (const_string "imov")
1682             (and (ne (symbol_ref "TARGET_MOVX")
1683                      (const_int 0))
1684                  (eq_attr "alternative" "0,2"))
1685               (const_string "imovx")
1686            ]
1687            (const_string "imov")))
1688     (set (attr "mode")
1689       (cond [(eq_attr "type" "imovx")
1690                (const_string "SI")
1691              (and (eq_attr "alternative" "1,2")
1692                   (match_operand:HI 1 "aligned_operand" ""))
1693                (const_string "SI")
1694              (and (eq_attr "alternative" "0")
1695                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1696                            (const_int 0))
1697                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1698                            (const_int 0))))
1699                (const_string "SI")
1700             ]
1701             (const_string "HI")))])
1702
1703 ;; Stores and loads of ax to arbitrary constant address.
1704 ;; We fake an second form of instruction to force reload to load address
1705 ;; into register when rax is not available
1706 (define_insn "*movabshi_1_rex64"
1707   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1708         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1709   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1710   "@
1711    movabs{w}\t{%1, %P0|%P0, %1}
1712    mov{w}\t{%1, %a0|%a0, %1}"
1713   [(set_attr "type" "imov")
1714    (set_attr "modrm" "0,*")
1715    (set_attr "length_address" "8,0")
1716    (set_attr "length_immediate" "0,*")
1717    (set_attr "memory" "store")
1718    (set_attr "mode" "HI")])
1719
1720 (define_insn "*movabshi_2_rex64"
1721   [(set (match_operand:HI 0 "register_operand" "=a,r")
1722         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1723   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1724   "@
1725    movabs{w}\t{%P1, %0|%0, %P1}
1726    mov{w}\t{%a1, %0|%0, %a1}"
1727   [(set_attr "type" "imov")
1728    (set_attr "modrm" "0,*")
1729    (set_attr "length_address" "8,0")
1730    (set_attr "length_immediate" "0")
1731    (set_attr "memory" "load")
1732    (set_attr "mode" "HI")])
1733
1734 (define_insn "*swaphi_1"
1735   [(set (match_operand:HI 0 "register_operand" "+r")
1736         (match_operand:HI 1 "register_operand" "+r"))
1737    (set (match_dup 1)
1738         (match_dup 0))]
1739   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1740   "xchg{l}\t%k1, %k0"
1741   [(set_attr "type" "imov")
1742    (set_attr "mode" "SI")
1743    (set_attr "pent_pair" "np")
1744    (set_attr "athlon_decode" "vector")
1745    (set_attr "amdfam10_decode" "double")])
1746
1747 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1748 (define_insn "*swaphi_2"
1749   [(set (match_operand:HI 0 "register_operand" "+r")
1750         (match_operand:HI 1 "register_operand" "+r"))
1751    (set (match_dup 1)
1752         (match_dup 0))]
1753   "TARGET_PARTIAL_REG_STALL"
1754   "xchg{w}\t%1, %0"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "HI")
1757    (set_attr "pent_pair" "np")
1758    (set_attr "athlon_decode" "vector")])
1759
1760 (define_expand "movstricthi"
1761   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1762         (match_operand:HI 1 "general_operand" ""))]
1763   ""
1764 {
1765   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1766     FAIL;
1767   /* Don't generate memory->memory moves, go through a register */
1768   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1769     operands[1] = force_reg (HImode, operands[1]);
1770 })
1771
1772 (define_insn "*movstricthi_1"
1773   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1774         (match_operand:HI 1 "general_operand" "rn,m"))]
1775   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1776    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1777   "mov{w}\t{%1, %0|%0, %1}"
1778   [(set_attr "type" "imov")
1779    (set_attr "mode" "HI")])
1780
1781 (define_insn "*movstricthi_xor"
1782   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1783         (match_operand:HI 1 "const0_operand" ""))
1784    (clobber (reg:CC FLAGS_REG))]
1785   "reload_completed"
1786   "xor{w}\t%0, %0"
1787   [(set_attr "type" "alu1")
1788    (set_attr "mode" "HI")
1789    (set_attr "length_immediate" "0")])
1790
1791 (define_expand "movqi"
1792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1793         (match_operand:QI 1 "general_operand" ""))]
1794   ""
1795   "ix86_expand_move (QImode, operands); DONE;")
1796
1797 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1798 ;; "push a byte".  But actually we use pushl, which has the effect
1799 ;; of rounding the amount pushed up to a word.
1800
1801 (define_insn "*pushqi2"
1802   [(set (match_operand:QI 0 "push_operand" "=X")
1803         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1804   "!TARGET_64BIT"
1805   "push{l}\t%k1"
1806   [(set_attr "type" "push")
1807    (set_attr "mode" "SI")])
1808
1809 ;; For 64BIT abi we always round up to 8 bytes.
1810 (define_insn "*pushqi2_rex64"
1811   [(set (match_operand:QI 0 "push_operand" "=X")
1812         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1813   "TARGET_64BIT"
1814   "push{q}\t%q1"
1815   [(set_attr "type" "push")
1816    (set_attr "mode" "DI")])
1817
1818 ;; Situation is quite tricky about when to choose full sized (SImode) move
1819 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1820 ;; partial register dependency machines (such as AMD Athlon), where QImode
1821 ;; moves issue extra dependency and for partial register stalls machines
1822 ;; that don't use QImode patterns (and QImode move cause stall on the next
1823 ;; instruction).
1824 ;;
1825 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1826 ;; register stall machines with, where we use QImode instructions, since
1827 ;; partial register stall can be caused there.  Then we use movzx.
1828 (define_insn "*movqi_1"
1829   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1830         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1831   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832 {
1833   switch (get_attr_type (insn))
1834     {
1835     case TYPE_IMOVX:
1836       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1837       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1838     default:
1839       if (get_attr_mode (insn) == MODE_SI)
1840         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1841       else
1842         return "mov{b}\t{%1, %0|%0, %1}";
1843     }
1844 }
1845   [(set (attr "type")
1846      (cond [(and (eq_attr "alternative" "5")
1847                  (not (match_operand:QI 1 "aligned_operand" "")))
1848               (const_string "imovx")
1849             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1850               (const_string "imov")
1851             (and (eq_attr "alternative" "3")
1852                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1853                           (const_int 0))
1854                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1855                           (const_int 0))))
1856               (const_string "imov")
1857             (eq_attr "alternative" "3,5")
1858               (const_string "imovx")
1859             (and (ne (symbol_ref "TARGET_MOVX")
1860                      (const_int 0))
1861                  (eq_attr "alternative" "2"))
1862               (const_string "imovx")
1863            ]
1864            (const_string "imov")))
1865    (set (attr "mode")
1866       (cond [(eq_attr "alternative" "3,4,5")
1867                (const_string "SI")
1868              (eq_attr "alternative" "6")
1869                (const_string "QI")
1870              (eq_attr "type" "imovx")
1871                (const_string "SI")
1872              (and (eq_attr "type" "imov")
1873                   (and (eq_attr "alternative" "0,1")
1874                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1875                                 (const_int 0))
1876                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1877                                      (const_int 0))
1878                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1879                                      (const_int 0))))))
1880                (const_string "SI")
1881              ;; Avoid partial register stalls when not using QImode arithmetic
1882              (and (eq_attr "type" "imov")
1883                   (and (eq_attr "alternative" "0,1")
1884                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1885                                 (const_int 0))
1886                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1887                                 (const_int 0)))))
1888                (const_string "SI")
1889            ]
1890            (const_string "QI")))])
1891
1892 (define_insn "*swapqi_1"
1893   [(set (match_operand:QI 0 "register_operand" "+r")
1894         (match_operand:QI 1 "register_operand" "+r"))
1895    (set (match_dup 1)
1896         (match_dup 0))]
1897   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1898   "xchg{l}\t%k1, %k0"
1899   [(set_attr "type" "imov")
1900    (set_attr "mode" "SI")
1901    (set_attr "pent_pair" "np")
1902    (set_attr "athlon_decode" "vector")
1903    (set_attr "amdfam10_decode" "vector")])
1904
1905 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1906 (define_insn "*swapqi_2"
1907   [(set (match_operand:QI 0 "register_operand" "+q")
1908         (match_operand:QI 1 "register_operand" "+q"))
1909    (set (match_dup 1)
1910         (match_dup 0))]
1911   "TARGET_PARTIAL_REG_STALL"
1912   "xchg{b}\t%1, %0"
1913   [(set_attr "type" "imov")
1914    (set_attr "mode" "QI")
1915    (set_attr "pent_pair" "np")
1916    (set_attr "athlon_decode" "vector")])
1917
1918 (define_expand "movstrictqi"
1919   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1920         (match_operand:QI 1 "general_operand" ""))]
1921   ""
1922 {
1923   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1924     FAIL;
1925   /* Don't generate memory->memory moves, go through a register.  */
1926   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1927     operands[1] = force_reg (QImode, operands[1]);
1928 })
1929
1930 (define_insn "*movstrictqi_1"
1931   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1932         (match_operand:QI 1 "general_operand" "*qn,m"))]
1933   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1934    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935   "mov{b}\t{%1, %0|%0, %1}"
1936   [(set_attr "type" "imov")
1937    (set_attr "mode" "QI")])
1938
1939 (define_insn "*movstrictqi_xor"
1940   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1941         (match_operand:QI 1 "const0_operand" ""))
1942    (clobber (reg:CC FLAGS_REG))]
1943   "reload_completed"
1944   "xor{b}\t%0, %0"
1945   [(set_attr "type" "alu1")
1946    (set_attr "mode" "QI")
1947    (set_attr "length_immediate" "0")])
1948
1949 (define_insn "*movsi_extv_1"
1950   [(set (match_operand:SI 0 "register_operand" "=R")
1951         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1952                          (const_int 8)
1953                          (const_int 8)))]
1954   ""
1955   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1956   [(set_attr "type" "imovx")
1957    (set_attr "mode" "SI")])
1958
1959 (define_insn "*movhi_extv_1"
1960   [(set (match_operand:HI 0 "register_operand" "=R")
1961         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1962                          (const_int 8)
1963                          (const_int 8)))]
1964   ""
1965   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1966   [(set_attr "type" "imovx")
1967    (set_attr "mode" "SI")])
1968
1969 (define_insn "*movqi_extv_1"
1970   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1971         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1972                          (const_int 8)
1973                          (const_int 8)))]
1974   "!TARGET_64BIT"
1975 {
1976   switch (get_attr_type (insn))
1977     {
1978     case TYPE_IMOVX:
1979       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1980     default:
1981       return "mov{b}\t{%h1, %0|%0, %h1}";
1982     }
1983 }
1984   [(set (attr "type")
1985      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1986                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1987                              (ne (symbol_ref "TARGET_MOVX")
1988                                  (const_int 0))))
1989         (const_string "imovx")
1990         (const_string "imov")))
1991    (set (attr "mode")
1992      (if_then_else (eq_attr "type" "imovx")
1993         (const_string "SI")
1994         (const_string "QI")))])
1995
1996 (define_insn "*movqi_extv_1_rex64"
1997   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1998         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1999                          (const_int 8)
2000                          (const_int 8)))]
2001   "TARGET_64BIT"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_IMOVX:
2006       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2007     default:
2008       return "mov{b}\t{%h1, %0|%0, %h1}";
2009     }
2010 }
2011   [(set (attr "type")
2012      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2013                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2014                              (ne (symbol_ref "TARGET_MOVX")
2015                                  (const_int 0))))
2016         (const_string "imovx")
2017         (const_string "imov")))
2018    (set (attr "mode")
2019      (if_then_else (eq_attr "type" "imovx")
2020         (const_string "SI")
2021         (const_string "QI")))])
2022
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsqi_1_rex64"
2027   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2029   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030   "@
2031    movabs{b}\t{%1, %P0|%P0, %1}
2032    mov{b}\t{%1, %a0|%a0, %1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "modrm" "0,*")
2035    (set_attr "length_address" "8,0")
2036    (set_attr "length_immediate" "0,*")
2037    (set_attr "memory" "store")
2038    (set_attr "mode" "QI")])
2039
2040 (define_insn "*movabsqi_2_rex64"
2041   [(set (match_operand:QI 0 "register_operand" "=a,r")
2042         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044   "@
2045    movabs{b}\t{%P1, %0|%0, %P1}
2046    mov{b}\t{%a1, %0|%0, %a1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0")
2051    (set_attr "memory" "load")
2052    (set_attr "mode" "QI")])
2053
2054 (define_insn "*movdi_extzv_1"
2055   [(set (match_operand:DI 0 "register_operand" "=R")
2056         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2057                          (const_int 8)
2058                          (const_int 8)))]
2059   "TARGET_64BIT"
2060   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2061   [(set_attr "type" "imovx")
2062    (set_attr "mode" "DI")])
2063
2064 (define_insn "*movsi_extzv_1"
2065   [(set (match_operand:SI 0 "register_operand" "=R")
2066         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2067                          (const_int 8)
2068                          (const_int 8)))]
2069   ""
2070   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2071   [(set_attr "type" "imovx")
2072    (set_attr "mode" "SI")])
2073
2074 (define_insn "*movqi_extzv_2"
2075   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2076         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2077                                     (const_int 8)
2078                                     (const_int 8)) 0))]
2079   "!TARGET_64BIT"
2080 {
2081   switch (get_attr_type (insn))
2082     {
2083     case TYPE_IMOVX:
2084       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2085     default:
2086       return "mov{b}\t{%h1, %0|%0, %h1}";
2087     }
2088 }
2089   [(set (attr "type")
2090      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2091                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2092                              (ne (symbol_ref "TARGET_MOVX")
2093                                  (const_int 0))))
2094         (const_string "imovx")
2095         (const_string "imov")))
2096    (set (attr "mode")
2097      (if_then_else (eq_attr "type" "imovx")
2098         (const_string "SI")
2099         (const_string "QI")))])
2100
2101 (define_insn "*movqi_extzv_2_rex64"
2102   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2103         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2104                                     (const_int 8)
2105                                     (const_int 8)) 0))]
2106   "TARGET_64BIT"
2107 {
2108   switch (get_attr_type (insn))
2109     {
2110     case TYPE_IMOVX:
2111       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2112     default:
2113       return "mov{b}\t{%h1, %0|%0, %h1}";
2114     }
2115 }
2116   [(set (attr "type")
2117      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2118                         (ne (symbol_ref "TARGET_MOVX")
2119                             (const_int 0)))
2120         (const_string "imovx")
2121         (const_string "imov")))
2122    (set (attr "mode")
2123      (if_then_else (eq_attr "type" "imovx")
2124         (const_string "SI")
2125         (const_string "QI")))])
2126
2127 (define_insn "movsi_insv_1"
2128   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2129                          (const_int 8)
2130                          (const_int 8))
2131         (match_operand:SI 1 "general_operand" "Qmn"))]
2132   "!TARGET_64BIT"
2133   "mov{b}\t{%b1, %h0|%h0, %b1}"
2134   [(set_attr "type" "imov")
2135    (set_attr "mode" "QI")])
2136
2137 (define_insn "*movsi_insv_1_rex64"
2138   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2139                          (const_int 8)
2140                          (const_int 8))
2141         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2142   "TARGET_64BIT"
2143   "mov{b}\t{%b1, %h0|%h0, %b1}"
2144   [(set_attr "type" "imov")
2145    (set_attr "mode" "QI")])
2146
2147 (define_insn "movdi_insv_1_rex64"
2148   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2149                          (const_int 8)
2150                          (const_int 8))
2151         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2152   "TARGET_64BIT"
2153   "mov{b}\t{%b1, %h0|%h0, %b1}"
2154   [(set_attr "type" "imov")
2155    (set_attr "mode" "QI")])
2156
2157 (define_insn "*movqi_insv_2"
2158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2159                          (const_int 8)
2160                          (const_int 8))
2161         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2162                      (const_int 8)))]
2163   ""
2164   "mov{b}\t{%h1, %h0|%h0, %h1}"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "QI")])
2167
2168 (define_expand "movdi"
2169   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2170         (match_operand:DI 1 "general_operand" ""))]
2171   ""
2172   "ix86_expand_move (DImode, operands); DONE;")
2173
2174 (define_insn "*pushdi"
2175   [(set (match_operand:DI 0 "push_operand" "=<")
2176         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2177   "!TARGET_64BIT"
2178   "#")
2179
2180 (define_insn "*pushdi2_rex64"
2181   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2182         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2183   "TARGET_64BIT"
2184   "@
2185    push{q}\t%1
2186    #"
2187   [(set_attr "type" "push,multi")
2188    (set_attr "mode" "DI")])
2189
2190 ;; Convert impossible pushes of immediate to existing instructions.
2191 ;; First try to get scratch register and go through it.  In case this
2192 ;; fails, push sign extended lower part first and then overwrite
2193 ;; upper part by 32bit move.
2194 (define_peephole2
2195   [(match_scratch:DI 2 "r")
2196    (set (match_operand:DI 0 "push_operand" "")
2197         (match_operand:DI 1 "immediate_operand" ""))]
2198   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2199    && !x86_64_immediate_operand (operands[1], DImode)"
2200   [(set (match_dup 2) (match_dup 1))
2201    (set (match_dup 0) (match_dup 2))]
2202   "")
2203
2204 ;; We need to define this as both peepholer and splitter for case
2205 ;; peephole2 pass is not run.
2206 ;; "&& 1" is needed to keep it from matching the previous pattern.
2207 (define_peephole2
2208   [(set (match_operand:DI 0 "push_operand" "")
2209         (match_operand:DI 1 "immediate_operand" ""))]
2210   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2211    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2212   [(set (match_dup 0) (match_dup 1))
2213    (set (match_dup 2) (match_dup 3))]
2214   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2215    operands[1] = gen_lowpart (DImode, operands[2]);
2216    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2217                                                     GEN_INT (4)));
2218   ")
2219
2220 (define_split
2221   [(set (match_operand:DI 0 "push_operand" "")
2222         (match_operand:DI 1 "immediate_operand" ""))]
2223   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2224                     ? epilogue_completed : reload_completed)
2225    && !symbolic_operand (operands[1], DImode)
2226    && !x86_64_immediate_operand (operands[1], DImode)"
2227   [(set (match_dup 0) (match_dup 1))
2228    (set (match_dup 2) (match_dup 3))]
2229   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2230    operands[1] = gen_lowpart (DImode, operands[2]);
2231    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2232                                                     GEN_INT (4)));
2233   ")
2234
2235 (define_insn "*pushdi2_prologue_rex64"
2236   [(set (match_operand:DI 0 "push_operand" "=<")
2237         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2238    (clobber (mem:BLK (scratch)))]
2239   "TARGET_64BIT"
2240   "push{q}\t%1"
2241   [(set_attr "type" "push")
2242    (set_attr "mode" "DI")])
2243
2244 (define_insn "*popdi1_epilogue_rex64"
2245   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2246         (mem:DI (reg:DI SP_REG)))
2247    (set (reg:DI SP_REG)
2248         (plus:DI (reg:DI SP_REG) (const_int 8)))
2249    (clobber (mem:BLK (scratch)))]
2250   "TARGET_64BIT"
2251   "pop{q}\t%0"
2252   [(set_attr "type" "pop")
2253    (set_attr "mode" "DI")])
2254
2255 (define_insn "popdi1"
2256   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2257         (mem:DI (reg:DI SP_REG)))
2258    (set (reg:DI SP_REG)
2259         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2260   "TARGET_64BIT"
2261   "pop{q}\t%0"
2262   [(set_attr "type" "pop")
2263    (set_attr "mode" "DI")])
2264
2265 (define_insn "*movdi_xor_rex64"
2266   [(set (match_operand:DI 0 "register_operand" "=r")
2267         (match_operand:DI 1 "const0_operand" ""))
2268    (clobber (reg:CC FLAGS_REG))]
2269   "TARGET_64BIT
2270    && reload_completed"
2271   "xor{l}\t%k0, %k0";
2272   [(set_attr "type" "alu1")
2273    (set_attr "mode" "SI")
2274    (set_attr "length_immediate" "0")])
2275
2276 (define_insn "*movdi_or_rex64"
2277   [(set (match_operand:DI 0 "register_operand" "=r")
2278         (match_operand:DI 1 "const_int_operand" "i"))
2279    (clobber (reg:CC FLAGS_REG))]
2280   "TARGET_64BIT
2281    && reload_completed
2282    && operands[1] == constm1_rtx"
2283 {
2284   operands[1] = constm1_rtx;
2285   return "or{q}\t{%1, %0|%0, %1}";
2286 }
2287   [(set_attr "type" "alu1")
2288    (set_attr "mode" "DI")
2289    (set_attr "length_immediate" "1")])
2290
2291 (define_insn "*movdi_2"
2292   [(set (match_operand:DI 0 "nonimmediate_operand"
2293                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2294         (match_operand:DI 1 "general_operand"
2295                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2296   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2297   "@
2298    #
2299    #
2300    pxor\t%0, %0
2301    movq\t{%1, %0|%0, %1}
2302    movq\t{%1, %0|%0, %1}
2303    %vpxor\t%0, %d0
2304    %vmovq\t{%1, %0|%0, %1}
2305    %vmovdqa\t{%1, %0|%0, %1}
2306    %vmovq\t{%1, %0|%0, %1}
2307    xorps\t%0, %0
2308    movlps\t{%1, %0|%0, %1}
2309    movaps\t{%1, %0|%0, %1}
2310    movlps\t{%1, %0|%0, %1}"
2311   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2312    (set (attr "prefix")
2313      (if_then_else (eq_attr "alternative" "5,6,7,8")
2314        (const_string "vex")
2315        (const_string "orig")))
2316    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2317
2318 (define_split
2319   [(set (match_operand:DI 0 "push_operand" "")
2320         (match_operand:DI 1 "general_operand" ""))]
2321   "!TARGET_64BIT && reload_completed
2322    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2323   [(const_int 0)]
2324   "ix86_split_long_move (operands); DONE;")
2325
2326 ;; %%% This multiword shite has got to go.
2327 (define_split
2328   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2329         (match_operand:DI 1 "general_operand" ""))]
2330   "!TARGET_64BIT && reload_completed
2331    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2332    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2333   [(const_int 0)]
2334   "ix86_split_long_move (operands); DONE;")
2335
2336 (define_insn "*movdi_1_rex64"
2337   [(set (match_operand:DI 0 "nonimmediate_operand"
2338           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2339         (match_operand:DI 1 "general_operand"
2340           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2341   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2342 {
2343   switch (get_attr_type (insn))
2344     {
2345     case TYPE_SSECVT:
2346       if (SSE_REG_P (operands[0]))
2347         return "movq2dq\t{%1, %0|%0, %1}";
2348       else
2349         return "movdq2q\t{%1, %0|%0, %1}";
2350
2351     case TYPE_SSEMOV:
2352       if (TARGET_AVX)
2353         {
2354           if (get_attr_mode (insn) == MODE_TI)
2355             return "vmovdqa\t{%1, %0|%0, %1}";
2356           else
2357             return "vmovq\t{%1, %0|%0, %1}";
2358         }
2359
2360       if (get_attr_mode (insn) == MODE_TI)
2361         return "movdqa\t{%1, %0|%0, %1}";
2362       /* FALLTHRU */
2363
2364     case TYPE_MMXMOV:
2365       /* Moves from and into integer register is done using movd
2366          opcode with REX prefix.  */
2367       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2368         return "movd\t{%1, %0|%0, %1}";
2369       return "movq\t{%1, %0|%0, %1}";
2370
2371     case TYPE_SSELOG1:
2372       return "%vpxor\t%0, %d0";
2373
2374     case TYPE_MMX:
2375       return "pxor\t%0, %0";
2376
2377     case TYPE_MULTI:
2378       return "#";
2379
2380     case TYPE_LEA:
2381       return "lea{q}\t{%a1, %0|%0, %a1}";
2382
2383     default:
2384       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2385       if (get_attr_mode (insn) == MODE_SI)
2386         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2387       else if (which_alternative == 2)
2388         return "movabs{q}\t{%1, %0|%0, %1}";
2389       else
2390         return "mov{q}\t{%1, %0|%0, %1}";
2391     }
2392 }
2393   [(set (attr "type")
2394      (cond [(eq_attr "alternative" "5")
2395               (const_string "mmx")
2396             (eq_attr "alternative" "6,7,8,9,10")
2397               (const_string "mmxmov")
2398             (eq_attr "alternative" "11")
2399               (const_string "sselog1")
2400             (eq_attr "alternative" "12,13,14,15,16")
2401               (const_string "ssemov")
2402             (eq_attr "alternative" "17,18")
2403               (const_string "ssecvt")
2404             (eq_attr "alternative" "4")
2405               (const_string "multi")
2406             (match_operand:DI 1 "pic_32bit_operand" "")
2407               (const_string "lea")
2408            ]
2409            (const_string "imov")))
2410    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2412    (set (attr "prefix")
2413      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2414        (const_string "maybe_vex")
2415        (const_string "orig")))
2416    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2417
2418 ;; Stores and loads of ax to arbitrary constant address.
2419 ;; We fake an second form of instruction to force reload to load address
2420 ;; into register when rax is not available
2421 (define_insn "*movabsdi_1_rex64"
2422   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2423         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2424   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2425   "@
2426    movabs{q}\t{%1, %P0|%P0, %1}
2427    mov{q}\t{%1, %a0|%a0, %1}"
2428   [(set_attr "type" "imov")
2429    (set_attr "modrm" "0,*")
2430    (set_attr "length_address" "8,0")
2431    (set_attr "length_immediate" "0,*")
2432    (set_attr "memory" "store")
2433    (set_attr "mode" "DI")])
2434
2435 (define_insn "*movabsdi_2_rex64"
2436   [(set (match_operand:DI 0 "register_operand" "=a,r")
2437         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2438   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2439   "@
2440    movabs{q}\t{%P1, %0|%0, %P1}
2441    mov{q}\t{%a1, %0|%0, %a1}"
2442   [(set_attr "type" "imov")
2443    (set_attr "modrm" "0,*")
2444    (set_attr "length_address" "8,0")
2445    (set_attr "length_immediate" "0")
2446    (set_attr "memory" "load")
2447    (set_attr "mode" "DI")])
2448
2449 ;; Convert impossible stores of immediate to existing instructions.
2450 ;; First try to get scratch register and go through it.  In case this
2451 ;; fails, move by 32bit parts.
2452 (define_peephole2
2453   [(match_scratch:DI 2 "r")
2454    (set (match_operand:DI 0 "memory_operand" "")
2455         (match_operand:DI 1 "immediate_operand" ""))]
2456   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2457    && !x86_64_immediate_operand (operands[1], DImode)"
2458   [(set (match_dup 2) (match_dup 1))
2459    (set (match_dup 0) (match_dup 2))]
2460   "")
2461
2462 ;; We need to define this as both peepholer and splitter for case
2463 ;; peephole2 pass is not run.
2464 ;; "&& 1" is needed to keep it from matching the previous pattern.
2465 (define_peephole2
2466   [(set (match_operand:DI 0 "memory_operand" "")
2467         (match_operand:DI 1 "immediate_operand" ""))]
2468   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2469    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2470   [(set (match_dup 2) (match_dup 3))
2471    (set (match_dup 4) (match_dup 5))]
2472   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2473
2474 (define_split
2475   [(set (match_operand:DI 0 "memory_operand" "")
2476         (match_operand:DI 1 "immediate_operand" ""))]
2477   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2478                     ? epilogue_completed : reload_completed)
2479    && !symbolic_operand (operands[1], DImode)
2480    && !x86_64_immediate_operand (operands[1], DImode)"
2481   [(set (match_dup 2) (match_dup 3))
2482    (set (match_dup 4) (match_dup 5))]
2483   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2484
2485 (define_insn "*swapdi_rex64"
2486   [(set (match_operand:DI 0 "register_operand" "+r")
2487         (match_operand:DI 1 "register_operand" "+r"))
2488    (set (match_dup 1)
2489         (match_dup 0))]
2490   "TARGET_64BIT"
2491   "xchg{q}\t%1, %0"
2492   [(set_attr "type" "imov")
2493    (set_attr "mode" "DI")
2494    (set_attr "pent_pair" "np")
2495    (set_attr "athlon_decode" "vector")
2496    (set_attr "amdfam10_decode" "double")])
2497
2498 (define_expand "movoi"
2499   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2500         (match_operand:OI 1 "general_operand" ""))]
2501   "TARGET_AVX"
2502   "ix86_expand_move (OImode, operands); DONE;")
2503
2504 (define_insn "*movoi_internal"
2505   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2506         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2507   "TARGET_AVX
2508    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2509 {
2510   switch (which_alternative)
2511     {
2512     case 0:
2513       return "vxorps\t%0, %0, %0";
2514     case 1:
2515     case 2:
2516       if (misaligned_operand (operands[0], OImode)
2517           || misaligned_operand (operands[1], OImode))
2518         return "vmovdqu\t{%1, %0|%0, %1}";
2519       else
2520         return "vmovdqa\t{%1, %0|%0, %1}";
2521     default:
2522       gcc_unreachable ();
2523     }
2524 }
2525   [(set_attr "type" "sselog1,ssemov,ssemov")
2526    (set_attr "prefix" "vex")
2527    (set_attr "mode" "OI")])
2528
2529 (define_expand "movti"
2530   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2531         (match_operand:TI 1 "nonimmediate_operand" ""))]
2532   "TARGET_SSE || TARGET_64BIT"
2533 {
2534   if (TARGET_64BIT)
2535     ix86_expand_move (TImode, operands);
2536   else if (push_operand (operands[0], TImode))
2537     ix86_expand_push (TImode, operands[1]);
2538   else
2539     ix86_expand_vector_move (TImode, operands);
2540   DONE;
2541 })
2542
2543 (define_insn "*movti_internal"
2544   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2545         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2546   "TARGET_SSE && !TARGET_64BIT
2547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2548 {
2549   switch (which_alternative)
2550     {
2551     case 0:
2552       if (get_attr_mode (insn) == MODE_V4SF)
2553         return "%vxorps\t%0, %d0";
2554       else
2555         return "%vpxor\t%0, %d0";
2556     case 1:
2557     case 2:
2558       /* TDmode values are passed as TImode on the stack.  Moving them
2559          to stack may result in unaligned memory access.  */
2560       if (misaligned_operand (operands[0], TImode)
2561           || misaligned_operand (operands[1], TImode))
2562         {
2563           if (get_attr_mode (insn) == MODE_V4SF)
2564             return "%vmovups\t{%1, %0|%0, %1}";
2565          else
2566            return "%vmovdqu\t{%1, %0|%0, %1}";
2567         }
2568       else
2569         {
2570           if (get_attr_mode (insn) == MODE_V4SF)
2571             return "%vmovaps\t{%1, %0|%0, %1}";
2572          else
2573            return "%vmovdqa\t{%1, %0|%0, %1}";
2574         }
2575     default:
2576       gcc_unreachable ();
2577     }
2578 }
2579   [(set_attr "type" "sselog1,ssemov,ssemov")
2580    (set_attr "prefix" "maybe_vex")
2581    (set (attr "mode")
2582         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2583                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2584                  (const_string "V4SF")
2585                (and (eq_attr "alternative" "2")
2586                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2587                         (const_int 0)))
2588                  (const_string "V4SF")]
2589               (const_string "TI")))])
2590
2591 (define_insn "*movti_rex64"
2592   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2593         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2594   "TARGET_64BIT
2595    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2596 {
2597   switch (which_alternative)
2598     {
2599     case 0:
2600     case 1:
2601       return "#";
2602     case 2:
2603       if (get_attr_mode (insn) == MODE_V4SF)
2604         return "%vxorps\t%0, %d0";
2605       else
2606         return "%vpxor\t%0, %d0";
2607     case 3:
2608     case 4:
2609       /* TDmode values are passed as TImode on the stack.  Moving them
2610          to stack may result in unaligned memory access.  */
2611       if (misaligned_operand (operands[0], TImode)
2612           || misaligned_operand (operands[1], TImode))
2613         {
2614           if (get_attr_mode (insn) == MODE_V4SF)
2615             return "%vmovups\t{%1, %0|%0, %1}";
2616          else
2617            return "%vmovdqu\t{%1, %0|%0, %1}";
2618         }
2619       else
2620         {
2621           if (get_attr_mode (insn) == MODE_V4SF)
2622             return "%vmovaps\t{%1, %0|%0, %1}";
2623          else
2624            return "%vmovdqa\t{%1, %0|%0, %1}";
2625         }
2626     default:
2627       gcc_unreachable ();
2628     }
2629 }
2630   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2631    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "2,3")
2634                  (if_then_else
2635                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2636                        (const_int 0))
2637                    (const_string "V4SF")
2638                    (const_string "TI"))
2639                (eq_attr "alternative" "4")
2640                  (if_then_else
2641                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2642                             (const_int 0))
2643                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2644                             (const_int 0)))
2645                    (const_string "V4SF")
2646                    (const_string "TI"))]
2647                (const_string "DI")))])
2648
2649 (define_split
2650   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2651         (match_operand:TI 1 "general_operand" ""))]
2652   "reload_completed && !SSE_REG_P (operands[0])
2653    && !SSE_REG_P (operands[1])"
2654   [(const_int 0)]
2655   "ix86_split_long_move (operands); DONE;")
2656
2657 ;; This expands to what emit_move_complex would generate if we didn't
2658 ;; have a movti pattern.  Having this avoids problems with reload on
2659 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2660 ;; to have around all the time.
2661 (define_expand "movcdi"
2662   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2663         (match_operand:CDI 1 "general_operand" ""))]
2664   ""
2665 {
2666   if (push_operand (operands[0], CDImode))
2667     emit_move_complex_push (CDImode, operands[0], operands[1]);
2668   else
2669     emit_move_complex_parts (operands[0], operands[1]);
2670   DONE;
2671 })
2672
2673 (define_expand "movsf"
2674   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2675         (match_operand:SF 1 "general_operand" ""))]
2676   ""
2677   "ix86_expand_move (SFmode, operands); DONE;")
2678
2679 (define_insn "*pushsf"
2680   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2681         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2682   "!TARGET_64BIT"
2683 {
2684   /* Anything else should be already split before reg-stack.  */
2685   gcc_assert (which_alternative == 1);
2686   return "push{l}\t%1";
2687 }
2688   [(set_attr "type" "multi,push,multi")
2689    (set_attr "unit" "i387,*,*")
2690    (set_attr "mode" "SF,SI,SF")])
2691
2692 (define_insn "*pushsf_rex64"
2693   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2694         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2695   "TARGET_64BIT"
2696 {
2697   /* Anything else should be already split before reg-stack.  */
2698   gcc_assert (which_alternative == 1);
2699   return "push{q}\t%q1";
2700 }
2701   [(set_attr "type" "multi,push,multi")
2702    (set_attr "unit" "i387,*,*")
2703    (set_attr "mode" "SF,DI,SF")])
2704
2705 (define_split
2706   [(set (match_operand:SF 0 "push_operand" "")
2707         (match_operand:SF 1 "memory_operand" ""))]
2708   "reload_completed
2709    && MEM_P (operands[1])
2710    && (operands[2] = find_constant_src (insn))"
2711   [(set (match_dup 0)
2712         (match_dup 2))])
2713
2714
2715 ;; %%% Kill this when call knows how to work this out.
2716 (define_split
2717   [(set (match_operand:SF 0 "push_operand" "")
2718         (match_operand:SF 1 "any_fp_register_operand" ""))]
2719   "!TARGET_64BIT"
2720   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2721    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2722
2723 (define_split
2724   [(set (match_operand:SF 0 "push_operand" "")
2725         (match_operand:SF 1 "any_fp_register_operand" ""))]
2726   "TARGET_64BIT"
2727   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2728    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2729
2730 (define_insn "*movsf_1"
2731   [(set (match_operand:SF 0 "nonimmediate_operand"
2732           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2733         (match_operand:SF 1 "general_operand"
2734           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2735   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2736    && (reload_in_progress || reload_completed
2737        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2738        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2739            && standard_80387_constant_p (operands[1]))
2740        || GET_CODE (operands[1]) != CONST_DOUBLE
2741        || memory_operand (operands[0], SFmode))"
2742 {
2743   switch (which_alternative)
2744     {
2745     case 0:
2746     case 1:
2747       return output_387_reg_move (insn, operands);
2748
2749     case 2:
2750       return standard_80387_constant_opcode (operands[1]);
2751
2752     case 3:
2753     case 4:
2754       return "mov{l}\t{%1, %0|%0, %1}";
2755     case 5:
2756       if (get_attr_mode (insn) == MODE_TI)
2757         return "%vpxor\t%0, %d0";
2758       else
2759         return "%vxorps\t%0, %d0";
2760     case 6:
2761       if (get_attr_mode (insn) == MODE_V4SF)
2762         return "%vmovaps\t{%1, %0|%0, %1}";
2763       else
2764         return "%vmovss\t{%1, %d0|%d0, %1}";
2765     case 7:
2766       if (TARGET_AVX)
2767         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2768                                    : "vmovss\t{%1, %0|%0, %1}";
2769       else
2770         return "movss\t{%1, %0|%0, %1}";
2771     case 8:
2772       return "%vmovss\t{%1, %0|%0, %1}";
2773
2774     case 9: case 10: case 14: case 15:
2775       return "movd\t{%1, %0|%0, %1}";
2776     case 12: case 13:
2777       return "%vmovd\t{%1, %0|%0, %1}";
2778
2779     case 11:
2780       return "movq\t{%1, %0|%0, %1}";
2781
2782     default:
2783       gcc_unreachable ();
2784     }
2785 }
2786   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2787    (set (attr "prefix")
2788      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2789        (const_string "maybe_vex")
2790        (const_string "orig")))
2791    (set (attr "mode")
2792         (cond [(eq_attr "alternative" "3,4,9,10")
2793                  (const_string "SI")
2794                (eq_attr "alternative" "5")
2795                  (if_then_else
2796                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2797                                  (const_int 0))
2798                              (ne (symbol_ref "TARGET_SSE2")
2799                                  (const_int 0)))
2800                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2801                             (const_int 0)))
2802                    (const_string "TI")
2803                    (const_string "V4SF"))
2804                /* For architectures resolving dependencies on
2805                   whole SSE registers use APS move to break dependency
2806                   chains, otherwise use short move to avoid extra work.
2807
2808                   Do the same for architectures resolving dependencies on
2809                   the parts.  While in DF mode it is better to always handle
2810                   just register parts, the SF mode is different due to lack
2811                   of instructions to load just part of the register.  It is
2812                   better to maintain the whole registers in single format
2813                   to avoid problems on using packed logical operations.  */
2814                (eq_attr "alternative" "6")
2815                  (if_then_else
2816                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2817                             (const_int 0))
2818                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2819                             (const_int 0)))
2820                    (const_string "V4SF")
2821                    (const_string "SF"))
2822                (eq_attr "alternative" "11")
2823                  (const_string "DI")]
2824                (const_string "SF")))])
2825
2826 (define_insn "*swapsf"
2827   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2828         (match_operand:SF 1 "fp_register_operand" "+f"))
2829    (set (match_dup 1)
2830         (match_dup 0))]
2831   "reload_completed || TARGET_80387"
2832 {
2833   if (STACK_TOP_P (operands[0]))
2834     return "fxch\t%1";
2835   else
2836     return "fxch\t%0";
2837 }
2838   [(set_attr "type" "fxch")
2839    (set_attr "mode" "SF")])
2840
2841 (define_expand "movdf"
2842   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2843         (match_operand:DF 1 "general_operand" ""))]
2844   ""
2845   "ix86_expand_move (DFmode, operands); DONE;")
2846
2847 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2848 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2849 ;; On the average, pushdf using integers can be still shorter.  Allow this
2850 ;; pattern for optimize_size too.
2851
2852 (define_insn "*pushdf_nointeger"
2853   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2854         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2855   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2856 {
2857   /* This insn should be already split before reg-stack.  */
2858   gcc_unreachable ();
2859 }
2860   [(set_attr "type" "multi")
2861    (set_attr "unit" "i387,*,*,*")
2862    (set_attr "mode" "DF,SI,SI,DF")])
2863
2864 (define_insn "*pushdf_integer"
2865   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2866         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2867   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2868 {
2869   /* This insn should be already split before reg-stack.  */
2870   gcc_unreachable ();
2871 }
2872   [(set_attr "type" "multi")
2873    (set_attr "unit" "i387,*,*")
2874    (set_attr "mode" "DF,SI,DF")])
2875
2876 ;; %%% Kill this when call knows how to work this out.
2877 (define_split
2878   [(set (match_operand:DF 0 "push_operand" "")
2879         (match_operand:DF 1 "any_fp_register_operand" ""))]
2880   "reload_completed"
2881   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2882    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2883   "")
2884
2885 (define_split
2886   [(set (match_operand:DF 0 "push_operand" "")
2887         (match_operand:DF 1 "general_operand" ""))]
2888   "reload_completed"
2889   [(const_int 0)]
2890   "ix86_split_long_move (operands); DONE;")
2891
2892 ;; Moving is usually shorter when only FP registers are used. This separate
2893 ;; movdf pattern avoids the use of integer registers for FP operations
2894 ;; when optimizing for size.
2895
2896 (define_insn "*movdf_nointeger"
2897   [(set (match_operand:DF 0 "nonimmediate_operand"
2898                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2899         (match_operand:DF 1 "general_operand"
2900                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2901   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2902    && ((optimize_function_for_size_p (cfun)
2903        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2904    && (reload_in_progress || reload_completed
2905        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2906        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2907            && optimize_function_for_size_p (cfun)
2908            && !memory_operand (operands[0], DFmode)
2909            && standard_80387_constant_p (operands[1]))
2910        || GET_CODE (operands[1]) != CONST_DOUBLE
2911        || ((optimize_function_for_size_p (cfun)
2912             || !TARGET_MEMORY_MISMATCH_STALL
2913             || reload_in_progress || reload_completed)
2914            && memory_operand (operands[0], DFmode)))"
2915 {
2916   switch (which_alternative)
2917     {
2918     case 0:
2919     case 1:
2920       return output_387_reg_move (insn, operands);
2921
2922     case 2:
2923       return standard_80387_constant_opcode (operands[1]);
2924
2925     case 3:
2926     case 4:
2927       return "#";
2928     case 5:
2929       switch (get_attr_mode (insn))
2930         {
2931         case MODE_V4SF:
2932           return "%vxorps\t%0, %d0";
2933         case MODE_V2DF:
2934           return "%vxorpd\t%0, %d0";
2935         case MODE_TI:
2936           return "%vpxor\t%0, %d0";
2937         default:
2938           gcc_unreachable ();
2939         }
2940     case 6:
2941     case 7:
2942     case 8:
2943       switch (get_attr_mode (insn))
2944         {
2945         case MODE_V4SF:
2946           return "%vmovaps\t{%1, %0|%0, %1}";
2947         case MODE_V2DF:
2948           return "%vmovapd\t{%1, %0|%0, %1}";
2949         case MODE_TI:
2950           return "%vmovdqa\t{%1, %0|%0, %1}";
2951         case MODE_DI:
2952           return "%vmovq\t{%1, %0|%0, %1}";
2953         case MODE_DF:
2954           if (TARGET_AVX)
2955             {
2956               if (REG_P (operands[0]) && REG_P (operands[1]))
2957                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2958               else
2959                 return "vmovsd\t{%1, %0|%0, %1}";
2960             }
2961           else
2962             return "movsd\t{%1, %0|%0, %1}";
2963         case MODE_V1DF:
2964           if (TARGET_AVX)
2965             {
2966               if (REG_P (operands[0]))
2967                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2968               else
2969                 return "vmovlpd\t{%1, %0|%0, %1}";
2970             }
2971           else
2972             return "movlpd\t{%1, %0|%0, %1}";
2973         case MODE_V2SF:
2974           if (TARGET_AVX)
2975             {
2976               if (REG_P (operands[0]))
2977                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2978               else
2979                 return "vmovlps\t{%1, %0|%0, %1}";
2980             }
2981           else
2982             return "movlps\t{%1, %0|%0, %1}";
2983         default:
2984           gcc_unreachable ();
2985         }
2986
2987     default:
2988       gcc_unreachable ();
2989     }
2990 }
2991   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2992    (set (attr "prefix")
2993      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2994        (const_string "orig")
2995        (const_string "maybe_vex")))
2996    (set (attr "mode")
2997         (cond [(eq_attr "alternative" "0,1,2")
2998                  (const_string "DF")
2999                (eq_attr "alternative" "3,4")
3000                  (const_string "SI")
3001
3002                /* For SSE1, we have many fewer alternatives.  */
3003                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3004                  (cond [(eq_attr "alternative" "5,6")
3005                           (const_string "V4SF")
3006                        ]
3007                    (const_string "V2SF"))
3008
3009                /* xorps is one byte shorter.  */
3010                (eq_attr "alternative" "5")
3011                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012                             (const_int 0))
3013                           (const_string "V4SF")
3014                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3015                             (const_int 0))
3016                           (const_string "TI")
3017                        ]
3018                        (const_string "V2DF"))
3019
3020                /* For architectures resolving dependencies on
3021                   whole SSE registers use APD move to break dependency
3022                   chains, otherwise use short move to avoid extra work.
3023
3024                   movaps encodes one byte shorter.  */
3025                (eq_attr "alternative" "6")
3026                  (cond
3027                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028                         (const_int 0))
3029                       (const_string "V4SF")
3030                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3031                         (const_int 0))
3032                       (const_string "V2DF")
3033                    ]
3034                    (const_string "DF"))
3035                /* For architectures resolving dependencies on register
3036                   parts we may avoid extra work to zero out upper part
3037                   of register.  */
3038                (eq_attr "alternative" "7")
3039                  (if_then_else
3040                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3041                        (const_int 0))
3042                    (const_string "V1DF")
3043                    (const_string "DF"))
3044               ]
3045               (const_string "DF")))])
3046
3047 (define_insn "*movdf_integer_rex64"
3048   [(set (match_operand:DF 0 "nonimmediate_operand"
3049                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3050         (match_operand:DF 1 "general_operand"
3051                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3052   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3053    && (reload_in_progress || reload_completed
3054        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3055        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3056            && optimize_function_for_size_p (cfun)
3057            && standard_80387_constant_p (operands[1]))
3058        || GET_CODE (operands[1]) != CONST_DOUBLE
3059        || memory_operand (operands[0], DFmode))"
3060 {
3061   switch (which_alternative)
3062     {
3063     case 0:
3064     case 1:
3065       return output_387_reg_move (insn, operands);
3066
3067     case 2:
3068       return standard_80387_constant_opcode (operands[1]);
3069
3070     case 3:
3071     case 4:
3072       return "#";
3073
3074     case 5:
3075       switch (get_attr_mode (insn))
3076         {
3077         case MODE_V4SF:
3078           return "%vxorps\t%0, %d0";
3079         case MODE_V2DF:
3080           return "%vxorpd\t%0, %d0";
3081         case MODE_TI:
3082           return "%vpxor\t%0, %d0";
3083         default:
3084           gcc_unreachable ();
3085         }
3086     case 6:
3087     case 7:
3088     case 8:
3089       switch (get_attr_mode (insn))
3090         {
3091         case MODE_V4SF:
3092           return "%vmovaps\t{%1, %0|%0, %1}";
3093         case MODE_V2DF:
3094           return "%vmovapd\t{%1, %0|%0, %1}";
3095         case MODE_TI:
3096           return "%vmovdqa\t{%1, %0|%0, %1}";
3097         case MODE_DI:
3098           return "%vmovq\t{%1, %0|%0, %1}";
3099         case MODE_DF:
3100           if (TARGET_AVX)
3101             {
3102               if (REG_P (operands[0]) && REG_P (operands[1]))
3103                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104               else
3105                 return "vmovsd\t{%1, %0|%0, %1}";
3106             }
3107           else
3108             return "movsd\t{%1, %0|%0, %1}";
3109         case MODE_V1DF:
3110           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3111         case MODE_V2SF:
3112           return "%vmovlps\t{%1, %d0|%d0, %1}";
3113         default:
3114           gcc_unreachable ();
3115         }
3116
3117     case 9:
3118     case 10:
3119     return "%vmovd\t{%1, %0|%0, %1}";
3120
3121     default:
3122       gcc_unreachable();
3123     }
3124 }
3125   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3126    (set (attr "prefix")
3127      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3128        (const_string "orig")
3129        (const_string "maybe_vex")))
3130    (set (attr "mode")
3131         (cond [(eq_attr "alternative" "0,1,2")
3132                  (const_string "DF")
3133                (eq_attr "alternative" "3,4,9,10")
3134                  (const_string "DI")
3135
3136                /* For SSE1, we have many fewer alternatives.  */
3137                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138                  (cond [(eq_attr "alternative" "5,6")
3139                           (const_string "V4SF")
3140                        ]
3141                    (const_string "V2SF"))
3142
3143                /* xorps is one byte shorter.  */
3144                (eq_attr "alternative" "5")
3145                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146                             (const_int 0))
3147                           (const_string "V4SF")
3148                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3149                             (const_int 0))
3150                           (const_string "TI")
3151                        ]
3152                        (const_string "V2DF"))
3153
3154                /* For architectures resolving dependencies on
3155                   whole SSE registers use APD move to break dependency
3156                   chains, otherwise use short move to avoid extra work.
3157
3158                   movaps encodes one byte shorter.  */
3159                (eq_attr "alternative" "6")
3160                  (cond
3161                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162                         (const_int 0))
3163                       (const_string "V4SF")
3164                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165                         (const_int 0))
3166                       (const_string "V2DF")
3167                    ]
3168                    (const_string "DF"))
3169                /* For architectures resolving dependencies on register
3170                   parts we may avoid extra work to zero out upper part
3171                   of register.  */
3172                (eq_attr "alternative" "7")
3173                  (if_then_else
3174                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175                        (const_int 0))
3176                    (const_string "V1DF")
3177                    (const_string "DF"))
3178               ]
3179               (const_string "DF")))])
3180
3181 (define_insn "*movdf_integer"
3182   [(set (match_operand:DF 0 "nonimmediate_operand"
3183                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3184         (match_operand:DF 1 "general_operand"
3185                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3186   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3187    && optimize_function_for_speed_p (cfun)
3188    && TARGET_INTEGER_DFMODE_MOVES
3189    && (reload_in_progress || reload_completed
3190        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3191        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3192            && optimize_function_for_size_p (cfun)
3193            && standard_80387_constant_p (operands[1]))
3194        || GET_CODE (operands[1]) != CONST_DOUBLE
3195        || memory_operand (operands[0], DFmode))"
3196 {
3197   switch (which_alternative)
3198     {
3199     case 0:
3200     case 1:
3201       return output_387_reg_move (insn, operands);
3202
3203     case 2:
3204       return standard_80387_constant_opcode (operands[1]);
3205
3206     case 3:
3207     case 4:
3208       return "#";
3209
3210     case 5:
3211       switch (get_attr_mode (insn))
3212         {
3213         case MODE_V4SF:
3214           return "xorps\t%0, %0";
3215         case MODE_V2DF:
3216           return "xorpd\t%0, %0";
3217         case MODE_TI:
3218           return "pxor\t%0, %0";
3219         default:
3220           gcc_unreachable ();
3221         }
3222     case 6:
3223     case 7:
3224     case 8:
3225       switch (get_attr_mode (insn))
3226         {
3227         case MODE_V4SF:
3228           return "movaps\t{%1, %0|%0, %1}";
3229         case MODE_V2DF:
3230           return "movapd\t{%1, %0|%0, %1}";
3231         case MODE_TI:
3232           return "movdqa\t{%1, %0|%0, %1}";
3233         case MODE_DI:
3234           return "movq\t{%1, %0|%0, %1}";
3235         case MODE_DF:
3236           return "movsd\t{%1, %0|%0, %1}";
3237         case MODE_V1DF:
3238           return "movlpd\t{%1, %0|%0, %1}";
3239         case MODE_V2SF:
3240           return "movlps\t{%1, %0|%0, %1}";
3241         default:
3242           gcc_unreachable ();
3243         }
3244
3245     default:
3246       gcc_unreachable();
3247     }
3248 }
3249   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3250    (set (attr "mode")
3251         (cond [(eq_attr "alternative" "0,1,2")
3252                  (const_string "DF")
3253                (eq_attr "alternative" "3,4")
3254                  (const_string "SI")
3255
3256                /* For SSE1, we have many fewer alternatives.  */
3257                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3258                  (cond [(eq_attr "alternative" "5,6")
3259                           (const_string "V4SF")
3260                        ]
3261                    (const_string "V2SF"))
3262
3263                /* xorps is one byte shorter.  */
3264                (eq_attr "alternative" "5")
3265                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3266                             (const_int 0))
3267                           (const_string "V4SF")
3268                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3269                             (const_int 0))
3270                           (const_string "TI")
3271                        ]
3272                        (const_string "V2DF"))
3273
3274                /* For architectures resolving dependencies on
3275                   whole SSE registers use APD move to break dependency
3276                   chains, otherwise use short move to avoid extra work.
3277
3278                   movaps encodes one byte shorter.  */
3279                (eq_attr "alternative" "6")
3280                  (cond
3281                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3282                         (const_int 0))
3283                       (const_string "V4SF")
3284                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285                         (const_int 0))
3286                       (const_string "V2DF")
3287                    ]
3288                    (const_string "DF"))
3289                /* For architectures resolving dependencies on register
3290                   parts we may avoid extra work to zero out upper part
3291                   of register.  */
3292                (eq_attr "alternative" "7")
3293                  (if_then_else
3294                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3295                        (const_int 0))
3296                    (const_string "V1DF")
3297                    (const_string "DF"))
3298               ]
3299               (const_string "DF")))])
3300
3301 (define_split
3302   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3303         (match_operand:DF 1 "general_operand" ""))]
3304   "reload_completed
3305    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3306    && ! (ANY_FP_REG_P (operands[0]) ||
3307          (GET_CODE (operands[0]) == SUBREG
3308           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3309    && ! (ANY_FP_REG_P (operands[1]) ||
3310          (GET_CODE (operands[1]) == SUBREG
3311           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3312   [(const_int 0)]
3313   "ix86_split_long_move (operands); DONE;")
3314
3315 (define_insn "*swapdf"
3316   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3317         (match_operand:DF 1 "fp_register_operand" "+f"))
3318    (set (match_dup 1)
3319         (match_dup 0))]
3320   "reload_completed || TARGET_80387"
3321 {
3322   if (STACK_TOP_P (operands[0]))
3323     return "fxch\t%1";
3324   else
3325     return "fxch\t%0";
3326 }
3327   [(set_attr "type" "fxch")
3328    (set_attr "mode" "DF")])
3329
3330 (define_expand "movxf"
3331   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3332         (match_operand:XF 1 "general_operand" ""))]
3333   ""
3334   "ix86_expand_move (XFmode, operands); DONE;")
3335
3336 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3337 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3338 ;; Pushing using integer instructions is longer except for constants
3339 ;; and direct memory references.
3340 ;; (assuming that any given constant is pushed only once, but this ought to be
3341 ;;  handled elsewhere).
3342
3343 (define_insn "*pushxf_nointeger"
3344   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3345         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3346   "optimize_function_for_size_p (cfun)"
3347 {
3348   /* This insn should be already split before reg-stack.  */
3349   gcc_unreachable ();
3350 }
3351   [(set_attr "type" "multi")
3352    (set_attr "unit" "i387,*,*")
3353    (set_attr "mode" "XF,SI,SI")])
3354
3355 (define_insn "*pushxf_integer"
3356   [(set (match_operand:XF 0 "push_operand" "=<,<")
3357         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3358   "optimize_function_for_speed_p (cfun)"
3359 {
3360   /* This insn should be already split before reg-stack.  */
3361   gcc_unreachable ();
3362 }
3363   [(set_attr "type" "multi")
3364    (set_attr "unit" "i387,*")
3365    (set_attr "mode" "XF,SI")])
3366
3367 (define_split
3368   [(set (match_operand 0 "push_operand" "")
3369         (match_operand 1 "general_operand" ""))]
3370   "reload_completed
3371    && (GET_MODE (operands[0]) == XFmode
3372        || GET_MODE (operands[0]) == DFmode)
3373    && !ANY_FP_REG_P (operands[1])"
3374   [(const_int 0)]
3375   "ix86_split_long_move (operands); DONE;")
3376
3377 (define_split
3378   [(set (match_operand:XF 0 "push_operand" "")
3379         (match_operand:XF 1 "any_fp_register_operand" ""))]
3380   ""
3381   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3382    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3383   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3384
3385 ;; Do not use integer registers when optimizing for size
3386 (define_insn "*movxf_nointeger"
3387   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3388         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3389   "optimize_function_for_size_p (cfun)
3390    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3391    && (reload_in_progress || reload_completed
3392        || standard_80387_constant_p (operands[1])
3393        || GET_CODE (operands[1]) != CONST_DOUBLE
3394        || memory_operand (operands[0], XFmode))"
3395 {
3396   switch (which_alternative)
3397     {
3398     case 0:
3399     case 1:
3400       return output_387_reg_move (insn, operands);
3401
3402     case 2:
3403       return standard_80387_constant_opcode (operands[1]);
3404
3405     case 3: case 4:
3406       return "#";
3407     default:
3408       gcc_unreachable ();
3409     }
3410 }
3411   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3412    (set_attr "mode" "XF,XF,XF,SI,SI")])
3413
3414 (define_insn "*movxf_integer"
3415   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3416         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3417   "optimize_function_for_speed_p (cfun)
3418    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3419    && (reload_in_progress || reload_completed
3420        || GET_CODE (operands[1]) != CONST_DOUBLE
3421        || memory_operand (operands[0], XFmode))"
3422 {
3423   switch (which_alternative)
3424     {
3425     case 0:
3426     case 1:
3427       return output_387_reg_move (insn, operands);
3428
3429     case 2:
3430       return standard_80387_constant_opcode (operands[1]);
3431
3432     case 3: case 4:
3433       return "#";
3434
3435     default:
3436       gcc_unreachable ();
3437     }
3438 }
3439   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3440    (set_attr "mode" "XF,XF,XF,SI,SI")])
3441
3442 (define_expand "movtf"
3443   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3444         (match_operand:TF 1 "nonimmediate_operand" ""))]
3445   "TARGET_SSE2"
3446 {
3447   ix86_expand_move (TFmode, operands);
3448   DONE;
3449 })
3450
3451 (define_insn "*movtf_internal"
3452   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3453         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3454   "TARGET_SSE2
3455    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3456 {
3457   switch (which_alternative)
3458     {
3459     case 0:
3460     case 1:
3461       if (get_attr_mode (insn) == MODE_V4SF)
3462         return "%vmovaps\t{%1, %0|%0, %1}";
3463       else
3464         return "%vmovdqa\t{%1, %0|%0, %1}";
3465     case 2:
3466       if (get_attr_mode (insn) == MODE_V4SF)
3467         return "%vxorps\t%0, %d0";
3468       else
3469         return "%vpxor\t%0, %d0";
3470     case 3:
3471     case 4:
3472         return "#";
3473     default:
3474       gcc_unreachable ();
3475     }
3476 }
3477   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3478    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3479    (set (attr "mode")
3480         (cond [(eq_attr "alternative" "0,2")
3481                  (if_then_else
3482                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3483                        (const_int 0))
3484                    (const_string "V4SF")
3485                    (const_string "TI"))
3486                (eq_attr "alternative" "1")
3487                  (if_then_else
3488                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3489                             (const_int 0))
3490                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3491                             (const_int 0)))
3492                    (const_string "V4SF")
3493                    (const_string "TI"))]
3494                (const_string "DI")))])
3495
3496 (define_insn "*pushtf_sse"
3497   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3498         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3499   "TARGET_SSE2"
3500 {
3501   /* This insn should be already split before reg-stack.  */
3502   gcc_unreachable ();
3503 }
3504   [(set_attr "type" "multi")
3505    (set_attr "unit" "sse,*,*")
3506    (set_attr "mode" "TF,SI,SI")])
3507
3508 (define_split
3509   [(set (match_operand:TF 0 "push_operand" "")
3510         (match_operand:TF 1 "general_operand" ""))]
3511   "TARGET_SSE2 && reload_completed
3512    && !SSE_REG_P (operands[1])"
3513   [(const_int 0)]
3514   "ix86_split_long_move (operands); DONE;")
3515
3516 (define_split
3517   [(set (match_operand:TF 0 "push_operand" "")
3518         (match_operand:TF 1 "any_fp_register_operand" ""))]
3519   "TARGET_SSE2"
3520   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3521    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3522   "")
3523
3524 (define_split
3525   [(set (match_operand 0 "nonimmediate_operand" "")
3526         (match_operand 1 "general_operand" ""))]
3527   "reload_completed
3528    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3529    && GET_MODE (operands[0]) == XFmode
3530    && ! (ANY_FP_REG_P (operands[0]) ||
3531          (GET_CODE (operands[0]) == SUBREG
3532           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3533    && ! (ANY_FP_REG_P (operands[1]) ||
3534          (GET_CODE (operands[1]) == SUBREG
3535           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3536   [(const_int 0)]
3537   "ix86_split_long_move (operands); DONE;")
3538
3539 (define_split
3540   [(set (match_operand 0 "register_operand" "")
3541         (match_operand 1 "memory_operand" ""))]
3542   "reload_completed
3543    && MEM_P (operands[1])
3544    && (GET_MODE (operands[0]) == TFmode
3545        || GET_MODE (operands[0]) == XFmode
3546        || GET_MODE (operands[0]) == SFmode
3547        || GET_MODE (operands[0]) == DFmode)
3548    && (operands[2] = find_constant_src (insn))"
3549   [(set (match_dup 0) (match_dup 2))]
3550 {
3551   rtx c = operands[2];
3552   rtx r = operands[0];
3553
3554   if (GET_CODE (r) == SUBREG)
3555     r = SUBREG_REG (r);
3556
3557   if (SSE_REG_P (r))
3558     {
3559       if (!standard_sse_constant_p (c))
3560         FAIL;
3561     }
3562   else if (FP_REG_P (r))
3563     {
3564       if (!standard_80387_constant_p (c))
3565         FAIL;
3566     }
3567   else if (MMX_REG_P (r))
3568     FAIL;
3569 })
3570
3571 (define_split
3572   [(set (match_operand 0 "register_operand" "")
3573         (float_extend (match_operand 1 "memory_operand" "")))]
3574   "reload_completed
3575    && MEM_P (operands[1])
3576    && (GET_MODE (operands[0]) == TFmode
3577        || GET_MODE (operands[0]) == XFmode
3578        || GET_MODE (operands[0]) == SFmode
3579        || GET_MODE (operands[0]) == DFmode)
3580    && (operands[2] = find_constant_src (insn))"
3581   [(set (match_dup 0) (match_dup 2))]
3582 {
3583   rtx c = operands[2];
3584   rtx r = operands[0];
3585
3586   if (GET_CODE (r) == SUBREG)
3587     r = SUBREG_REG (r);
3588
3589   if (SSE_REG_P (r))
3590     {
3591       if (!standard_sse_constant_p (c))
3592         FAIL;
3593     }
3594   else if (FP_REG_P (r))
3595     {
3596       if (!standard_80387_constant_p (c))
3597         FAIL;
3598     }
3599   else if (MMX_REG_P (r))
3600     FAIL;
3601 })
3602
3603 (define_insn "swapxf"
3604   [(set (match_operand:XF 0 "register_operand" "+f")
3605         (match_operand:XF 1 "register_operand" "+f"))
3606    (set (match_dup 1)
3607         (match_dup 0))]
3608   "TARGET_80387"
3609 {
3610   if (STACK_TOP_P (operands[0]))
3611     return "fxch\t%1";
3612   else
3613     return "fxch\t%0";
3614 }
3615   [(set_attr "type" "fxch")
3616    (set_attr "mode" "XF")])
3617
3618 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3619 (define_split
3620   [(set (match_operand:X87MODEF 0 "register_operand" "")
3621         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3622   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3623    && (standard_80387_constant_p (operands[1]) == 8
3624        || standard_80387_constant_p (operands[1]) == 9)"
3625   [(set (match_dup 0)(match_dup 1))
3626    (set (match_dup 0)
3627         (neg:X87MODEF (match_dup 0)))]
3628 {
3629   REAL_VALUE_TYPE r;
3630
3631   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3632   if (real_isnegzero (&r))
3633     operands[1] = CONST0_RTX (<MODE>mode);
3634   else
3635     operands[1] = CONST1_RTX (<MODE>mode);
3636 })
3637
3638 (define_split
3639   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3640         (match_operand:TF 1 "general_operand" ""))]
3641   "reload_completed
3642    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3643   [(const_int 0)]
3644   "ix86_split_long_move (operands); DONE;")
3645 \f
3646 ;; Zero extension instructions
3647
3648 (define_expand "zero_extendhisi2"
3649   [(set (match_operand:SI 0 "register_operand" "")
3650      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3651   ""
3652 {
3653   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654     {
3655       operands[1] = force_reg (HImode, operands[1]);
3656       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3657       DONE;
3658     }
3659 })
3660
3661 (define_insn "zero_extendhisi2_and"
3662   [(set (match_operand:SI 0 "register_operand" "=r")
3663      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3664    (clobber (reg:CC FLAGS_REG))]
3665   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666   "#"
3667   [(set_attr "type" "alu1")
3668    (set_attr "mode" "SI")])
3669
3670 (define_split
3671   [(set (match_operand:SI 0 "register_operand" "")
3672         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3673    (clobber (reg:CC FLAGS_REG))]
3674   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3675    && optimize_function_for_speed_p (cfun)"
3676   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3677               (clobber (reg:CC FLAGS_REG))])]
3678   "")
3679
3680 (define_insn "*zero_extendhisi2_movzwl"
3681   [(set (match_operand:SI 0 "register_operand" "=r")
3682      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683   "!TARGET_ZERO_EXTEND_WITH_AND
3684    || optimize_function_for_size_p (cfun)"
3685   "movz{wl|x}\t{%1, %0|%0, %1}"
3686   [(set_attr "type" "imovx")
3687    (set_attr "mode" "SI")])
3688
3689 (define_expand "zero_extendqihi2"
3690   [(parallel
3691     [(set (match_operand:HI 0 "register_operand" "")
3692        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3693      (clobber (reg:CC FLAGS_REG))])]
3694   ""
3695   "")
3696
3697 (define_insn "*zero_extendqihi2_and"
3698   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3699      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3700    (clobber (reg:CC FLAGS_REG))]
3701   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702   "#"
3703   [(set_attr "type" "alu1")
3704    (set_attr "mode" "HI")])
3705
3706 (define_insn "*zero_extendqihi2_movzbw_and"
3707   [(set (match_operand:HI 0 "register_operand" "=r,r")
3708      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3709    (clobber (reg:CC FLAGS_REG))]
3710   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3711   "#"
3712   [(set_attr "type" "imovx,alu1")
3713    (set_attr "mode" "HI")])
3714
3715 ; zero extend to SImode here to avoid partial register stalls
3716 (define_insn "*zero_extendqihi2_movzbl"
3717   [(set (match_operand:HI 0 "register_operand" "=r")
3718      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3719   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3720    && reload_completed"
3721   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3722   [(set_attr "type" "imovx")
3723    (set_attr "mode" "SI")])
3724
3725 ;; For the movzbw case strip only the clobber
3726 (define_split
3727   [(set (match_operand:HI 0 "register_operand" "")
3728         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3729    (clobber (reg:CC FLAGS_REG))]
3730   "reload_completed
3731    && (!TARGET_ZERO_EXTEND_WITH_AND
3732        || optimize_function_for_size_p (cfun))
3733    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3734   [(set (match_operand:HI 0 "register_operand" "")
3735         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3736
3737 ;; When source and destination does not overlap, clear destination
3738 ;; first and then do the movb
3739 (define_split
3740   [(set (match_operand:HI 0 "register_operand" "")
3741         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3742    (clobber (reg:CC FLAGS_REG))]
3743   "reload_completed
3744    && ANY_QI_REG_P (operands[0])
3745    && (TARGET_ZERO_EXTEND_WITH_AND
3746        && optimize_function_for_speed_p (cfun))
3747    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3748   [(set (match_dup 0) (const_int 0))
3749    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3750   "operands[2] = gen_lowpart (QImode, operands[0]);")
3751
3752 ;; Rest is handled by single and.
3753 (define_split
3754   [(set (match_operand:HI 0 "register_operand" "")
3755         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3756    (clobber (reg:CC FLAGS_REG))]
3757   "reload_completed
3758    && true_regnum (operands[0]) == true_regnum (operands[1])"
3759   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3760               (clobber (reg:CC FLAGS_REG))])]
3761   "")
3762
3763 (define_expand "zero_extendqisi2"
3764   [(parallel
3765     [(set (match_operand:SI 0 "register_operand" "")
3766        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3767      (clobber (reg:CC FLAGS_REG))])]
3768   ""
3769   "")
3770
3771 (define_insn "*zero_extendqisi2_and"
3772   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3773      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3774    (clobber (reg:CC FLAGS_REG))]
3775   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3776   "#"
3777   [(set_attr "type" "alu1")
3778    (set_attr "mode" "SI")])
3779
3780 (define_insn "*zero_extendqisi2_movzbw_and"
3781   [(set (match_operand:SI 0 "register_operand" "=r,r")
3782      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3783    (clobber (reg:CC FLAGS_REG))]
3784   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3785   "#"
3786   [(set_attr "type" "imovx,alu1")
3787    (set_attr "mode" "SI")])
3788
3789 (define_insn "*zero_extendqisi2_movzbw"
3790   [(set (match_operand:SI 0 "register_operand" "=r")
3791      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3792   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3793    && reload_completed"
3794   "movz{bl|x}\t{%1, %0|%0, %1}"
3795   [(set_attr "type" "imovx")
3796    (set_attr "mode" "SI")])
3797
3798 ;; For the movzbl case strip only the clobber
3799 (define_split
3800   [(set (match_operand:SI 0 "register_operand" "")
3801         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3802    (clobber (reg:CC FLAGS_REG))]
3803   "reload_completed
3804    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3805    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3806   [(set (match_dup 0)
3807         (zero_extend:SI (match_dup 1)))])
3808
3809 ;; When source and destination does not overlap, clear destination
3810 ;; first and then do the movb
3811 (define_split
3812   [(set (match_operand:SI 0 "register_operand" "")
3813         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3814    (clobber (reg:CC FLAGS_REG))]
3815   "reload_completed
3816    && ANY_QI_REG_P (operands[0])
3817    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3818    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3819    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3820   [(set (match_dup 0) (const_int 0))
3821    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3822   "operands[2] = gen_lowpart (QImode, operands[0]);")
3823
3824 ;; Rest is handled by single and.
3825 (define_split
3826   [(set (match_operand:SI 0 "register_operand" "")
3827         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3828    (clobber (reg:CC FLAGS_REG))]
3829   "reload_completed
3830    && true_regnum (operands[0]) == true_regnum (operands[1])"
3831   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3832               (clobber (reg:CC FLAGS_REG))])]
3833   "")
3834
3835 ;; %%% Kill me once multi-word ops are sane.
3836 (define_expand "zero_extendsidi2"
3837   [(set (match_operand:DI 0 "register_operand" "")
3838      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3839   ""
3840 {
3841   if (!TARGET_64BIT)
3842     {
3843       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3844       DONE;
3845     }
3846 })
3847
3848 (define_insn "zero_extendsidi2_32"
3849   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3850         (zero_extend:DI
3851          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3852    (clobber (reg:CC FLAGS_REG))]
3853   "!TARGET_64BIT"
3854   "@
3855    #
3856    #
3857    #
3858    movd\t{%1, %0|%0, %1}
3859    movd\t{%1, %0|%0, %1}
3860    %vmovd\t{%1, %0|%0, %1}
3861    %vmovd\t{%1, %0|%0, %1}"
3862   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3863    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3864    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3865
3866 (define_insn "zero_extendsidi2_rex64"
3867   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3868      (zero_extend:DI
3869        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3870   "TARGET_64BIT"
3871   "@
3872    mov\t{%k1, %k0|%k0, %k1}
3873    #
3874    movd\t{%1, %0|%0, %1}
3875    movd\t{%1, %0|%0, %1}
3876    %vmovd\t{%1, %0|%0, %1}
3877    %vmovd\t{%1, %0|%0, %1}"
3878   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3879    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3880    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3881
3882 (define_split
3883   [(set (match_operand:DI 0 "memory_operand" "")
3884      (zero_extend:DI (match_dup 0)))]
3885   "TARGET_64BIT"
3886   [(set (match_dup 4) (const_int 0))]
3887   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3888
3889 (define_split
3890   [(set (match_operand:DI 0 "register_operand" "")
3891         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3892    (clobber (reg:CC FLAGS_REG))]
3893   "!TARGET_64BIT && reload_completed
3894    && true_regnum (operands[0]) == true_regnum (operands[1])"
3895   [(set (match_dup 4) (const_int 0))]
3896   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3897
3898 (define_split
3899   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3900         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3901    (clobber (reg:CC FLAGS_REG))]
3902   "!TARGET_64BIT && reload_completed
3903    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3904   [(set (match_dup 3) (match_dup 1))
3905    (set (match_dup 4) (const_int 0))]
3906   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3907
3908 (define_insn "zero_extendhidi2"
3909   [(set (match_operand:DI 0 "register_operand" "=r")
3910      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3911   "TARGET_64BIT"
3912   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3913   [(set_attr "type" "imovx")
3914    (set_attr "mode" "DI")])
3915
3916 (define_insn "zero_extendqidi2"
3917   [(set (match_operand:DI 0 "register_operand" "=r")
3918      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3919   "TARGET_64BIT"
3920   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3921   [(set_attr "type" "imovx")
3922    (set_attr "mode" "DI")])
3923 \f
3924 ;; Sign extension instructions
3925
3926 (define_expand "extendsidi2"
3927   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3928                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3929               (clobber (reg:CC FLAGS_REG))
3930               (clobber (match_scratch:SI 2 ""))])]
3931   ""
3932 {
3933   if (TARGET_64BIT)
3934     {
3935       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3936       DONE;
3937     }
3938 })
3939
3940 (define_insn "*extendsidi2_1"
3941   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3942         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3943    (clobber (reg:CC FLAGS_REG))
3944    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3945   "!TARGET_64BIT"
3946   "#")
3947
3948 (define_insn "extendsidi2_rex64"
3949   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3950         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3951   "TARGET_64BIT"
3952   "@
3953    {cltq|cdqe}
3954    movs{lq|x}\t{%1,%0|%0, %1}"
3955   [(set_attr "type" "imovx")
3956    (set_attr "mode" "DI")
3957    (set_attr "prefix_0f" "0")
3958    (set_attr "modrm" "0,1")])
3959
3960 (define_insn "extendhidi2"
3961   [(set (match_operand:DI 0 "register_operand" "=r")
3962         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3963   "TARGET_64BIT"
3964   "movs{wq|x}\t{%1,%0|%0, %1}"
3965   [(set_attr "type" "imovx")
3966    (set_attr "mode" "DI")])
3967
3968 (define_insn "extendqidi2"
3969   [(set (match_operand:DI 0 "register_operand" "=r")
3970         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3971   "TARGET_64BIT"
3972   "movs{bq|x}\t{%1,%0|%0, %1}"
3973    [(set_attr "type" "imovx")
3974     (set_attr "mode" "DI")])
3975
3976 ;; Extend to memory case when source register does die.
3977 (define_split
3978   [(set (match_operand:DI 0 "memory_operand" "")
3979         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3980    (clobber (reg:CC FLAGS_REG))
3981    (clobber (match_operand:SI 2 "register_operand" ""))]
3982   "(reload_completed
3983     && dead_or_set_p (insn, operands[1])
3984     && !reg_mentioned_p (operands[1], operands[0]))"
3985   [(set (match_dup 3) (match_dup 1))
3986    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3987               (clobber (reg:CC FLAGS_REG))])
3988    (set (match_dup 4) (match_dup 1))]
3989   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3990
3991 ;; Extend to memory case when source register does not die.
3992 (define_split
3993   [(set (match_operand:DI 0 "memory_operand" "")
3994         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3995    (clobber (reg:CC FLAGS_REG))
3996    (clobber (match_operand:SI 2 "register_operand" ""))]
3997   "reload_completed"
3998   [(const_int 0)]
3999 {
4000   split_di (&operands[0], 1, &operands[3], &operands[4]);
4001
4002   emit_move_insn (operands[3], operands[1]);
4003
4004   /* Generate a cltd if possible and doing so it profitable.  */
4005   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4006       && true_regnum (operands[1]) == AX_REG
4007       && true_regnum (operands[2]) == DX_REG)
4008     {
4009       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4010     }
4011   else
4012     {
4013       emit_move_insn (operands[2], operands[1]);
4014       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4015     }
4016   emit_move_insn (operands[4], operands[2]);
4017   DONE;
4018 })
4019
4020 ;; Extend to register case.  Optimize case where source and destination
4021 ;; registers match and cases where we can use cltd.
4022 (define_split
4023   [(set (match_operand:DI 0 "register_operand" "")
4024         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4025    (clobber (reg:CC FLAGS_REG))
4026    (clobber (match_scratch:SI 2 ""))]
4027   "reload_completed"
4028   [(const_int 0)]
4029 {
4030   split_di (&operands[0], 1, &operands[3], &operands[4]);
4031
4032   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4033     emit_move_insn (operands[3], operands[1]);
4034
4035   /* Generate a cltd if possible and doing so it profitable.  */
4036   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4037       && true_regnum (operands[3]) == AX_REG)
4038     {
4039       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4040       DONE;
4041     }
4042
4043   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4044     emit_move_insn (operands[4], operands[1]);
4045
4046   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4047   DONE;
4048 })
4049
4050 (define_insn "extendhisi2"
4051   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4052         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4053   ""
4054 {
4055   switch (get_attr_prefix_0f (insn))
4056     {
4057     case 0:
4058       return "{cwtl|cwde}";
4059     default:
4060       return "movs{wl|x}\t{%1,%0|%0, %1}";
4061     }
4062 }
4063   [(set_attr "type" "imovx")
4064    (set_attr "mode" "SI")
4065    (set (attr "prefix_0f")
4066      ;; movsx is short decodable while cwtl is vector decoded.
4067      (if_then_else (and (eq_attr "cpu" "!k6")
4068                         (eq_attr "alternative" "0"))
4069         (const_string "0")
4070         (const_string "1")))
4071    (set (attr "modrm")
4072      (if_then_else (eq_attr "prefix_0f" "0")
4073         (const_string "0")
4074         (const_string "1")))])
4075
4076 (define_insn "*extendhisi2_zext"
4077   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4078         (zero_extend:DI
4079           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4080   "TARGET_64BIT"
4081 {
4082   switch (get_attr_prefix_0f (insn))
4083     {
4084     case 0:
4085       return "{cwtl|cwde}";
4086     default:
4087       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4088     }
4089 }
4090   [(set_attr "type" "imovx")
4091    (set_attr "mode" "SI")
4092    (set (attr "prefix_0f")
4093      ;; movsx is short decodable while cwtl is vector decoded.
4094      (if_then_else (and (eq_attr "cpu" "!k6")
4095                         (eq_attr "alternative" "0"))
4096         (const_string "0")
4097         (const_string "1")))
4098    (set (attr "modrm")
4099      (if_then_else (eq_attr "prefix_0f" "0")
4100         (const_string "0")
4101         (const_string "1")))])
4102
4103 (define_insn "extendqihi2"
4104   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4105         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4106   ""
4107 {
4108   switch (get_attr_prefix_0f (insn))
4109     {
4110     case 0:
4111       return "{cbtw|cbw}";
4112     default:
4113       return "movs{bw|x}\t{%1,%0|%0, %1}";
4114     }
4115 }
4116   [(set_attr "type" "imovx")
4117    (set_attr "mode" "HI")
4118    (set (attr "prefix_0f")
4119      ;; movsx is short decodable while cwtl is vector decoded.
4120      (if_then_else (and (eq_attr "cpu" "!k6")
4121                         (eq_attr "alternative" "0"))
4122         (const_string "0")
4123         (const_string "1")))
4124    (set (attr "modrm")
4125      (if_then_else (eq_attr "prefix_0f" "0")
4126         (const_string "0")
4127         (const_string "1")))])
4128
4129 (define_insn "extendqisi2"
4130   [(set (match_operand:SI 0 "register_operand" "=r")
4131         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4132   ""
4133   "movs{bl|x}\t{%1,%0|%0, %1}"
4134    [(set_attr "type" "imovx")
4135     (set_attr "mode" "SI")])
4136
4137 (define_insn "*extendqisi2_zext"
4138   [(set (match_operand:DI 0 "register_operand" "=r")
4139         (zero_extend:DI
4140           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4141   "TARGET_64BIT"
4142   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4143    [(set_attr "type" "imovx")
4144     (set_attr "mode" "SI")])
4145 \f
4146 ;; Conversions between float and double.
4147
4148 ;; These are all no-ops in the model used for the 80387.  So just
4149 ;; emit moves.
4150
4151 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4152 (define_insn "*dummy_extendsfdf2"
4153   [(set (match_operand:DF 0 "push_operand" "=<")
4154         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4155   "0"
4156   "#")
4157
4158 (define_split
4159   [(set (match_operand:DF 0 "push_operand" "")
4160         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4161   ""
4162   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4163    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4164
4165 (define_insn "*dummy_extendsfxf2"
4166   [(set (match_operand:XF 0 "push_operand" "=<")
4167         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4168   "0"
4169   "#")
4170
4171 (define_split
4172   [(set (match_operand:XF 0 "push_operand" "")
4173         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4174   ""
4175   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4176    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4177   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4178
4179 (define_split
4180   [(set (match_operand:XF 0 "push_operand" "")
4181         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4182   ""
4183   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4184    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4185   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4186
4187 (define_expand "extendsfdf2"
4188   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4189         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4190   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4191 {
4192   /* ??? Needed for compress_float_constant since all fp constants
4193      are LEGITIMATE_CONSTANT_P.  */
4194   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4195     {
4196       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4197           && standard_80387_constant_p (operands[1]) > 0)
4198         {
4199           operands[1] = simplify_const_unary_operation
4200             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4201           emit_move_insn_1 (operands[0], operands[1]);
4202           DONE;
4203         }
4204       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4205     }
4206 })
4207
4208 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4209    cvtss2sd:
4210       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4211       cvtps2pd xmm2,xmm1
4212    We do the conversion post reload to avoid producing of 128bit spills
4213    that might lead to ICE on 32bit target.  The sequence unlikely combine
4214    anyway.  */
4215 (define_split
4216   [(set (match_operand:DF 0 "register_operand" "")
4217         (float_extend:DF
4218           (match_operand:SF 1 "nonimmediate_operand" "")))]
4219   "TARGET_USE_VECTOR_FP_CONVERTS
4220    && optimize_insn_for_speed_p ()
4221    && reload_completed && SSE_REG_P (operands[0])"
4222    [(set (match_dup 2)
4223          (float_extend:V2DF
4224            (vec_select:V2SF
4225              (match_dup 3)
4226              (parallel [(const_int 0) (const_int 1)]))))]
4227 {
4228   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4229   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4230   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4231      Try to avoid move when unpacking can be done in source.  */
4232   if (REG_P (operands[1]))
4233     {
4234       /* If it is unsafe to overwrite upper half of source, we need
4235          to move to destination and unpack there.  */
4236       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4237            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4238           && true_regnum (operands[0]) != true_regnum (operands[1]))
4239         {
4240           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4241           emit_move_insn (tmp, operands[1]);
4242         }
4243       else
4244         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4245       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4246     }
4247   else
4248     emit_insn (gen_vec_setv4sf_0 (operands[3],
4249                                   CONST0_RTX (V4SFmode), operands[1]));
4250 })
4251
4252 (define_insn "*extendsfdf2_mixed"
4253   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4254         (float_extend:DF
4255           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4256   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4257 {
4258   switch (which_alternative)
4259     {
4260     case 0:
4261     case 1:
4262       return output_387_reg_move (insn, operands);
4263
4264     case 2:
4265       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4266
4267     default:
4268       gcc_unreachable ();
4269     }
4270 }
4271   [(set_attr "type" "fmov,fmov,ssecvt")
4272    (set_attr "prefix" "orig,orig,maybe_vex")
4273    (set_attr "mode" "SF,XF,DF")])
4274
4275 (define_insn "*extendsfdf2_sse"
4276   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4277         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4278   "TARGET_SSE2 && TARGET_SSE_MATH"
4279   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4280   [(set_attr "type" "ssecvt")
4281    (set_attr "prefix" "maybe_vex")
4282    (set_attr "mode" "DF")])
4283
4284 (define_insn "*extendsfdf2_i387"
4285   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4286         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4287   "TARGET_80387"
4288   "* return output_387_reg_move (insn, operands);"
4289   [(set_attr "type" "fmov")
4290    (set_attr "mode" "SF,XF")])
4291
4292 (define_expand "extend<mode>xf2"
4293   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4294         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4295   "TARGET_80387"
4296 {
4297   /* ??? Needed for compress_float_constant since all fp constants
4298      are LEGITIMATE_CONSTANT_P.  */
4299   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4300     {
4301       if (standard_80387_constant_p (operands[1]) > 0)
4302         {
4303           operands[1] = simplify_const_unary_operation
4304             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4305           emit_move_insn_1 (operands[0], operands[1]);
4306           DONE;
4307         }
4308       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4309     }
4310 })
4311
4312 (define_insn "*extend<mode>xf2_i387"
4313   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4314         (float_extend:XF
4315           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4316   "TARGET_80387"
4317   "* return output_387_reg_move (insn, operands);"
4318   [(set_attr "type" "fmov")
4319    (set_attr "mode" "<MODE>,XF")])
4320
4321 ;; %%% This seems bad bad news.
4322 ;; This cannot output into an f-reg because there is no way to be sure
4323 ;; of truncating in that case.  Otherwise this is just like a simple move
4324 ;; insn.  So we pretend we can output to a reg in order to get better
4325 ;; register preferencing, but we really use a stack slot.
4326
4327 ;; Conversion from DFmode to SFmode.
4328
4329 (define_expand "truncdfsf2"
4330   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4331         (float_truncate:SF
4332           (match_operand:DF 1 "nonimmediate_operand" "")))]
4333   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4334 {
4335   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4336     ;
4337   else if (flag_unsafe_math_optimizations)
4338     ;
4339   else
4340     {
4341       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4342       rtx temp = assign_386_stack_local (SFmode, slot);
4343       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4344       DONE;
4345     }
4346 })
4347
4348 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4349    cvtsd2ss:
4350       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4351       cvtpd2ps xmm2,xmm1
4352    We do the conversion post reload to avoid producing of 128bit spills
4353    that might lead to ICE on 32bit target.  The sequence unlikely combine
4354    anyway.  */
4355 (define_split
4356   [(set (match_operand:SF 0 "register_operand" "")
4357         (float_truncate:SF
4358           (match_operand:DF 1 "nonimmediate_operand" "")))]
4359   "TARGET_USE_VECTOR_FP_CONVERTS
4360    && optimize_insn_for_speed_p ()
4361    && reload_completed && SSE_REG_P (operands[0])"
4362    [(set (match_dup 2)
4363          (vec_concat:V4SF
4364            (float_truncate:V2SF
4365              (match_dup 4))
4366            (match_dup 3)))]
4367 {
4368   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4369   operands[3] = CONST0_RTX (V2SFmode);
4370   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4371   /* Use movsd for loading from memory, unpcklpd for registers.
4372      Try to avoid move when unpacking can be done in source, or SSE3
4373      movddup is available.  */
4374   if (REG_P (operands[1]))
4375     {
4376       if (!TARGET_SSE3
4377           && true_regnum (operands[0]) != true_regnum (operands[1])
4378           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4379               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4380         {
4381           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4382           emit_move_insn (tmp, operands[1]);
4383           operands[1] = tmp;
4384         }
4385       else if (!TARGET_SSE3)
4386         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4387       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4388     }
4389   else
4390     emit_insn (gen_sse2_loadlpd (operands[4],
4391                                  CONST0_RTX (V2DFmode), operands[1]));
4392 })
4393
4394 (define_expand "truncdfsf2_with_temp"
4395   [(parallel [(set (match_operand:SF 0 "" "")
4396                    (float_truncate:SF (match_operand:DF 1 "" "")))
4397               (clobber (match_operand:SF 2 "" ""))])]
4398   "")
4399
4400 (define_insn "*truncdfsf_fast_mixed"
4401   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4402         (float_truncate:SF
4403           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4404   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4405 {
4406   switch (which_alternative)
4407     {
4408     case 0:
4409       return output_387_reg_move (insn, operands);
4410     case 1:
4411       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4412     default:
4413       gcc_unreachable ();
4414     }
4415 }
4416   [(set_attr "type" "fmov,ssecvt")
4417    (set_attr "prefix" "orig,maybe_vex")
4418    (set_attr "mode" "SF")])
4419
4420 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4421 ;; because nothing we do here is unsafe.
4422 (define_insn "*truncdfsf_fast_sse"
4423   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4424         (float_truncate:SF
4425           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4426   "TARGET_SSE2 && TARGET_SSE_MATH"
4427   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4428   [(set_attr "type" "ssecvt")
4429    (set_attr "prefix" "maybe_vex")
4430    (set_attr "mode" "SF")])
4431
4432 (define_insn "*truncdfsf_fast_i387"
4433   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4434         (float_truncate:SF
4435           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4436   "TARGET_80387 && flag_unsafe_math_optimizations"
4437   "* return output_387_reg_move (insn, operands);"
4438   [(set_attr "type" "fmov")
4439    (set_attr "mode" "SF")])
4440
4441 (define_insn "*truncdfsf_mixed"
4442   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4443         (float_truncate:SF
4444           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4445    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4446   "TARGET_MIX_SSE_I387"
4447 {
4448   switch (which_alternative)
4449     {
4450     case 0:
4451       return output_387_reg_move (insn, operands);
4452
4453     case 1:
4454       return "#";
4455     case 2:
4456       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4457     default:
4458       gcc_unreachable ();
4459     }
4460 }
4461   [(set_attr "type" "fmov,multi,ssecvt")
4462    (set_attr "unit" "*,i387,*")
4463    (set_attr "prefix" "orig,orig,maybe_vex")
4464    (set_attr "mode" "SF")])
4465
4466 (define_insn "*truncdfsf_i387"
4467   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4468         (float_truncate:SF
4469           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4470    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4471   "TARGET_80387"
4472 {
4473   switch (which_alternative)
4474     {
4475     case 0:
4476       return output_387_reg_move (insn, operands);
4477
4478     case 1:
4479       return "#";
4480     default:
4481       gcc_unreachable ();
4482     }
4483 }
4484   [(set_attr "type" "fmov,multi")
4485    (set_attr "unit" "*,i387")
4486    (set_attr "mode" "SF")])
4487
4488 (define_insn "*truncdfsf2_i387_1"
4489   [(set (match_operand:SF 0 "memory_operand" "=m")
4490         (float_truncate:SF
4491           (match_operand:DF 1 "register_operand" "f")))]
4492   "TARGET_80387
4493    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4494    && !TARGET_MIX_SSE_I387"
4495   "* return output_387_reg_move (insn, operands);"
4496   [(set_attr "type" "fmov")
4497    (set_attr "mode" "SF")])
4498
4499 (define_split
4500   [(set (match_operand:SF 0 "register_operand" "")
4501         (float_truncate:SF
4502          (match_operand:DF 1 "fp_register_operand" "")))
4503    (clobber (match_operand 2 "" ""))]
4504   "reload_completed"
4505   [(set (match_dup 2) (match_dup 1))
4506    (set (match_dup 0) (match_dup 2))]
4507 {
4508   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4509 })
4510
4511 ;; Conversion from XFmode to {SF,DF}mode
4512
4513 (define_expand "truncxf<mode>2"
4514   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4515                    (float_truncate:MODEF
4516                      (match_operand:XF 1 "register_operand" "")))
4517               (clobber (match_dup 2))])]
4518   "TARGET_80387"
4519 {
4520   if (flag_unsafe_math_optimizations)
4521     {
4522       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4523       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4524       if (reg != operands[0])
4525         emit_move_insn (operands[0], reg);
4526       DONE;
4527     }
4528   else
4529     {
4530       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4531       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4532     }
4533 })
4534
4535 (define_insn "*truncxfsf2_mixed"
4536   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4537         (float_truncate:SF
4538           (match_operand:XF 1 "register_operand" "f,f")))
4539    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4540   "TARGET_80387"
4541 {
4542   gcc_assert (!which_alternative);
4543   return output_387_reg_move (insn, operands);
4544 }
4545   [(set_attr "type" "fmov,multi")
4546    (set_attr "unit" "*,i387")
4547    (set_attr "mode" "SF")])
4548
4549 (define_insn "*truncxfdf2_mixed"
4550   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4551         (float_truncate:DF
4552           (match_operand:XF 1 "register_operand" "f,f")))
4553    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4554   "TARGET_80387"
4555 {
4556   gcc_assert (!which_alternative);
4557   return output_387_reg_move (insn, operands);
4558 }
4559   [(set_attr "type" "fmov,multi")
4560    (set_attr "unit" "*,i387")
4561    (set_attr "mode" "DF")])
4562
4563 (define_insn "truncxf<mode>2_i387_noop"
4564   [(set (match_operand:MODEF 0 "register_operand" "=f")
4565         (float_truncate:MODEF
4566           (match_operand:XF 1 "register_operand" "f")))]
4567   "TARGET_80387 && flag_unsafe_math_optimizations"
4568   "* return output_387_reg_move (insn, operands);"
4569   [(set_attr "type" "fmov")
4570    (set_attr "mode" "<MODE>")])
4571
4572 (define_insn "*truncxf<mode>2_i387"
4573   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4574         (float_truncate:MODEF
4575           (match_operand:XF 1 "register_operand" "f")))]
4576   "TARGET_80387"
4577   "* return output_387_reg_move (insn, operands);"
4578   [(set_attr "type" "fmov")
4579    (set_attr "mode" "<MODE>")])
4580
4581 (define_split
4582   [(set (match_operand:MODEF 0 "register_operand" "")
4583         (float_truncate:MODEF
4584           (match_operand:XF 1 "register_operand" "")))
4585    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4586   "TARGET_80387 && reload_completed"
4587   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4588    (set (match_dup 0) (match_dup 2))]
4589   "")
4590
4591 (define_split
4592   [(set (match_operand:MODEF 0 "memory_operand" "")
4593         (float_truncate:MODEF
4594           (match_operand:XF 1 "register_operand" "")))
4595    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4596   "TARGET_80387"
4597   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4598   "")
4599 \f
4600 ;; Signed conversion to DImode.
4601
4602 (define_expand "fix_truncxfdi2"
4603   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4604                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4605               (clobber (reg:CC FLAGS_REG))])]
4606   "TARGET_80387"
4607 {
4608   if (TARGET_FISTTP)
4609    {
4610      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4611      DONE;
4612    }
4613 })
4614
4615 (define_expand "fix_trunc<mode>di2"
4616   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4617                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4618               (clobber (reg:CC FLAGS_REG))])]
4619   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4620 {
4621   if (TARGET_FISTTP
4622       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4623    {
4624      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4625      DONE;
4626    }
4627   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4628    {
4629      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4630      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4631      if (out != operands[0])
4632         emit_move_insn (operands[0], out);
4633      DONE;
4634    }
4635 })
4636
4637 ;; Signed conversion to SImode.
4638
4639 (define_expand "fix_truncxfsi2"
4640   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4641                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4642               (clobber (reg:CC FLAGS_REG))])]
4643   "TARGET_80387"
4644 {
4645   if (TARGET_FISTTP)
4646    {
4647      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4648      DONE;
4649    }
4650 })
4651
4652 (define_expand "fix_trunc<mode>si2"
4653   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4654                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4655               (clobber (reg:CC FLAGS_REG))])]
4656   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4657 {
4658   if (TARGET_FISTTP
4659       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4660    {
4661      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4662      DONE;
4663    }
4664   if (SSE_FLOAT_MODE_P (<MODE>mode))
4665    {
4666      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4667      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4668      if (out != operands[0])
4669         emit_move_insn (operands[0], out);
4670      DONE;
4671    }
4672 })
4673
4674 ;; Signed conversion to HImode.
4675
4676 (define_expand "fix_trunc<mode>hi2"
4677   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4678                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4679               (clobber (reg:CC FLAGS_REG))])]
4680   "TARGET_80387
4681    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4682 {
4683   if (TARGET_FISTTP)
4684    {
4685      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4686      DONE;
4687    }
4688 })
4689
4690 ;; Unsigned conversion to SImode.
4691
4692 (define_expand "fixuns_trunc<mode>si2"
4693   [(parallel
4694     [(set (match_operand:SI 0 "register_operand" "")
4695           (unsigned_fix:SI
4696             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4697      (use (match_dup 2))
4698      (clobber (match_scratch:<ssevecmode> 3 ""))
4699      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4700   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701 {
4702   enum machine_mode mode = <MODE>mode;
4703   enum machine_mode vecmode = <ssevecmode>mode;
4704   REAL_VALUE_TYPE TWO31r;
4705   rtx two31;
4706
4707   if (optimize_insn_for_size_p ())
4708     FAIL;
4709
4710   real_ldexp (&TWO31r, &dconst1, 31);
4711   two31 = const_double_from_real_value (TWO31r, mode);
4712   two31 = ix86_build_const_vector (mode, true, two31);
4713   operands[2] = force_reg (vecmode, two31);
4714 })
4715
4716 (define_insn_and_split "*fixuns_trunc<mode>_1"
4717   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4718         (unsigned_fix:SI
4719           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4720    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4721    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4722    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4723   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4724    && optimize_function_for_speed_p (cfun)"
4725   "#"
4726   "&& reload_completed"
4727   [(const_int 0)]
4728 {
4729   ix86_split_convert_uns_si_sse (operands);
4730   DONE;
4731 })
4732
4733 ;; Unsigned conversion to HImode.
4734 ;; Without these patterns, we'll try the unsigned SI conversion which
4735 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4736
4737 (define_expand "fixuns_trunc<mode>hi2"
4738   [(set (match_dup 2)
4739         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4740    (set (match_operand:HI 0 "nonimmediate_operand" "")
4741         (subreg:HI (match_dup 2) 0))]
4742   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4743   "operands[2] = gen_reg_rtx (SImode);")
4744
4745 ;; When SSE is available, it is always faster to use it!
4746 (define_insn "fix_trunc<mode>di_sse"
4747   [(set (match_operand:DI 0 "register_operand" "=r,r")
4748         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4749   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4750    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4751   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4752   [(set_attr "type" "sseicvt")
4753    (set_attr "prefix" "maybe_vex")
4754    (set_attr "mode" "<MODE>")
4755    (set_attr "athlon_decode" "double,vector")
4756    (set_attr "amdfam10_decode" "double,double")])
4757
4758 (define_insn "fix_trunc<mode>si_sse"
4759   [(set (match_operand:SI 0 "register_operand" "=r,r")
4760         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4761   "SSE_FLOAT_MODE_P (<MODE>mode)
4762    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4763   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4764   [(set_attr "type" "sseicvt")
4765    (set_attr "prefix" "maybe_vex")
4766    (set_attr "mode" "<MODE>")
4767    (set_attr "athlon_decode" "double,vector")
4768    (set_attr "amdfam10_decode" "double,double")])
4769
4770 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4771 (define_peephole2
4772   [(set (match_operand:MODEF 0 "register_operand" "")
4773         (match_operand:MODEF 1 "memory_operand" ""))
4774    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4775         (fix:SSEMODEI24 (match_dup 0)))]
4776   "TARGET_SHORTEN_X87_SSE
4777    && peep2_reg_dead_p (2, operands[0])"
4778   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4779   "")
4780
4781 ;; Avoid vector decoded forms of the instruction.
4782 (define_peephole2
4783   [(match_scratch:DF 2 "Y2")
4784    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4785         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4786   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4787   [(set (match_dup 2) (match_dup 1))
4788    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4789   "")
4790
4791 (define_peephole2
4792   [(match_scratch:SF 2 "x")
4793    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4794         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4795   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4796   [(set (match_dup 2) (match_dup 1))
4797    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4798   "")
4799
4800 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4801   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4802         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4803   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4804    && TARGET_FISTTP
4805    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4806          && (TARGET_64BIT || <MODE>mode != DImode))
4807         && TARGET_SSE_MATH)
4808    && !(reload_completed || reload_in_progress)"
4809   "#"
4810   "&& 1"
4811   [(const_int 0)]
4812 {
4813   if (memory_operand (operands[0], VOIDmode))
4814     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4815   else
4816     {
4817       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4818       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4819                                                             operands[1],
4820                                                             operands[2]));
4821     }
4822   DONE;
4823 }
4824   [(set_attr "type" "fisttp")
4825    (set_attr "mode" "<MODE>")])
4826
4827 (define_insn "fix_trunc<mode>_i387_fisttp"
4828   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4829         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4830    (clobber (match_scratch:XF 2 "=&1f"))]
4831   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4832    && TARGET_FISTTP
4833    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4834          && (TARGET_64BIT || <MODE>mode != DImode))
4835         && TARGET_SSE_MATH)"
4836   "* return output_fix_trunc (insn, operands, 1);"
4837   [(set_attr "type" "fisttp")
4838    (set_attr "mode" "<MODE>")])
4839
4840 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4841   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4842         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4843    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4844    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4845   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4846    && TARGET_FISTTP
4847    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4848         && (TARGET_64BIT || <MODE>mode != DImode))
4849         && TARGET_SSE_MATH)"
4850   "#"
4851   [(set_attr "type" "fisttp")
4852    (set_attr "mode" "<MODE>")])
4853
4854 (define_split
4855   [(set (match_operand:X87MODEI 0 "register_operand" "")
4856         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4857    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4858    (clobber (match_scratch 3 ""))]
4859   "reload_completed"
4860   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4861               (clobber (match_dup 3))])
4862    (set (match_dup 0) (match_dup 2))]
4863   "")
4864
4865 (define_split
4866   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4867         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4868    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4869    (clobber (match_scratch 3 ""))]
4870   "reload_completed"
4871   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4872               (clobber (match_dup 3))])]
4873   "")
4874
4875 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4876 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4877 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4878 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4879 ;; function in i386.c.
4880 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4881   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4882         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883    (clobber (reg:CC FLAGS_REG))]
4884   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4885    && !TARGET_FISTTP
4886    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4887          && (TARGET_64BIT || <MODE>mode != DImode))
4888    && !(reload_completed || reload_in_progress)"
4889   "#"
4890   "&& 1"
4891   [(const_int 0)]
4892 {
4893   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4894
4895   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4896   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4897   if (memory_operand (operands[0], VOIDmode))
4898     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4899                                          operands[2], operands[3]));
4900   else
4901     {
4902       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4903       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4904                                                      operands[2], operands[3],
4905                                                      operands[4]));
4906     }
4907   DONE;
4908 }
4909   [(set_attr "type" "fistp")
4910    (set_attr "i387_cw" "trunc")
4911    (set_attr "mode" "<MODE>")])
4912
4913 (define_insn "fix_truncdi_i387"
4914   [(set (match_operand:DI 0 "memory_operand" "=m")
4915         (fix:DI (match_operand 1 "register_operand" "f")))
4916    (use (match_operand:HI 2 "memory_operand" "m"))
4917    (use (match_operand:HI 3 "memory_operand" "m"))
4918    (clobber (match_scratch:XF 4 "=&1f"))]
4919   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4920    && !TARGET_FISTTP
4921    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4922   "* return output_fix_trunc (insn, operands, 0);"
4923   [(set_attr "type" "fistp")
4924    (set_attr "i387_cw" "trunc")
4925    (set_attr "mode" "DI")])
4926
4927 (define_insn "fix_truncdi_i387_with_temp"
4928   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4929         (fix:DI (match_operand 1 "register_operand" "f,f")))
4930    (use (match_operand:HI 2 "memory_operand" "m,m"))
4931    (use (match_operand:HI 3 "memory_operand" "m,m"))
4932    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4933    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4934   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935    && !TARGET_FISTTP
4936    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937   "#"
4938   [(set_attr "type" "fistp")
4939    (set_attr "i387_cw" "trunc")
4940    (set_attr "mode" "DI")])
4941
4942 (define_split
4943   [(set (match_operand:DI 0 "register_operand" "")
4944         (fix:DI (match_operand 1 "register_operand" "")))
4945    (use (match_operand:HI 2 "memory_operand" ""))
4946    (use (match_operand:HI 3 "memory_operand" ""))
4947    (clobber (match_operand:DI 4 "memory_operand" ""))
4948    (clobber (match_scratch 5 ""))]
4949   "reload_completed"
4950   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4951               (use (match_dup 2))
4952               (use (match_dup 3))
4953               (clobber (match_dup 5))])
4954    (set (match_dup 0) (match_dup 4))]
4955   "")
4956
4957 (define_split
4958   [(set (match_operand:DI 0 "memory_operand" "")
4959         (fix:DI (match_operand 1 "register_operand" "")))
4960    (use (match_operand:HI 2 "memory_operand" ""))
4961    (use (match_operand:HI 3 "memory_operand" ""))
4962    (clobber (match_operand:DI 4 "memory_operand" ""))
4963    (clobber (match_scratch 5 ""))]
4964   "reload_completed"
4965   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4966               (use (match_dup 2))
4967               (use (match_dup 3))
4968               (clobber (match_dup 5))])]
4969   "")
4970
4971 (define_insn "fix_trunc<mode>_i387"
4972   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4973         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4974    (use (match_operand:HI 2 "memory_operand" "m"))
4975    (use (match_operand:HI 3 "memory_operand" "m"))]
4976   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977    && !TARGET_FISTTP
4978    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4979   "* return output_fix_trunc (insn, operands, 0);"
4980   [(set_attr "type" "fistp")
4981    (set_attr "i387_cw" "trunc")
4982    (set_attr "mode" "<MODE>")])
4983
4984 (define_insn "fix_trunc<mode>_i387_with_temp"
4985   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4986         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4987    (use (match_operand:HI 2 "memory_operand" "m,m"))
4988    (use (match_operand:HI 3 "memory_operand" "m,m"))
4989    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4990   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4991    && !TARGET_FISTTP
4992    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4993   "#"
4994   [(set_attr "type" "fistp")
4995    (set_attr "i387_cw" "trunc")
4996    (set_attr "mode" "<MODE>")])
4997
4998 (define_split
4999   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5000         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5001    (use (match_operand:HI 2 "memory_operand" ""))
5002    (use (match_operand:HI 3 "memory_operand" ""))
5003    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5004   "reload_completed"
5005   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5006               (use (match_dup 2))
5007               (use (match_dup 3))])
5008    (set (match_dup 0) (match_dup 4))]
5009   "")
5010
5011 (define_split
5012   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5013         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5014    (use (match_operand:HI 2 "memory_operand" ""))
5015    (use (match_operand:HI 3 "memory_operand" ""))
5016    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5017   "reload_completed"
5018   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5019               (use (match_dup 2))
5020               (use (match_dup 3))])]
5021   "")
5022
5023 (define_insn "x86_fnstcw_1"
5024   [(set (match_operand:HI 0 "memory_operand" "=m")
5025         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5026   "TARGET_80387"
5027   "fnstcw\t%0"
5028   [(set_attr "length" "2")
5029    (set_attr "mode" "HI")
5030    (set_attr "unit" "i387")])
5031
5032 (define_insn "x86_fldcw_1"
5033   [(set (reg:HI FPCR_REG)
5034         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5035   "TARGET_80387"
5036   "fldcw\t%0"
5037   [(set_attr "length" "2")
5038    (set_attr "mode" "HI")
5039    (set_attr "unit" "i387")
5040    (set_attr "athlon_decode" "vector")
5041    (set_attr "amdfam10_decode" "vector")])
5042 \f
5043 ;; Conversion between fixed point and floating point.
5044
5045 ;; Even though we only accept memory inputs, the backend _really_
5046 ;; wants to be able to do this between registers.
5047
5048 (define_expand "floathi<mode>2"
5049   [(set (match_operand:X87MODEF 0 "register_operand" "")
5050         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5051   "TARGET_80387
5052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5053        || TARGET_MIX_SSE_I387)"
5054   "")
5055
5056 ;; Pre-reload splitter to add memory clobber to the pattern.
5057 (define_insn_and_split "*floathi<mode>2_1"
5058   [(set (match_operand:X87MODEF 0 "register_operand" "")
5059         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5060   "TARGET_80387
5061    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5062        || TARGET_MIX_SSE_I387)
5063    && !(reload_completed || reload_in_progress)"
5064   "#"
5065   "&& 1"
5066   [(parallel [(set (match_dup 0)
5067               (float:X87MODEF (match_dup 1)))
5068    (clobber (match_dup 2))])]
5069   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5070
5071 (define_insn "*floathi<mode>2_i387_with_temp"
5072   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5073         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5074   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5075   "TARGET_80387
5076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077        || TARGET_MIX_SSE_I387)"
5078   "#"
5079   [(set_attr "type" "fmov,multi")
5080    (set_attr "mode" "<MODE>")
5081    (set_attr "unit" "*,i387")
5082    (set_attr "fp_int_src" "true")])
5083
5084 (define_insn "*floathi<mode>2_i387"
5085   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5086         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5087   "TARGET_80387
5088    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5089        || TARGET_MIX_SSE_I387)"
5090   "fild%z1\t%1"
5091   [(set_attr "type" "fmov")
5092    (set_attr "mode" "<MODE>")
5093    (set_attr "fp_int_src" "true")])
5094
5095 (define_split
5096   [(set (match_operand:X87MODEF 0 "register_operand" "")
5097         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5098    (clobber (match_operand:HI 2 "memory_operand" ""))]
5099   "TARGET_80387
5100    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5101        || TARGET_MIX_SSE_I387)
5102    && reload_completed"
5103   [(set (match_dup 2) (match_dup 1))
5104    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5105   "")
5106
5107 (define_split
5108   [(set (match_operand:X87MODEF 0 "register_operand" "")
5109         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5110    (clobber (match_operand:HI 2 "memory_operand" ""))]
5111    "TARGET_80387
5112     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5113         || TARGET_MIX_SSE_I387)
5114     && reload_completed"
5115   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5116   "")
5117
5118 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5119   [(set (match_operand:X87MODEF 0 "register_operand" "")
5120         (float:X87MODEF
5121           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5122   "TARGET_80387
5123    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5124        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5125   "")
5126
5127 ;; Pre-reload splitter to add memory clobber to the pattern.
5128 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5129   [(set (match_operand:X87MODEF 0 "register_operand" "")
5130         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5131   "((TARGET_80387
5132      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5133            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5134          || TARGET_MIX_SSE_I387))
5135     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5136         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5137         && ((<SSEMODEI24:MODE>mode == SImode
5138              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5139              && optimize_function_for_speed_p (cfun)
5140              && flag_trapping_math)
5141             || !(TARGET_INTER_UNIT_CONVERSIONS
5142                  || optimize_function_for_size_p (cfun)))))
5143    && !(reload_completed || reload_in_progress)"
5144   "#"
5145   "&& 1"
5146   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5147               (clobber (match_dup 2))])]
5148 {
5149   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5150
5151   /* Avoid store forwarding (partial memory) stall penalty
5152      by passing DImode value through XMM registers.  */
5153   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5154       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5155       && optimize_function_for_speed_p (cfun))
5156     {
5157       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5158                                                             operands[1],
5159                                                             operands[2]));
5160       DONE;
5161     }
5162 })
5163
5164 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5165   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5166         (float:MODEF
5167           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5168    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5169   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5170    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5171   "#"
5172   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5173    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5174    (set_attr "unit" "*,i387,*,*,*")
5175    (set_attr "athlon_decode" "*,*,double,direct,double")
5176    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5177    (set_attr "fp_int_src" "true")])
5178
5179 (define_insn "*floatsi<mode>2_vector_mixed"
5180   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5181         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5182   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5183    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5184   "@
5185    fild%z1\t%1
5186    #"
5187   [(set_attr "type" "fmov,sseicvt")
5188    (set_attr "mode" "<MODE>,<ssevecmode>")
5189    (set_attr "unit" "i387,*")
5190    (set_attr "athlon_decode" "*,direct")
5191    (set_attr "amdfam10_decode" "*,double")
5192    (set_attr "fp_int_src" "true")])
5193
5194 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5195   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5196         (float:MODEF
5197           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5198   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5199   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5200    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5201   "#"
5202   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5203    (set_attr "mode" "<MODEF:MODE>")
5204    (set_attr "unit" "*,i387,*,*")
5205    (set_attr "athlon_decode" "*,*,double,direct")
5206    (set_attr "amdfam10_decode" "*,*,vector,double")
5207    (set_attr "fp_int_src" "true")])
5208
5209 (define_split
5210   [(set (match_operand:MODEF 0 "register_operand" "")
5211         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5212    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5213   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5214    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5215    && TARGET_INTER_UNIT_CONVERSIONS
5216    && reload_completed
5217    && (SSE_REG_P (operands[0])
5218        || (GET_CODE (operands[0]) == SUBREG
5219            && SSE_REG_P (operands[0])))"
5220   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5221   "")
5222
5223 (define_split
5224   [(set (match_operand:MODEF 0 "register_operand" "")
5225         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5227   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5228    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5229    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5230    && reload_completed
5231    && (SSE_REG_P (operands[0])
5232        || (GET_CODE (operands[0]) == SUBREG
5233            && SSE_REG_P (operands[0])))"
5234   [(set (match_dup 2) (match_dup 1))
5235    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5236   "")
5237
5238 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5239   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5240         (float:MODEF
5241           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5242   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5243    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5244    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5245   "@
5246    fild%z1\t%1
5247    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5248    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5249   [(set_attr "type" "fmov,sseicvt,sseicvt")
5250    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5251    (set_attr "mode" "<MODEF:MODE>")
5252    (set_attr "unit" "i387,*,*")
5253    (set_attr "athlon_decode" "*,double,direct")
5254    (set_attr "amdfam10_decode" "*,vector,double")
5255    (set_attr "fp_int_src" "true")])
5256
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5258   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5259         (float:MODEF
5260           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5261   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5263    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5264   "@
5265    fild%z1\t%1
5266    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5267   [(set_attr "type" "fmov,sseicvt")
5268    (set_attr "prefix" "orig,maybe_vex")
5269    (set_attr "mode" "<MODEF:MODE>")
5270    (set_attr "athlon_decode" "*,direct")
5271    (set_attr "amdfam10_decode" "*,double")
5272    (set_attr "fp_int_src" "true")])
5273
5274 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5275   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5276         (float:MODEF
5277           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5278    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5279   "TARGET_SSE2 && TARGET_SSE_MATH
5280    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5281   "#"
5282   [(set_attr "type" "sseicvt")
5283    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5284    (set_attr "athlon_decode" "double,direct,double")
5285    (set_attr "amdfam10_decode" "vector,double,double")
5286    (set_attr "fp_int_src" "true")])
5287
5288 (define_insn "*floatsi<mode>2_vector_sse"
5289   [(set (match_operand:MODEF 0 "register_operand" "=x")
5290         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5291   "TARGET_SSE2 && TARGET_SSE_MATH
5292    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5293   "#"
5294   [(set_attr "type" "sseicvt")
5295    (set_attr "mode" "<MODE>")
5296    (set_attr "athlon_decode" "direct")
5297    (set_attr "amdfam10_decode" "double")
5298    (set_attr "fp_int_src" "true")])
5299
5300 (define_split
5301   [(set (match_operand:MODEF 0 "register_operand" "")
5302         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5303    (clobber (match_operand:SI 2 "memory_operand" ""))]
5304   "TARGET_SSE2 && TARGET_SSE_MATH
5305    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5306    && reload_completed
5307    && (SSE_REG_P (operands[0])
5308        || (GET_CODE (operands[0]) == SUBREG
5309            && SSE_REG_P (operands[0])))"
5310   [(const_int 0)]
5311 {
5312   rtx op1 = operands[1];
5313
5314   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5315                                      <MODE>mode, 0);
5316   if (GET_CODE (op1) == SUBREG)
5317     op1 = SUBREG_REG (op1);
5318
5319   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5320     {
5321       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5322       emit_insn (gen_sse2_loadld (operands[4],
5323                                   CONST0_RTX (V4SImode), operands[1]));
5324     }
5325   /* We can ignore possible trapping value in the
5326      high part of SSE register for non-trapping math. */
5327   else if (SSE_REG_P (op1) && !flag_trapping_math)
5328     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5329   else
5330     {
5331       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5332       emit_move_insn (operands[2], operands[1]);
5333       emit_insn (gen_sse2_loadld (operands[4],
5334                                   CONST0_RTX (V4SImode), operands[2]));
5335     }
5336   emit_insn
5337     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5338   DONE;
5339 })
5340
5341 (define_split
5342   [(set (match_operand:MODEF 0 "register_operand" "")
5343         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5344    (clobber (match_operand:SI 2 "memory_operand" ""))]
5345   "TARGET_SSE2 && TARGET_SSE_MATH
5346    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5347    && reload_completed
5348    && (SSE_REG_P (operands[0])
5349        || (GET_CODE (operands[0]) == SUBREG
5350            && SSE_REG_P (operands[0])))"
5351   [(const_int 0)]
5352 {
5353   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5354                                      <MODE>mode, 0);
5355   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5356
5357   emit_insn (gen_sse2_loadld (operands[4],
5358                               CONST0_RTX (V4SImode), operands[1]));
5359   emit_insn
5360     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5361   DONE;
5362 })
5363
5364 (define_split
5365   [(set (match_operand:MODEF 0 "register_operand" "")
5366         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5367   "TARGET_SSE2 && TARGET_SSE_MATH
5368    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5369    && reload_completed
5370    && (SSE_REG_P (operands[0])
5371        || (GET_CODE (operands[0]) == SUBREG
5372            && SSE_REG_P (operands[0])))"
5373   [(const_int 0)]
5374 {
5375   rtx op1 = operands[1];
5376
5377   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5378                                      <MODE>mode, 0);
5379   if (GET_CODE (op1) == SUBREG)
5380     op1 = SUBREG_REG (op1);
5381
5382   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5383     {
5384       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5385       emit_insn (gen_sse2_loadld (operands[4],
5386                                   CONST0_RTX (V4SImode), operands[1]));
5387     }
5388   /* We can ignore possible trapping value in the
5389      high part of SSE register for non-trapping math. */
5390   else if (SSE_REG_P (op1) && !flag_trapping_math)
5391     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5392   else
5393     gcc_unreachable ();
5394   emit_insn
5395     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5396   DONE;
5397 })
5398
5399 (define_split
5400   [(set (match_operand:MODEF 0 "register_operand" "")
5401         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5402   "TARGET_SSE2 && TARGET_SSE_MATH
5403    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5404    && reload_completed
5405    && (SSE_REG_P (operands[0])
5406        || (GET_CODE (operands[0]) == SUBREG
5407            && SSE_REG_P (operands[0])))"
5408   [(const_int 0)]
5409 {
5410   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5411                                      <MODE>mode, 0);
5412   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5413
5414   emit_insn (gen_sse2_loadld (operands[4],
5415                               CONST0_RTX (V4SImode), operands[1]));
5416   emit_insn
5417     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5418   DONE;
5419 })
5420
5421 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5422   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5423         (float:MODEF
5424           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5425   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5426   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5427    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5428   "#"
5429   [(set_attr "type" "sseicvt")
5430    (set_attr "mode" "<MODEF:MODE>")
5431    (set_attr "athlon_decode" "double,direct")
5432    (set_attr "amdfam10_decode" "vector,double")
5433    (set_attr "fp_int_src" "true")])
5434
5435 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5436   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5437         (float:MODEF
5438           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5439   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5440    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5441    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5442   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5443   [(set_attr "type" "sseicvt")
5444    (set_attr "prefix" "maybe_vex")
5445    (set_attr "mode" "<MODEF:MODE>")
5446    (set_attr "athlon_decode" "double,direct")
5447    (set_attr "amdfam10_decode" "vector,double")
5448    (set_attr "fp_int_src" "true")])
5449
5450 (define_split
5451   [(set (match_operand:MODEF 0 "register_operand" "")
5452         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5453    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5454   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5456    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5457    && reload_completed
5458    && (SSE_REG_P (operands[0])
5459        || (GET_CODE (operands[0]) == SUBREG
5460            && SSE_REG_P (operands[0])))"
5461   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5462   "")
5463
5464 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5465   [(set (match_operand:MODEF 0 "register_operand" "=x")
5466         (float:MODEF
5467           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5468   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5469    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5470    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5471   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5472   [(set_attr "type" "sseicvt")
5473    (set_attr "prefix" "maybe_vex")
5474    (set_attr "mode" "<MODEF:MODE>")
5475    (set_attr "athlon_decode" "direct")
5476    (set_attr "amdfam10_decode" "double")
5477    (set_attr "fp_int_src" "true")])
5478
5479 (define_split
5480   [(set (match_operand:MODEF 0 "register_operand" "")
5481         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5482    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5483   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5486    && reload_completed
5487    && (SSE_REG_P (operands[0])
5488        || (GET_CODE (operands[0]) == SUBREG
5489            && SSE_REG_P (operands[0])))"
5490   [(set (match_dup 2) (match_dup 1))
5491    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5492   "")
5493
5494 (define_split
5495   [(set (match_operand:MODEF 0 "register_operand" "")
5496         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5497    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5498   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500    && reload_completed
5501    && (SSE_REG_P (operands[0])
5502        || (GET_CODE (operands[0]) == SUBREG
5503            && SSE_REG_P (operands[0])))"
5504   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5505   "")
5506
5507 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5508   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5509         (float:X87MODEF
5510           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5511   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5512   "TARGET_80387"
5513   "@
5514    fild%z1\t%1
5515    #"
5516   [(set_attr "type" "fmov,multi")
5517    (set_attr "mode" "<X87MODEF:MODE>")
5518    (set_attr "unit" "*,i387")
5519    (set_attr "fp_int_src" "true")])
5520
5521 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5522   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5523         (float:X87MODEF
5524           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5525   "TARGET_80387"
5526   "fild%z1\t%1"
5527   [(set_attr "type" "fmov")
5528    (set_attr "mode" "<X87MODEF:MODE>")
5529    (set_attr "fp_int_src" "true")])
5530
5531 (define_split
5532   [(set (match_operand:X87MODEF 0 "register_operand" "")
5533         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5534    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5535   "TARGET_80387
5536    && reload_completed
5537    && FP_REG_P (operands[0])"
5538   [(set (match_dup 2) (match_dup 1))
5539    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5540   "")
5541
5542 (define_split
5543   [(set (match_operand:X87MODEF 0 "register_operand" "")
5544         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5545    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5546   "TARGET_80387
5547    && reload_completed
5548    && FP_REG_P (operands[0])"
5549   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5550   "")
5551
5552 ;; Avoid store forwarding (partial memory) stall penalty
5553 ;; by passing DImode value through XMM registers.  */
5554
5555 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5556   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5557         (float:X87MODEF
5558           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5559    (clobber (match_scratch:V4SI 3 "=X,x"))
5560    (clobber (match_scratch:V4SI 4 "=X,x"))
5561    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5562   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5563    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5564   "#"
5565   [(set_attr "type" "multi")
5566    (set_attr "mode" "<X87MODEF:MODE>")
5567    (set_attr "unit" "i387")
5568    (set_attr "fp_int_src" "true")])
5569
5570 (define_split
5571   [(set (match_operand:X87MODEF 0 "register_operand" "")
5572         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5573    (clobber (match_scratch:V4SI 3 ""))
5574    (clobber (match_scratch:V4SI 4 ""))
5575    (clobber (match_operand:DI 2 "memory_operand" ""))]
5576   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5577    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5578    && reload_completed
5579    && FP_REG_P (operands[0])"
5580   [(set (match_dup 2) (match_dup 3))
5581    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5582 {
5583   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5584      Assemble the 64-bit DImode value in an xmm register.  */
5585   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5586                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5587   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5588                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5589   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5590
5591   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5592 })
5593
5594 (define_split
5595   [(set (match_operand:X87MODEF 0 "register_operand" "")
5596         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5597    (clobber (match_scratch:V4SI 3 ""))
5598    (clobber (match_scratch:V4SI 4 ""))
5599    (clobber (match_operand:DI 2 "memory_operand" ""))]
5600   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5601    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5602    && reload_completed
5603    && FP_REG_P (operands[0])"
5604   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5605   "")
5606
5607 ;; Avoid store forwarding (partial memory) stall penalty by extending
5608 ;; SImode value to DImode through XMM register instead of pushing two
5609 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5610 ;; targets benefit from this optimization. Also note that fild
5611 ;; loads from memory only.
5612
5613 (define_insn "*floatunssi<mode>2_1"
5614   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5615         (unsigned_float:X87MODEF
5616           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5617    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5618    (clobber (match_scratch:SI 3 "=X,x"))]
5619   "!TARGET_64BIT
5620    && TARGET_80387 && TARGET_SSE"
5621   "#"
5622   [(set_attr "type" "multi")
5623    (set_attr "mode" "<MODE>")])
5624
5625 (define_split
5626   [(set (match_operand:X87MODEF 0 "register_operand" "")
5627         (unsigned_float:X87MODEF
5628           (match_operand:SI 1 "register_operand" "")))
5629    (clobber (match_operand:DI 2 "memory_operand" ""))
5630    (clobber (match_scratch:SI 3 ""))]
5631   "!TARGET_64BIT
5632    && TARGET_80387 && TARGET_SSE
5633    && reload_completed"
5634   [(set (match_dup 2) (match_dup 1))
5635    (set (match_dup 0)
5636         (float:X87MODEF (match_dup 2)))]
5637   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5638
5639 (define_split
5640   [(set (match_operand:X87MODEF 0 "register_operand" "")
5641         (unsigned_float:X87MODEF
5642           (match_operand:SI 1 "memory_operand" "")))
5643    (clobber (match_operand:DI 2 "memory_operand" ""))
5644    (clobber (match_scratch:SI 3 ""))]
5645   "!TARGET_64BIT
5646    && TARGET_80387 && TARGET_SSE
5647    && reload_completed"
5648   [(set (match_dup 2) (match_dup 3))
5649    (set (match_dup 0)
5650         (float:X87MODEF (match_dup 2)))]
5651 {
5652   emit_move_insn (operands[3], operands[1]);
5653   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5654 })
5655
5656 (define_expand "floatunssi<mode>2"
5657   [(parallel
5658      [(set (match_operand:X87MODEF 0 "register_operand" "")
5659            (unsigned_float:X87MODEF
5660              (match_operand:SI 1 "nonimmediate_operand" "")))
5661       (clobber (match_dup 2))
5662       (clobber (match_scratch:SI 3 ""))])]
5663   "!TARGET_64BIT
5664    && ((TARGET_80387 && TARGET_SSE)
5665        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5666 {
5667   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5668     {
5669       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5670       DONE;
5671     }
5672   else
5673     {
5674       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5675       operands[2] = assign_386_stack_local (DImode, slot);
5676     }
5677 })
5678
5679 (define_expand "floatunsdisf2"
5680   [(use (match_operand:SF 0 "register_operand" ""))
5681    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5682   "TARGET_64BIT && TARGET_SSE_MATH"
5683   "x86_emit_floatuns (operands); DONE;")
5684
5685 (define_expand "floatunsdidf2"
5686   [(use (match_operand:DF 0 "register_operand" ""))
5687    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5688   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5689    && TARGET_SSE2 && TARGET_SSE_MATH"
5690 {
5691   if (TARGET_64BIT)
5692     x86_emit_floatuns (operands);
5693   else
5694     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5695   DONE;
5696 })
5697 \f
5698 ;; Add instructions
5699
5700 ;; %%% splits for addditi3
5701
5702 (define_expand "addti3"
5703   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5704         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5705                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5706   "TARGET_64BIT"
5707   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5708
5709 (define_insn "*addti3_1"
5710   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5711         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5712                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5713    (clobber (reg:CC FLAGS_REG))]
5714   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5715   "#")
5716
5717 (define_split
5718   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5719         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5720                  (match_operand:TI 2 "x86_64_general_operand" "")))
5721    (clobber (reg:CC FLAGS_REG))]
5722   "TARGET_64BIT && reload_completed"
5723   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5724                                           UNSPEC_ADD_CARRY))
5725               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5726    (parallel [(set (match_dup 3)
5727                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5728                                      (match_dup 4))
5729                             (match_dup 5)))
5730               (clobber (reg:CC FLAGS_REG))])]
5731   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5732
5733 ;; %%% splits for addsidi3
5734 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5735 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5736 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5737
5738 (define_expand "adddi3"
5739   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5740         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5741                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5742   ""
5743   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5744
5745 (define_insn "*adddi3_1"
5746   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5747         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5748                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5749    (clobber (reg:CC FLAGS_REG))]
5750   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5751   "#")
5752
5753 (define_split
5754   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5755         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5756                  (match_operand:DI 2 "general_operand" "")))
5757    (clobber (reg:CC FLAGS_REG))]
5758   "!TARGET_64BIT && reload_completed"
5759   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5760                                           UNSPEC_ADD_CARRY))
5761               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5762    (parallel [(set (match_dup 3)
5763                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5764                                      (match_dup 4))
5765                             (match_dup 5)))
5766               (clobber (reg:CC FLAGS_REG))])]
5767   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5768
5769 (define_insn "adddi3_carry_rex64"
5770   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5771           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5772                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5773                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5774    (clobber (reg:CC FLAGS_REG))]
5775   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5776   "adc{q}\t{%2, %0|%0, %2}"
5777   [(set_attr "type" "alu")
5778    (set_attr "pent_pair" "pu")
5779    (set_attr "mode" "DI")])
5780
5781 (define_insn "*adddi3_cc_rex64"
5782   [(set (reg:CC FLAGS_REG)
5783         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5784                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5785                    UNSPEC_ADD_CARRY))
5786    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5787         (plus:DI (match_dup 1) (match_dup 2)))]
5788   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5789   "add{q}\t{%2, %0|%0, %2}"
5790   [(set_attr "type" "alu")
5791    (set_attr "mode" "DI")])
5792
5793 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5794   [(set (reg:CCC FLAGS_REG)
5795         (compare:CCC
5796             (plusminus:SWI
5797                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5798                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5799             (match_dup 1)))
5800    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5801         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5802   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5803   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5804   [(set_attr "type" "alu")
5805    (set_attr "mode" "<MODE>")])
5806
5807 (define_insn "*add<mode>3_cconly_overflow"
5808   [(set (reg:CCC FLAGS_REG)
5809         (compare:CCC
5810                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5811                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5812                 (match_dup 1)))
5813    (clobber (match_scratch:SWI 0 "=<r>"))]
5814   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5815   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5816   [(set_attr "type" "alu")
5817    (set_attr "mode" "<MODE>")])
5818
5819 (define_insn "*sub<mode>3_cconly_overflow"
5820   [(set (reg:CCC FLAGS_REG)
5821         (compare:CCC
5822              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5823                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5824              (match_dup 0)))]
5825   ""
5826   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5827   [(set_attr "type" "icmp")
5828    (set_attr "mode" "<MODE>")])
5829
5830 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5831   [(set (reg:CCC FLAGS_REG)
5832         (compare:CCC
5833             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5834                           (match_operand:SI 2 "general_operand" "g"))
5835             (match_dup 1)))
5836    (set (match_operand:DI 0 "register_operand" "=r")
5837         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5838   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5839   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5840   [(set_attr "type" "alu")
5841    (set_attr "mode" "SI")])
5842
5843 (define_insn "addqi3_carry"
5844   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5845           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5846                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5847                    (match_operand:QI 2 "general_operand" "qn,qm")))
5848    (clobber (reg:CC FLAGS_REG))]
5849   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5850   "adc{b}\t{%2, %0|%0, %2}"
5851   [(set_attr "type" "alu")
5852    (set_attr "pent_pair" "pu")
5853    (set_attr "mode" "QI")])
5854
5855 (define_insn "addhi3_carry"
5856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5857           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5858                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5859                    (match_operand:HI 2 "general_operand" "rn,rm")))
5860    (clobber (reg:CC FLAGS_REG))]
5861   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5862   "adc{w}\t{%2, %0|%0, %2}"
5863   [(set_attr "type" "alu")
5864    (set_attr "pent_pair" "pu")
5865    (set_attr "mode" "HI")])
5866
5867 (define_insn "addsi3_carry"
5868   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5869           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5870                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5871                    (match_operand:SI 2 "general_operand" "ri,rm")))
5872    (clobber (reg:CC FLAGS_REG))]
5873   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5874   "adc{l}\t{%2, %0|%0, %2}"
5875   [(set_attr "type" "alu")
5876    (set_attr "pent_pair" "pu")
5877    (set_attr "mode" "SI")])
5878
5879 (define_insn "*addsi3_carry_zext"
5880   [(set (match_operand:DI 0 "register_operand" "=r")
5881           (zero_extend:DI
5882             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5883                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5884                      (match_operand:SI 2 "general_operand" "g"))))
5885    (clobber (reg:CC FLAGS_REG))]
5886   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5887   "adc{l}\t{%2, %k0|%k0, %2}"
5888   [(set_attr "type" "alu")
5889    (set_attr "pent_pair" "pu")
5890    (set_attr "mode" "SI")])
5891
5892 (define_insn "*addsi3_cc"
5893   [(set (reg:CC FLAGS_REG)
5894         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5895                     (match_operand:SI 2 "general_operand" "ri,rm")]
5896                    UNSPEC_ADD_CARRY))
5897    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5898         (plus:SI (match_dup 1) (match_dup 2)))]
5899   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5900   "add{l}\t{%2, %0|%0, %2}"
5901   [(set_attr "type" "alu")
5902    (set_attr "mode" "SI")])
5903
5904 (define_insn "addqi3_cc"
5905   [(set (reg:CC FLAGS_REG)
5906         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5907                     (match_operand:QI 2 "general_operand" "qn,qm")]
5908                    UNSPEC_ADD_CARRY))
5909    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5910         (plus:QI (match_dup 1) (match_dup 2)))]
5911   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5912   "add{b}\t{%2, %0|%0, %2}"
5913   [(set_attr "type" "alu")
5914    (set_attr "mode" "QI")])
5915
5916 (define_expand "addsi3"
5917   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5918         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5919                  (match_operand:SI 2 "general_operand" "")))]
5920   ""
5921   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5922
5923 (define_insn "*lea_1"
5924   [(set (match_operand:SI 0 "register_operand" "=r")
5925         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5926   "!TARGET_64BIT"
5927   "lea{l}\t{%a1, %0|%0, %a1}"
5928   [(set_attr "type" "lea")
5929    (set_attr "mode" "SI")])
5930
5931 (define_insn "*lea_1_rex64"
5932   [(set (match_operand:SI 0 "register_operand" "=r")
5933         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5934   "TARGET_64BIT"
5935   "lea{l}\t{%a1, %0|%0, %a1}"
5936   [(set_attr "type" "lea")
5937    (set_attr "mode" "SI")])
5938
5939 (define_insn "*lea_1_zext"
5940   [(set (match_operand:DI 0 "register_operand" "=r")
5941         (zero_extend:DI
5942          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5943   "TARGET_64BIT"
5944   "lea{l}\t{%a1, %k0|%k0, %a1}"
5945   [(set_attr "type" "lea")
5946    (set_attr "mode" "SI")])
5947
5948 (define_insn "*lea_2_rex64"
5949   [(set (match_operand:DI 0 "register_operand" "=r")
5950         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5951   "TARGET_64BIT"
5952   "lea{q}\t{%a1, %0|%0, %a1}"
5953   [(set_attr "type" "lea")
5954    (set_attr "mode" "DI")])
5955
5956 ;; The lea patterns for non-Pmodes needs to be matched by several
5957 ;; insns converted to real lea by splitters.
5958
5959 (define_insn_and_split "*lea_general_1"
5960   [(set (match_operand 0 "register_operand" "=r")
5961         (plus (plus (match_operand 1 "index_register_operand" "l")
5962                     (match_operand 2 "register_operand" "r"))
5963               (match_operand 3 "immediate_operand" "i")))]
5964   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5965     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5966    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5967    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5968    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5969    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5970        || GET_MODE (operands[3]) == VOIDmode)"
5971   "#"
5972   "&& reload_completed"
5973   [(const_int 0)]
5974 {
5975   rtx pat;
5976   operands[0] = gen_lowpart (SImode, operands[0]);
5977   operands[1] = gen_lowpart (Pmode, operands[1]);
5978   operands[2] = gen_lowpart (Pmode, operands[2]);
5979   operands[3] = gen_lowpart (Pmode, operands[3]);
5980   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5981                       operands[3]);
5982   if (Pmode != SImode)
5983     pat = gen_rtx_SUBREG (SImode, pat, 0);
5984   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5985   DONE;
5986 }
5987   [(set_attr "type" "lea")
5988    (set_attr "mode" "SI")])
5989
5990 (define_insn_and_split "*lea_general_1_zext"
5991   [(set (match_operand:DI 0 "register_operand" "=r")
5992         (zero_extend:DI
5993           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5994                             (match_operand:SI 2 "register_operand" "r"))
5995                    (match_operand:SI 3 "immediate_operand" "i"))))]
5996   "TARGET_64BIT"
5997   "#"
5998   "&& reload_completed"
5999   [(set (match_dup 0)
6000         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6001                                                      (match_dup 2))
6002                                             (match_dup 3)) 0)))]
6003 {
6004   operands[1] = gen_lowpart (Pmode, operands[1]);
6005   operands[2] = gen_lowpart (Pmode, operands[2]);
6006   operands[3] = gen_lowpart (Pmode, operands[3]);
6007 }
6008   [(set_attr "type" "lea")
6009    (set_attr "mode" "SI")])
6010
6011 (define_insn_and_split "*lea_general_2"
6012   [(set (match_operand 0 "register_operand" "=r")
6013         (plus (mult (match_operand 1 "index_register_operand" "l")
6014                     (match_operand 2 "const248_operand" "i"))
6015               (match_operand 3 "nonmemory_operand" "ri")))]
6016   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6017     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6018    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6019    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6020    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6021        || GET_MODE (operands[3]) == VOIDmode)"
6022   "#"
6023   "&& reload_completed"
6024   [(const_int 0)]
6025 {
6026   rtx pat;
6027   operands[0] = gen_lowpart (SImode, operands[0]);
6028   operands[1] = gen_lowpart (Pmode, operands[1]);
6029   operands[3] = gen_lowpart (Pmode, operands[3]);
6030   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6031                       operands[3]);
6032   if (Pmode != SImode)
6033     pat = gen_rtx_SUBREG (SImode, pat, 0);
6034   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6035   DONE;
6036 }
6037   [(set_attr "type" "lea")
6038    (set_attr "mode" "SI")])
6039
6040 (define_insn_and_split "*lea_general_2_zext"
6041   [(set (match_operand:DI 0 "register_operand" "=r")
6042         (zero_extend:DI
6043           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6044                             (match_operand:SI 2 "const248_operand" "n"))
6045                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6046   "TARGET_64BIT"
6047   "#"
6048   "&& reload_completed"
6049   [(set (match_dup 0)
6050         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6051                                                      (match_dup 2))
6052                                             (match_dup 3)) 0)))]
6053 {
6054   operands[1] = gen_lowpart (Pmode, operands[1]);
6055   operands[3] = gen_lowpart (Pmode, operands[3]);
6056 }
6057   [(set_attr "type" "lea")
6058    (set_attr "mode" "SI")])
6059
6060 (define_insn_and_split "*lea_general_3"
6061   [(set (match_operand 0 "register_operand" "=r")
6062         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6063                           (match_operand 2 "const248_operand" "i"))
6064                     (match_operand 3 "register_operand" "r"))
6065               (match_operand 4 "immediate_operand" "i")))]
6066   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6067     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6068    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6069    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6070    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6071   "#"
6072   "&& reload_completed"
6073   [(const_int 0)]
6074 {
6075   rtx pat;
6076   operands[0] = gen_lowpart (SImode, operands[0]);
6077   operands[1] = gen_lowpart (Pmode, operands[1]);
6078   operands[3] = gen_lowpart (Pmode, operands[3]);
6079   operands[4] = gen_lowpart (Pmode, operands[4]);
6080   pat = gen_rtx_PLUS (Pmode,
6081                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6082                                                          operands[2]),
6083                                     operands[3]),
6084                       operands[4]);
6085   if (Pmode != SImode)
6086     pat = gen_rtx_SUBREG (SImode, pat, 0);
6087   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6088   DONE;
6089 }
6090   [(set_attr "type" "lea")
6091    (set_attr "mode" "SI")])
6092
6093 (define_insn_and_split "*lea_general_3_zext"
6094   [(set (match_operand:DI 0 "register_operand" "=r")
6095         (zero_extend:DI
6096           (plus:SI (plus:SI (mult:SI
6097                               (match_operand:SI 1 "index_register_operand" "l")
6098                               (match_operand:SI 2 "const248_operand" "n"))
6099                             (match_operand:SI 3 "register_operand" "r"))
6100                    (match_operand:SI 4 "immediate_operand" "i"))))]
6101   "TARGET_64BIT"
6102   "#"
6103   "&& reload_completed"
6104   [(set (match_dup 0)
6105         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6106                                                               (match_dup 2))
6107                                                      (match_dup 3))
6108                                             (match_dup 4)) 0)))]
6109 {
6110   operands[1] = gen_lowpart (Pmode, operands[1]);
6111   operands[3] = gen_lowpart (Pmode, operands[3]);
6112   operands[4] = gen_lowpart (Pmode, operands[4]);
6113 }
6114   [(set_attr "type" "lea")
6115    (set_attr "mode" "SI")])
6116
6117 (define_insn "*adddi_1_rex64"
6118   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6119         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6120                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6121    (clobber (reg:CC FLAGS_REG))]
6122   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6123 {
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_LEA:
6127       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6128       return "lea{q}\t{%a2, %0|%0, %a2}";
6129
6130     case TYPE_INCDEC:
6131       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6132       if (operands[2] == const1_rtx)
6133         return "inc{q}\t%0";
6134       else
6135         {
6136           gcc_assert (operands[2] == constm1_rtx);
6137           return "dec{q}\t%0";
6138         }
6139
6140     default:
6141       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6142
6143       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6144          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6145       if (CONST_INT_P (operands[2])
6146           /* Avoid overflows.  */
6147           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6148           && (INTVAL (operands[2]) == 128
6149               || (INTVAL (operands[2]) < 0
6150                   && INTVAL (operands[2]) != -128)))
6151         {
6152           operands[2] = GEN_INT (-INTVAL (operands[2]));
6153           return "sub{q}\t{%2, %0|%0, %2}";
6154         }
6155       return "add{q}\t{%2, %0|%0, %2}";
6156     }
6157 }
6158   [(set (attr "type")
6159      (cond [(eq_attr "alternative" "2")
6160               (const_string "lea")
6161             ; Current assemblers are broken and do not allow @GOTOFF in
6162             ; ought but a memory context.
6163             (match_operand:DI 2 "pic_symbolic_operand" "")
6164               (const_string "lea")
6165             (match_operand:DI 2 "incdec_operand" "")
6166               (const_string "incdec")
6167            ]
6168            (const_string "alu")))
6169    (set_attr "mode" "DI")])
6170
6171 ;; Convert lea to the lea pattern to avoid flags dependency.
6172 (define_split
6173   [(set (match_operand:DI 0 "register_operand" "")
6174         (plus:DI (match_operand:DI 1 "register_operand" "")
6175                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6176    (clobber (reg:CC FLAGS_REG))]
6177   "TARGET_64BIT && reload_completed
6178    && true_regnum (operands[0]) != true_regnum (operands[1])"
6179   [(set (match_dup 0)
6180         (plus:DI (match_dup 1)
6181                  (match_dup 2)))]
6182   "")
6183
6184 (define_insn "*adddi_2_rex64"
6185   [(set (reg FLAGS_REG)
6186         (compare
6187           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6188                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6189           (const_int 0)))
6190    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6191         (plus:DI (match_dup 1) (match_dup 2)))]
6192   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6193    && ix86_binary_operator_ok (PLUS, DImode, operands)
6194    /* Current assemblers are broken and do not allow @GOTOFF in
6195       ought but a memory context.  */
6196    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6197 {
6198   switch (get_attr_type (insn))
6199     {
6200     case TYPE_INCDEC:
6201       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6202       if (operands[2] == const1_rtx)
6203         return "inc{q}\t%0";
6204       else
6205         {
6206           gcc_assert (operands[2] == constm1_rtx);
6207           return "dec{q}\t%0";
6208         }
6209
6210     default:
6211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6212       /* ???? We ought to handle there the 32bit case too
6213          - do we need new constraint?  */
6214       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6215          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6216       if (CONST_INT_P (operands[2])
6217           /* Avoid overflows.  */
6218           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6219           && (INTVAL (operands[2]) == 128
6220               || (INTVAL (operands[2]) < 0
6221                   && INTVAL (operands[2]) != -128)))
6222         {
6223           operands[2] = GEN_INT (-INTVAL (operands[2]));
6224           return "sub{q}\t{%2, %0|%0, %2}";
6225         }
6226       return "add{q}\t{%2, %0|%0, %2}";
6227     }
6228 }
6229   [(set (attr "type")
6230      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6231         (const_string "incdec")
6232         (const_string "alu")))
6233    (set_attr "mode" "DI")])
6234
6235 (define_insn "*adddi_3_rex64"
6236   [(set (reg FLAGS_REG)
6237         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6238                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6239    (clobber (match_scratch:DI 0 "=r"))]
6240   "TARGET_64BIT
6241    && ix86_match_ccmode (insn, CCZmode)
6242    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6243    /* Current assemblers are broken and do not allow @GOTOFF in
6244       ought but a memory context.  */
6245    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6246 {
6247   switch (get_attr_type (insn))
6248     {
6249     case TYPE_INCDEC:
6250       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6251       if (operands[2] == const1_rtx)
6252         return "inc{q}\t%0";
6253       else
6254         {
6255           gcc_assert (operands[2] == constm1_rtx);
6256           return "dec{q}\t%0";
6257         }
6258
6259     default:
6260       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6261       /* ???? We ought to handle there the 32bit case too
6262          - do we need new constraint?  */
6263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6265       if (CONST_INT_P (operands[2])
6266           /* Avoid overflows.  */
6267           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6268           && (INTVAL (operands[2]) == 128
6269               || (INTVAL (operands[2]) < 0
6270                   && INTVAL (operands[2]) != -128)))
6271         {
6272           operands[2] = GEN_INT (-INTVAL (operands[2]));
6273           return "sub{q}\t{%2, %0|%0, %2}";
6274         }
6275       return "add{q}\t{%2, %0|%0, %2}";
6276     }
6277 }
6278   [(set (attr "type")
6279      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6280         (const_string "incdec")
6281         (const_string "alu")))
6282    (set_attr "mode" "DI")])
6283
6284 ; For comparisons against 1, -1 and 128, we may generate better code
6285 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6286 ; is matched then.  We can't accept general immediate, because for
6287 ; case of overflows,  the result is messed up.
6288 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6289 ; when negated.
6290 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6291 ; only for comparisons not depending on it.
6292 (define_insn "*adddi_4_rex64"
6293   [(set (reg FLAGS_REG)
6294         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6295                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6296    (clobber (match_scratch:DI 0 "=rm"))]
6297   "TARGET_64BIT
6298    &&  ix86_match_ccmode (insn, CCGCmode)"
6299 {
6300   switch (get_attr_type (insn))
6301     {
6302     case TYPE_INCDEC:
6303       if (operands[2] == constm1_rtx)
6304         return "inc{q}\t%0";
6305       else
6306         {
6307           gcc_assert (operands[2] == const1_rtx);
6308           return "dec{q}\t%0";
6309         }
6310
6311     default:
6312       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6313       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6314          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6315       if ((INTVAL (operands[2]) == -128
6316            || (INTVAL (operands[2]) > 0
6317                && INTVAL (operands[2]) != 128))
6318           /* Avoid overflows.  */
6319           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6320         return "sub{q}\t{%2, %0|%0, %2}";
6321       operands[2] = GEN_INT (-INTVAL (operands[2]));
6322       return "add{q}\t{%2, %0|%0, %2}";
6323     }
6324 }
6325   [(set (attr "type")
6326      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6327         (const_string "incdec")
6328         (const_string "alu")))
6329    (set_attr "mode" "DI")])
6330
6331 (define_insn "*adddi_5_rex64"
6332   [(set (reg FLAGS_REG)
6333         (compare
6334           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6335                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6336           (const_int 0)))
6337    (clobber (match_scratch:DI 0 "=r"))]
6338   "TARGET_64BIT
6339    && ix86_match_ccmode (insn, CCGOCmode)
6340    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6341    /* Current assemblers are broken and do not allow @GOTOFF in
6342       ought but a memory context.  */
6343    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6344 {
6345   switch (get_attr_type (insn))
6346     {
6347     case TYPE_INCDEC:
6348       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6349       if (operands[2] == const1_rtx)
6350         return "inc{q}\t%0";
6351       else
6352         {
6353           gcc_assert (operands[2] == constm1_rtx);
6354           return "dec{q}\t%0";
6355         }
6356
6357     default:
6358       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6359       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6360          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6361       if (CONST_INT_P (operands[2])
6362           /* Avoid overflows.  */
6363           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6364           && (INTVAL (operands[2]) == 128
6365               || (INTVAL (operands[2]) < 0
6366                   && INTVAL (operands[2]) != -128)))
6367         {
6368           operands[2] = GEN_INT (-INTVAL (operands[2]));
6369           return "sub{q}\t{%2, %0|%0, %2}";
6370         }
6371       return "add{q}\t{%2, %0|%0, %2}";
6372     }
6373 }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set_attr "mode" "DI")])
6379
6380
6381 (define_insn "*addsi_1"
6382   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6383         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6384                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6385    (clobber (reg:CC FLAGS_REG))]
6386   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6387 {
6388   switch (get_attr_type (insn))
6389     {
6390     case TYPE_LEA:
6391       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6392       return "lea{l}\t{%a2, %0|%0, %a2}";
6393
6394     case TYPE_INCDEC:
6395       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6396       if (operands[2] == const1_rtx)
6397         return "inc{l}\t%0";
6398       else
6399         {
6400           gcc_assert (operands[2] == constm1_rtx);
6401           return "dec{l}\t%0";
6402         }
6403
6404     default:
6405       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6406
6407       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6408          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6409       if (CONST_INT_P (operands[2])
6410           && (INTVAL (operands[2]) == 128
6411               || (INTVAL (operands[2]) < 0
6412                   && INTVAL (operands[2]) != -128)))
6413         {
6414           operands[2] = GEN_INT (-INTVAL (operands[2]));
6415           return "sub{l}\t{%2, %0|%0, %2}";
6416         }
6417       return "add{l}\t{%2, %0|%0, %2}";
6418     }
6419 }
6420   [(set (attr "type")
6421      (cond [(eq_attr "alternative" "2")
6422               (const_string "lea")
6423             ; Current assemblers are broken and do not allow @GOTOFF in
6424             ; ought but a memory context.
6425             (match_operand:SI 2 "pic_symbolic_operand" "")
6426               (const_string "lea")
6427             (match_operand:SI 2 "incdec_operand" "")
6428               (const_string "incdec")
6429            ]
6430            (const_string "alu")))
6431    (set_attr "mode" "SI")])
6432
6433 ;; Convert lea to the lea pattern to avoid flags dependency.
6434 (define_split
6435   [(set (match_operand 0 "register_operand" "")
6436         (plus (match_operand 1 "register_operand" "")
6437               (match_operand 2 "nonmemory_operand" "")))
6438    (clobber (reg:CC FLAGS_REG))]
6439   "reload_completed
6440    && true_regnum (operands[0]) != true_regnum (operands[1])"
6441   [(const_int 0)]
6442 {
6443   rtx pat;
6444   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6445      may confuse gen_lowpart.  */
6446   if (GET_MODE (operands[0]) != Pmode)
6447     {
6448       operands[1] = gen_lowpart (Pmode, operands[1]);
6449       operands[2] = gen_lowpart (Pmode, operands[2]);
6450     }
6451   operands[0] = gen_lowpart (SImode, operands[0]);
6452   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6453   if (Pmode != SImode)
6454     pat = gen_rtx_SUBREG (SImode, pat, 0);
6455   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6456   DONE;
6457 })
6458
6459 ;; It may seem that nonimmediate operand is proper one for operand 1.
6460 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6461 ;; we take care in ix86_binary_operator_ok to not allow two memory
6462 ;; operands so proper swapping will be done in reload.  This allow
6463 ;; patterns constructed from addsi_1 to match.
6464 (define_insn "addsi_1_zext"
6465   [(set (match_operand:DI 0 "register_operand" "=r,r")
6466         (zero_extend:DI
6467           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6468                    (match_operand:SI 2 "general_operand" "g,li"))))
6469    (clobber (reg:CC FLAGS_REG))]
6470   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6471 {
6472   switch (get_attr_type (insn))
6473     {
6474     case TYPE_LEA:
6475       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6476       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6477
6478     case TYPE_INCDEC:
6479       if (operands[2] == const1_rtx)
6480         return "inc{l}\t%k0";
6481       else
6482         {
6483           gcc_assert (operands[2] == constm1_rtx);
6484           return "dec{l}\t%k0";
6485         }
6486
6487     default:
6488       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6490       if (CONST_INT_P (operands[2])
6491           && (INTVAL (operands[2]) == 128
6492               || (INTVAL (operands[2]) < 0
6493                   && INTVAL (operands[2]) != -128)))
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "sub{l}\t{%2, %k0|%k0, %2}";
6497         }
6498       return "add{l}\t{%2, %k0|%k0, %2}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (cond [(eq_attr "alternative" "1")
6503               (const_string "lea")
6504             ; Current assemblers are broken and do not allow @GOTOFF in
6505             ; ought but a memory context.
6506             (match_operand:SI 2 "pic_symbolic_operand" "")
6507               (const_string "lea")
6508             (match_operand:SI 2 "incdec_operand" "")
6509               (const_string "incdec")
6510            ]
6511            (const_string "alu")))
6512    (set_attr "mode" "SI")])
6513
6514 ;; Convert lea to the lea pattern to avoid flags dependency.
6515 (define_split
6516   [(set (match_operand:DI 0 "register_operand" "")
6517         (zero_extend:DI
6518           (plus:SI (match_operand:SI 1 "register_operand" "")
6519                    (match_operand:SI 2 "nonmemory_operand" ""))))
6520    (clobber (reg:CC FLAGS_REG))]
6521   "TARGET_64BIT && reload_completed
6522    && true_regnum (operands[0]) != true_regnum (operands[1])"
6523   [(set (match_dup 0)
6524         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6525 {
6526   operands[1] = gen_lowpart (Pmode, operands[1]);
6527   operands[2] = gen_lowpart (Pmode, operands[2]);
6528 })
6529
6530 (define_insn "*addsi_2"
6531   [(set (reg FLAGS_REG)
6532         (compare
6533           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6534                    (match_operand:SI 2 "general_operand" "g,ri"))
6535           (const_int 0)))
6536    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6537         (plus:SI (match_dup 1) (match_dup 2)))]
6538   "ix86_match_ccmode (insn, CCGOCmode)
6539    && ix86_binary_operator_ok (PLUS, SImode, operands)
6540    /* Current assemblers are broken and do not allow @GOTOFF in
6541       ought but a memory context.  */
6542    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6543 {
6544   switch (get_attr_type (insn))
6545     {
6546     case TYPE_INCDEC:
6547       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6548       if (operands[2] == const1_rtx)
6549         return "inc{l}\t%0";
6550       else
6551         {
6552           gcc_assert (operands[2] == constm1_rtx);
6553           return "dec{l}\t%0";
6554         }
6555
6556     default:
6557       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6558       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6559          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6560       if (CONST_INT_P (operands[2])
6561           && (INTVAL (operands[2]) == 128
6562               || (INTVAL (operands[2]) < 0
6563                   && INTVAL (operands[2]) != -128)))
6564         {
6565           operands[2] = GEN_INT (-INTVAL (operands[2]));
6566           return "sub{l}\t{%2, %0|%0, %2}";
6567         }
6568       return "add{l}\t{%2, %0|%0, %2}";
6569     }
6570 }
6571   [(set (attr "type")
6572      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6573         (const_string "incdec")
6574         (const_string "alu")))
6575    (set_attr "mode" "SI")])
6576
6577 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6578 (define_insn "*addsi_2_zext"
6579   [(set (reg FLAGS_REG)
6580         (compare
6581           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6582                    (match_operand:SI 2 "general_operand" "g"))
6583           (const_int 0)))
6584    (set (match_operand:DI 0 "register_operand" "=r")
6585         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6586   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6587    && ix86_binary_operator_ok (PLUS, SImode, operands)
6588    /* Current assemblers are broken and do not allow @GOTOFF in
6589       ought but a memory context.  */
6590    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6591 {
6592   switch (get_attr_type (insn))
6593     {
6594     case TYPE_INCDEC:
6595       if (operands[2] == const1_rtx)
6596         return "inc{l}\t%k0";
6597       else
6598         {
6599           gcc_assert (operands[2] == constm1_rtx);
6600           return "dec{l}\t%k0";
6601         }
6602
6603     default:
6604       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6606       if (CONST_INT_P (operands[2])
6607           && (INTVAL (operands[2]) == 128
6608               || (INTVAL (operands[2]) < 0
6609                   && INTVAL (operands[2]) != -128)))
6610         {
6611           operands[2] = GEN_INT (-INTVAL (operands[2]));
6612           return "sub{l}\t{%2, %k0|%k0, %2}";
6613         }
6614       return "add{l}\t{%2, %k0|%k0, %2}";
6615     }
6616 }
6617   [(set (attr "type")
6618      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6619         (const_string "incdec")
6620         (const_string "alu")))
6621    (set_attr "mode" "SI")])
6622
6623 (define_insn "*addsi_3"
6624   [(set (reg FLAGS_REG)
6625         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6626                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6627    (clobber (match_scratch:SI 0 "=r"))]
6628   "ix86_match_ccmode (insn, CCZmode)
6629    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6630    /* Current assemblers are broken and do not allow @GOTOFF in
6631       ought but a memory context.  */
6632    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6633 {
6634   switch (get_attr_type (insn))
6635     {
6636     case TYPE_INCDEC:
6637       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6638       if (operands[2] == const1_rtx)
6639         return "inc{l}\t%0";
6640       else
6641         {
6642           gcc_assert (operands[2] == constm1_rtx);
6643           return "dec{l}\t%0";
6644         }
6645
6646     default:
6647       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6648       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6649          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6650       if (CONST_INT_P (operands[2])
6651           && (INTVAL (operands[2]) == 128
6652               || (INTVAL (operands[2]) < 0
6653                   && INTVAL (operands[2]) != -128)))
6654         {
6655           operands[2] = GEN_INT (-INTVAL (operands[2]));
6656           return "sub{l}\t{%2, %0|%0, %2}";
6657         }
6658       return "add{l}\t{%2, %0|%0, %2}";
6659     }
6660 }
6661   [(set (attr "type")
6662      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6663         (const_string "incdec")
6664         (const_string "alu")))
6665    (set_attr "mode" "SI")])
6666
6667 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6668 (define_insn "*addsi_3_zext"
6669   [(set (reg FLAGS_REG)
6670         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6671                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6672    (set (match_operand:DI 0 "register_operand" "=r")
6673         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6674   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6675    && ix86_binary_operator_ok (PLUS, SImode, operands)
6676    /* Current assemblers are broken and do not allow @GOTOFF in
6677       ought but a memory context.  */
6678    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6679 {
6680   switch (get_attr_type (insn))
6681     {
6682     case TYPE_INCDEC:
6683       if (operands[2] == const1_rtx)
6684         return "inc{l}\t%k0";
6685       else
6686         {
6687           gcc_assert (operands[2] == constm1_rtx);
6688           return "dec{l}\t%k0";
6689         }
6690
6691     default:
6692       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6693          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6694       if (CONST_INT_P (operands[2])
6695           && (INTVAL (operands[2]) == 128
6696               || (INTVAL (operands[2]) < 0
6697                   && INTVAL (operands[2]) != -128)))
6698         {
6699           operands[2] = GEN_INT (-INTVAL (operands[2]));
6700           return "sub{l}\t{%2, %k0|%k0, %2}";
6701         }
6702       return "add{l}\t{%2, %k0|%k0, %2}";
6703     }
6704 }
6705   [(set (attr "type")
6706      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6707         (const_string "incdec")
6708         (const_string "alu")))
6709    (set_attr "mode" "SI")])
6710
6711 ; For comparisons against 1, -1 and 128, we may generate better code
6712 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6713 ; is matched then.  We can't accept general immediate, because for
6714 ; case of overflows,  the result is messed up.
6715 ; This pattern also don't hold of 0x80000000, since the value overflows
6716 ; when negated.
6717 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6718 ; only for comparisons not depending on it.
6719 (define_insn "*addsi_4"
6720   [(set (reg FLAGS_REG)
6721         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6722                  (match_operand:SI 2 "const_int_operand" "n")))
6723    (clobber (match_scratch:SI 0 "=rm"))]
6724   "ix86_match_ccmode (insn, CCGCmode)
6725    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6726 {
6727   switch (get_attr_type (insn))
6728     {
6729     case TYPE_INCDEC:
6730       if (operands[2] == constm1_rtx)
6731         return "inc{l}\t%0";
6732       else
6733         {
6734           gcc_assert (operands[2] == const1_rtx);
6735           return "dec{l}\t%0";
6736         }
6737
6738     default:
6739       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6740       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6741          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6742       if ((INTVAL (operands[2]) == -128
6743            || (INTVAL (operands[2]) > 0
6744                && INTVAL (operands[2]) != 128)))
6745         return "sub{l}\t{%2, %0|%0, %2}";
6746       operands[2] = GEN_INT (-INTVAL (operands[2]));
6747       return "add{l}\t{%2, %0|%0, %2}";
6748     }
6749 }
6750   [(set (attr "type")
6751      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6752         (const_string "incdec")
6753         (const_string "alu")))
6754    (set_attr "mode" "SI")])
6755
6756 (define_insn "*addsi_5"
6757   [(set (reg FLAGS_REG)
6758         (compare
6759           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6760                    (match_operand:SI 2 "general_operand" "g"))
6761           (const_int 0)))
6762    (clobber (match_scratch:SI 0 "=r"))]
6763   "ix86_match_ccmode (insn, CCGOCmode)
6764    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6765    /* Current assemblers are broken and do not allow @GOTOFF in
6766       ought but a memory context.  */
6767    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6768 {
6769   switch (get_attr_type (insn))
6770     {
6771     case TYPE_INCDEC:
6772       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6773       if (operands[2] == const1_rtx)
6774         return "inc{l}\t%0";
6775       else
6776         {
6777           gcc_assert (operands[2] == constm1_rtx);
6778           return "dec{l}\t%0";
6779         }
6780
6781     default:
6782       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6783       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6784          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6785       if (CONST_INT_P (operands[2])
6786           && (INTVAL (operands[2]) == 128
6787               || (INTVAL (operands[2]) < 0
6788                   && INTVAL (operands[2]) != -128)))
6789         {
6790           operands[2] = GEN_INT (-INTVAL (operands[2]));
6791           return "sub{l}\t{%2, %0|%0, %2}";
6792         }
6793       return "add{l}\t{%2, %0|%0, %2}";
6794     }
6795 }
6796   [(set (attr "type")
6797      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6798         (const_string "incdec")
6799         (const_string "alu")))
6800    (set_attr "mode" "SI")])
6801
6802 (define_expand "addhi3"
6803   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6804         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6805                  (match_operand:HI 2 "general_operand" "")))]
6806   "TARGET_HIMODE_MATH"
6807   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6808
6809 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6810 ;; type optimizations enabled by define-splits.  This is not important
6811 ;; for PII, and in fact harmful because of partial register stalls.
6812
6813 (define_insn "*addhi_1_lea"
6814   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6815         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6816                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6817    (clobber (reg:CC FLAGS_REG))]
6818   "!TARGET_PARTIAL_REG_STALL
6819    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6820 {
6821   switch (get_attr_type (insn))
6822     {
6823     case TYPE_LEA:
6824       return "#";
6825     case TYPE_INCDEC:
6826       if (operands[2] == const1_rtx)
6827         return "inc{w}\t%0";
6828       else
6829         {
6830           gcc_assert (operands[2] == constm1_rtx);
6831           return "dec{w}\t%0";
6832         }
6833
6834     default:
6835       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6836          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6837       if (CONST_INT_P (operands[2])
6838           && (INTVAL (operands[2]) == 128
6839               || (INTVAL (operands[2]) < 0
6840                   && INTVAL (operands[2]) != -128)))
6841         {
6842           operands[2] = GEN_INT (-INTVAL (operands[2]));
6843           return "sub{w}\t{%2, %0|%0, %2}";
6844         }
6845       return "add{w}\t{%2, %0|%0, %2}";
6846     }
6847 }
6848   [(set (attr "type")
6849      (if_then_else (eq_attr "alternative" "2")
6850         (const_string "lea")
6851         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6852            (const_string "incdec")
6853            (const_string "alu"))))
6854    (set_attr "mode" "HI,HI,SI")])
6855
6856 (define_insn "*addhi_1"
6857   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6858         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6859                  (match_operand:HI 2 "general_operand" "rn,rm")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "TARGET_PARTIAL_REG_STALL
6862    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6863 {
6864   switch (get_attr_type (insn))
6865     {
6866     case TYPE_INCDEC:
6867       if (operands[2] == const1_rtx)
6868         return "inc{w}\t%0";
6869       else
6870         {
6871           gcc_assert (operands[2] == constm1_rtx);
6872           return "dec{w}\t%0";
6873         }
6874
6875     default:
6876       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6877          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6878       if (CONST_INT_P (operands[2])
6879           && (INTVAL (operands[2]) == 128
6880               || (INTVAL (operands[2]) < 0
6881                   && INTVAL (operands[2]) != -128)))
6882         {
6883           operands[2] = GEN_INT (-INTVAL (operands[2]));
6884           return "sub{w}\t{%2, %0|%0, %2}";
6885         }
6886       return "add{w}\t{%2, %0|%0, %2}";
6887     }
6888 }
6889   [(set (attr "type")
6890      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6891         (const_string "incdec")
6892         (const_string "alu")))
6893    (set_attr "mode" "HI")])
6894
6895 (define_insn "*addhi_2"
6896   [(set (reg FLAGS_REG)
6897         (compare
6898           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6899                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6900           (const_int 0)))
6901    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6902         (plus:HI (match_dup 1) (match_dup 2)))]
6903   "ix86_match_ccmode (insn, CCGOCmode)
6904    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6905 {
6906   switch (get_attr_type (insn))
6907     {
6908     case TYPE_INCDEC:
6909       if (operands[2] == const1_rtx)
6910         return "inc{w}\t%0";
6911       else
6912         {
6913           gcc_assert (operands[2] == constm1_rtx);
6914           return "dec{w}\t%0";
6915         }
6916
6917     default:
6918       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6919          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6920       if (CONST_INT_P (operands[2])
6921           && (INTVAL (operands[2]) == 128
6922               || (INTVAL (operands[2]) < 0
6923                   && INTVAL (operands[2]) != -128)))
6924         {
6925           operands[2] = GEN_INT (-INTVAL (operands[2]));
6926           return "sub{w}\t{%2, %0|%0, %2}";
6927         }
6928       return "add{w}\t{%2, %0|%0, %2}";
6929     }
6930 }
6931   [(set (attr "type")
6932      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6933         (const_string "incdec")
6934         (const_string "alu")))
6935    (set_attr "mode" "HI")])
6936
6937 (define_insn "*addhi_3"
6938   [(set (reg FLAGS_REG)
6939         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6940                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6941    (clobber (match_scratch:HI 0 "=r"))]
6942   "ix86_match_ccmode (insn, CCZmode)
6943    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 {
6945   switch (get_attr_type (insn))
6946     {
6947     case TYPE_INCDEC:
6948       if (operands[2] == const1_rtx)
6949         return "inc{w}\t%0";
6950       else
6951         {
6952           gcc_assert (operands[2] == constm1_rtx);
6953           return "dec{w}\t%0";
6954         }
6955
6956     default:
6957       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6958          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6959       if (CONST_INT_P (operands[2])
6960           && (INTVAL (operands[2]) == 128
6961               || (INTVAL (operands[2]) < 0
6962                   && INTVAL (operands[2]) != -128)))
6963         {
6964           operands[2] = GEN_INT (-INTVAL (operands[2]));
6965           return "sub{w}\t{%2, %0|%0, %2}";
6966         }
6967       return "add{w}\t{%2, %0|%0, %2}";
6968     }
6969 }
6970   [(set (attr "type")
6971      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6972         (const_string "incdec")
6973         (const_string "alu")))
6974    (set_attr "mode" "HI")])
6975
6976 ; See comments above addsi_4 for details.
6977 (define_insn "*addhi_4"
6978   [(set (reg FLAGS_REG)
6979         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6980                  (match_operand:HI 2 "const_int_operand" "n")))
6981    (clobber (match_scratch:HI 0 "=rm"))]
6982   "ix86_match_ccmode (insn, CCGCmode)
6983    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6984 {
6985   switch (get_attr_type (insn))
6986     {
6987     case TYPE_INCDEC:
6988       if (operands[2] == constm1_rtx)
6989         return "inc{w}\t%0";
6990       else
6991         {
6992           gcc_assert (operands[2] == const1_rtx);
6993           return "dec{w}\t%0";
6994         }
6995
6996     default:
6997       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6998       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6999          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7000       if ((INTVAL (operands[2]) == -128
7001            || (INTVAL (operands[2]) > 0
7002                && INTVAL (operands[2]) != 128)))
7003         return "sub{w}\t{%2, %0|%0, %2}";
7004       operands[2] = GEN_INT (-INTVAL (operands[2]));
7005       return "add{w}\t{%2, %0|%0, %2}";
7006     }
7007 }
7008   [(set (attr "type")
7009      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7010         (const_string "incdec")
7011         (const_string "alu")))
7012    (set_attr "mode" "SI")])
7013
7014
7015 (define_insn "*addhi_5"
7016   [(set (reg FLAGS_REG)
7017         (compare
7018           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7019                    (match_operand:HI 2 "general_operand" "rmn"))
7020           (const_int 0)))
7021    (clobber (match_scratch:HI 0 "=r"))]
7022   "ix86_match_ccmode (insn, CCGOCmode)
7023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024 {
7025   switch (get_attr_type (insn))
7026     {
7027     case TYPE_INCDEC:
7028       if (operands[2] == const1_rtx)
7029         return "inc{w}\t%0";
7030       else
7031         {
7032           gcc_assert (operands[2] == constm1_rtx);
7033           return "dec{w}\t%0";
7034         }
7035
7036     default:
7037       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7038          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7039       if (CONST_INT_P (operands[2])
7040           && (INTVAL (operands[2]) == 128
7041               || (INTVAL (operands[2]) < 0
7042                   && INTVAL (operands[2]) != -128)))
7043         {
7044           operands[2] = GEN_INT (-INTVAL (operands[2]));
7045           return "sub{w}\t{%2, %0|%0, %2}";
7046         }
7047       return "add{w}\t{%2, %0|%0, %2}";
7048     }
7049 }
7050   [(set (attr "type")
7051      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7052         (const_string "incdec")
7053         (const_string "alu")))
7054    (set_attr "mode" "HI")])
7055
7056 (define_expand "addqi3"
7057   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7058         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7059                  (match_operand:QI 2 "general_operand" "")))]
7060   "TARGET_QIMODE_MATH"
7061   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7062
7063 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7064 (define_insn "*addqi_1_lea"
7065   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7066         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7067                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7068    (clobber (reg:CC FLAGS_REG))]
7069   "!TARGET_PARTIAL_REG_STALL
7070    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7071 {
7072   int widen = (which_alternative == 2);
7073   switch (get_attr_type (insn))
7074     {
7075     case TYPE_LEA:
7076       return "#";
7077     case TYPE_INCDEC:
7078       if (operands[2] == const1_rtx)
7079         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7080       else
7081         {
7082           gcc_assert (operands[2] == constm1_rtx);
7083           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7084         }
7085
7086     default:
7087       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7088          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7089       if (CONST_INT_P (operands[2])
7090           && (INTVAL (operands[2]) == 128
7091               || (INTVAL (operands[2]) < 0
7092                   && INTVAL (operands[2]) != -128)))
7093         {
7094           operands[2] = GEN_INT (-INTVAL (operands[2]));
7095           if (widen)
7096             return "sub{l}\t{%2, %k0|%k0, %2}";
7097           else
7098             return "sub{b}\t{%2, %0|%0, %2}";
7099         }
7100       if (widen)
7101         return "add{l}\t{%k2, %k0|%k0, %k2}";
7102       else
7103         return "add{b}\t{%2, %0|%0, %2}";
7104     }
7105 }
7106   [(set (attr "type")
7107      (if_then_else (eq_attr "alternative" "3")
7108         (const_string "lea")
7109         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7110            (const_string "incdec")
7111            (const_string "alu"))))
7112    (set_attr "mode" "QI,QI,SI,SI")])
7113
7114 (define_insn "*addqi_1"
7115   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7116         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7117                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7118    (clobber (reg:CC FLAGS_REG))]
7119   "TARGET_PARTIAL_REG_STALL
7120    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7121 {
7122   int widen = (which_alternative == 2);
7123   switch (get_attr_type (insn))
7124     {
7125     case TYPE_INCDEC:
7126       if (operands[2] == const1_rtx)
7127         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7128       else
7129         {
7130           gcc_assert (operands[2] == constm1_rtx);
7131           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7132         }
7133
7134     default:
7135       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7136          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7137       if (CONST_INT_P (operands[2])
7138           && (INTVAL (operands[2]) == 128
7139               || (INTVAL (operands[2]) < 0
7140                   && INTVAL (operands[2]) != -128)))
7141         {
7142           operands[2] = GEN_INT (-INTVAL (operands[2]));
7143           if (widen)
7144             return "sub{l}\t{%2, %k0|%k0, %2}";
7145           else
7146             return "sub{b}\t{%2, %0|%0, %2}";
7147         }
7148       if (widen)
7149         return "add{l}\t{%k2, %k0|%k0, %k2}";
7150       else
7151         return "add{b}\t{%2, %0|%0, %2}";
7152     }
7153 }
7154   [(set (attr "type")
7155      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7156         (const_string "incdec")
7157         (const_string "alu")))
7158    (set_attr "mode" "QI,QI,SI")])
7159
7160 (define_insn "*addqi_1_slp"
7161   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7162         (plus:QI (match_dup 0)
7163                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7164    (clobber (reg:CC FLAGS_REG))]
7165   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7166    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7167 {
7168   switch (get_attr_type (insn))
7169     {
7170     case TYPE_INCDEC:
7171       if (operands[1] == const1_rtx)
7172         return "inc{b}\t%0";
7173       else
7174         {
7175           gcc_assert (operands[1] == constm1_rtx);
7176           return "dec{b}\t%0";
7177         }
7178
7179     default:
7180       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7181       if (CONST_INT_P (operands[1])
7182           && INTVAL (operands[1]) < 0)
7183         {
7184           operands[1] = GEN_INT (-INTVAL (operands[1]));
7185           return "sub{b}\t{%1, %0|%0, %1}";
7186         }
7187       return "add{b}\t{%1, %0|%0, %1}";
7188     }
7189 }
7190   [(set (attr "type")
7191      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7192         (const_string "incdec")
7193         (const_string "alu1")))
7194    (set (attr "memory")
7195      (if_then_else (match_operand 1 "memory_operand" "")
7196         (const_string "load")
7197         (const_string "none")))
7198    (set_attr "mode" "QI")])
7199
7200 (define_insn "*addqi_2"
7201   [(set (reg FLAGS_REG)
7202         (compare
7203           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7204                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7205           (const_int 0)))
7206    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7207         (plus:QI (match_dup 1) (match_dup 2)))]
7208   "ix86_match_ccmode (insn, CCGOCmode)
7209    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7210 {
7211   switch (get_attr_type (insn))
7212     {
7213     case TYPE_INCDEC:
7214       if (operands[2] == const1_rtx)
7215         return "inc{b}\t%0";
7216       else
7217         {
7218           gcc_assert (operands[2] == constm1_rtx
7219                       || (CONST_INT_P (operands[2])
7220                           && INTVAL (operands[2]) == 255));
7221           return "dec{b}\t%0";
7222         }
7223
7224     default:
7225       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7226       if (CONST_INT_P (operands[2])
7227           && INTVAL (operands[2]) < 0)
7228         {
7229           operands[2] = GEN_INT (-INTVAL (operands[2]));
7230           return "sub{b}\t{%2, %0|%0, %2}";
7231         }
7232       return "add{b}\t{%2, %0|%0, %2}";
7233     }
7234 }
7235   [(set (attr "type")
7236      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7237         (const_string "incdec")
7238         (const_string "alu")))
7239    (set_attr "mode" "QI")])
7240
7241 (define_insn "*addqi_3"
7242   [(set (reg FLAGS_REG)
7243         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7244                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7245    (clobber (match_scratch:QI 0 "=q"))]
7246   "ix86_match_ccmode (insn, CCZmode)
7247    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7248 {
7249   switch (get_attr_type (insn))
7250     {
7251     case TYPE_INCDEC:
7252       if (operands[2] == const1_rtx)
7253         return "inc{b}\t%0";
7254       else
7255         {
7256           gcc_assert (operands[2] == constm1_rtx
7257                       || (CONST_INT_P (operands[2])
7258                           && INTVAL (operands[2]) == 255));
7259           return "dec{b}\t%0";
7260         }
7261
7262     default:
7263       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7264       if (CONST_INT_P (operands[2])
7265           && INTVAL (operands[2]) < 0)
7266         {
7267           operands[2] = GEN_INT (-INTVAL (operands[2]));
7268           return "sub{b}\t{%2, %0|%0, %2}";
7269         }
7270       return "add{b}\t{%2, %0|%0, %2}";
7271     }
7272 }
7273   [(set (attr "type")
7274      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7275         (const_string "incdec")
7276         (const_string "alu")))
7277    (set_attr "mode" "QI")])
7278
7279 ; See comments above addsi_4 for details.
7280 (define_insn "*addqi_4"
7281   [(set (reg FLAGS_REG)
7282         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7283                  (match_operand:QI 2 "const_int_operand" "n")))
7284    (clobber (match_scratch:QI 0 "=qm"))]
7285   "ix86_match_ccmode (insn, CCGCmode)
7286    && (INTVAL (operands[2]) & 0xff) != 0x80"
7287 {
7288   switch (get_attr_type (insn))
7289     {
7290     case TYPE_INCDEC:
7291       if (operands[2] == constm1_rtx
7292           || (CONST_INT_P (operands[2])
7293               && INTVAL (operands[2]) == 255))
7294         return "inc{b}\t%0";
7295       else
7296         {
7297           gcc_assert (operands[2] == const1_rtx);
7298           return "dec{b}\t%0";
7299         }
7300
7301     default:
7302       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7303       if (INTVAL (operands[2]) < 0)
7304         {
7305           operands[2] = GEN_INT (-INTVAL (operands[2]));
7306           return "add{b}\t{%2, %0|%0, %2}";
7307         }
7308       return "sub{b}\t{%2, %0|%0, %2}";
7309     }
7310 }
7311   [(set (attr "type")
7312      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7313         (const_string "incdec")
7314         (const_string "alu")))
7315    (set_attr "mode" "QI")])
7316
7317
7318 (define_insn "*addqi_5"
7319   [(set (reg FLAGS_REG)
7320         (compare
7321           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7322                    (match_operand:QI 2 "general_operand" "qmn"))
7323           (const_int 0)))
7324    (clobber (match_scratch:QI 0 "=q"))]
7325   "ix86_match_ccmode (insn, CCGOCmode)
7326    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7327 {
7328   switch (get_attr_type (insn))
7329     {
7330     case TYPE_INCDEC:
7331       if (operands[2] == const1_rtx)
7332         return "inc{b}\t%0";
7333       else
7334         {
7335           gcc_assert (operands[2] == constm1_rtx
7336                       || (CONST_INT_P (operands[2])
7337                           && INTVAL (operands[2]) == 255));
7338           return "dec{b}\t%0";
7339         }
7340
7341     default:
7342       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7343       if (CONST_INT_P (operands[2])
7344           && INTVAL (operands[2]) < 0)
7345         {
7346           operands[2] = GEN_INT (-INTVAL (operands[2]));
7347           return "sub{b}\t{%2, %0|%0, %2}";
7348         }
7349       return "add{b}\t{%2, %0|%0, %2}";
7350     }
7351 }
7352   [(set (attr "type")
7353      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7354         (const_string "incdec")
7355         (const_string "alu")))
7356    (set_attr "mode" "QI")])
7357
7358
7359 (define_insn "addqi_ext_1"
7360   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7361                          (const_int 8)
7362                          (const_int 8))
7363         (plus:SI
7364           (zero_extract:SI
7365             (match_operand 1 "ext_register_operand" "0")
7366             (const_int 8)
7367             (const_int 8))
7368           (match_operand:QI 2 "general_operand" "Qmn")))
7369    (clobber (reg:CC FLAGS_REG))]
7370   "!TARGET_64BIT"
7371 {
7372   switch (get_attr_type (insn))
7373     {
7374     case TYPE_INCDEC:
7375       if (operands[2] == const1_rtx)
7376         return "inc{b}\t%h0";
7377       else
7378         {
7379           gcc_assert (operands[2] == constm1_rtx
7380                       || (CONST_INT_P (operands[2])
7381                           && INTVAL (operands[2]) == 255));
7382           return "dec{b}\t%h0";
7383         }
7384
7385     default:
7386       return "add{b}\t{%2, %h0|%h0, %2}";
7387     }
7388 }
7389   [(set (attr "type")
7390      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7391         (const_string "incdec")
7392         (const_string "alu")))
7393    (set_attr "mode" "QI")])
7394
7395 (define_insn "*addqi_ext_1_rex64"
7396   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7397                          (const_int 8)
7398                          (const_int 8))
7399         (plus:SI
7400           (zero_extract:SI
7401             (match_operand 1 "ext_register_operand" "0")
7402             (const_int 8)
7403             (const_int 8))
7404           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7405    (clobber (reg:CC FLAGS_REG))]
7406   "TARGET_64BIT"
7407 {
7408   switch (get_attr_type (insn))
7409     {
7410     case TYPE_INCDEC:
7411       if (operands[2] == const1_rtx)
7412         return "inc{b}\t%h0";
7413       else
7414         {
7415           gcc_assert (operands[2] == constm1_rtx
7416                       || (CONST_INT_P (operands[2])
7417                           && INTVAL (operands[2]) == 255));
7418           return "dec{b}\t%h0";
7419         }
7420
7421     default:
7422       return "add{b}\t{%2, %h0|%h0, %2}";
7423     }
7424 }
7425   [(set (attr "type")
7426      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7427         (const_string "incdec")
7428         (const_string "alu")))
7429    (set_attr "mode" "QI")])
7430
7431 (define_insn "*addqi_ext_2"
7432   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7433                          (const_int 8)
7434                          (const_int 8))
7435         (plus:SI
7436           (zero_extract:SI
7437             (match_operand 1 "ext_register_operand" "%0")
7438             (const_int 8)
7439             (const_int 8))
7440           (zero_extract:SI
7441             (match_operand 2 "ext_register_operand" "Q")
7442             (const_int 8)
7443             (const_int 8))))
7444    (clobber (reg:CC FLAGS_REG))]
7445   ""
7446   "add{b}\t{%h2, %h0|%h0, %h2}"
7447   [(set_attr "type" "alu")
7448    (set_attr "mode" "QI")])
7449
7450 ;; The patterns that match these are at the end of this file.
7451
7452 (define_expand "addxf3"
7453   [(set (match_operand:XF 0 "register_operand" "")
7454         (plus:XF (match_operand:XF 1 "register_operand" "")
7455                  (match_operand:XF 2 "register_operand" "")))]
7456   "TARGET_80387"
7457   "")
7458
7459 (define_expand "add<mode>3"
7460   [(set (match_operand:MODEF 0 "register_operand" "")
7461         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7462                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7463   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7464   "")
7465 \f
7466 ;; Subtract instructions
7467
7468 ;; %%% splits for subditi3
7469
7470 (define_expand "subti3"
7471   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7472         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7473                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7474   "TARGET_64BIT"
7475   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7476
7477 (define_insn "*subti3_1"
7478   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7479         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7480                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7483   "#")
7484
7485 (define_split
7486   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7487         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7488                   (match_operand:TI 2 "x86_64_general_operand" "")))
7489    (clobber (reg:CC FLAGS_REG))]
7490   "TARGET_64BIT && reload_completed"
7491   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7492               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7493    (parallel [(set (match_dup 3)
7494                    (minus:DI (match_dup 4)
7495                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7496                                       (match_dup 5))))
7497               (clobber (reg:CC FLAGS_REG))])]
7498   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7499
7500 ;; %%% splits for subsidi3
7501
7502 (define_expand "subdi3"
7503   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7504         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7505                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7506   ""
7507   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7508
7509 (define_insn "*subdi3_1"
7510   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7511         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7512                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7513    (clobber (reg:CC FLAGS_REG))]
7514   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7515   "#")
7516
7517 (define_split
7518   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7519         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7520                   (match_operand:DI 2 "general_operand" "")))
7521    (clobber (reg:CC FLAGS_REG))]
7522   "!TARGET_64BIT && reload_completed"
7523   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7524               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7525    (parallel [(set (match_dup 3)
7526                    (minus:SI (match_dup 4)
7527                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7528                                       (match_dup 5))))
7529               (clobber (reg:CC FLAGS_REG))])]
7530   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7531
7532 (define_insn "subdi3_carry_rex64"
7533   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7534           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7535             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7536                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7539   "sbb{q}\t{%2, %0|%0, %2}"
7540   [(set_attr "type" "alu")
7541    (set_attr "pent_pair" "pu")
7542    (set_attr "mode" "DI")])
7543
7544 (define_insn "*subdi_1_rex64"
7545   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7546         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7547                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7548    (clobber (reg:CC FLAGS_REG))]
7549   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7550   "sub{q}\t{%2, %0|%0, %2}"
7551   [(set_attr "type" "alu")
7552    (set_attr "mode" "DI")])
7553
7554 (define_insn "*subdi_2_rex64"
7555   [(set (reg FLAGS_REG)
7556         (compare
7557           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7558                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7559           (const_int 0)))
7560    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7561         (minus:DI (match_dup 1) (match_dup 2)))]
7562   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7563    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7564   "sub{q}\t{%2, %0|%0, %2}"
7565   [(set_attr "type" "alu")
7566    (set_attr "mode" "DI")])
7567
7568 (define_insn "*subdi_3_rex63"
7569   [(set (reg FLAGS_REG)
7570         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7571                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7572    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7573         (minus:DI (match_dup 1) (match_dup 2)))]
7574   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7575    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7576   "sub{q}\t{%2, %0|%0, %2}"
7577   [(set_attr "type" "alu")
7578    (set_attr "mode" "DI")])
7579
7580 (define_insn "subqi3_carry"
7581   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7582           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7583             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7584                (match_operand:QI 2 "general_operand" "qn,qm"))))
7585    (clobber (reg:CC FLAGS_REG))]
7586   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7587   "sbb{b}\t{%2, %0|%0, %2}"
7588   [(set_attr "type" "alu")
7589    (set_attr "pent_pair" "pu")
7590    (set_attr "mode" "QI")])
7591
7592 (define_insn "subhi3_carry"
7593   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7594           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7595             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7596                (match_operand:HI 2 "general_operand" "rn,rm"))))
7597    (clobber (reg:CC FLAGS_REG))]
7598   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7599   "sbb{w}\t{%2, %0|%0, %2}"
7600   [(set_attr "type" "alu")
7601    (set_attr "pent_pair" "pu")
7602    (set_attr "mode" "HI")])
7603
7604 (define_insn "subsi3_carry"
7605   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7606           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7607             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7608                (match_operand:SI 2 "general_operand" "ri,rm"))))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7611   "sbb{l}\t{%2, %0|%0, %2}"
7612   [(set_attr "type" "alu")
7613    (set_attr "pent_pair" "pu")
7614    (set_attr "mode" "SI")])
7615
7616 (define_insn "subsi3_carry_zext"
7617   [(set (match_operand:DI 0 "register_operand" "=r")
7618           (zero_extend:DI
7619             (minus:SI (match_operand:SI 1 "register_operand" "0")
7620               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7621                  (match_operand:SI 2 "general_operand" "g")))))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7624   "sbb{l}\t{%2, %k0|%k0, %2}"
7625   [(set_attr "type" "alu")
7626    (set_attr "pent_pair" "pu")
7627    (set_attr "mode" "SI")])
7628
7629 (define_expand "subsi3"
7630   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7631         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7632                   (match_operand:SI 2 "general_operand" "")))]
7633   ""
7634   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7635
7636 (define_insn "*subsi_1"
7637   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7638         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7639                   (match_operand:SI 2 "general_operand" "ri,rm")))
7640    (clobber (reg:CC FLAGS_REG))]
7641   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7642   "sub{l}\t{%2, %0|%0, %2}"
7643   [(set_attr "type" "alu")
7644    (set_attr "mode" "SI")])
7645
7646 (define_insn "*subsi_1_zext"
7647   [(set (match_operand:DI 0 "register_operand" "=r")
7648         (zero_extend:DI
7649           (minus:SI (match_operand:SI 1 "register_operand" "0")
7650                     (match_operand:SI 2 "general_operand" "g"))))
7651    (clobber (reg:CC FLAGS_REG))]
7652   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7653   "sub{l}\t{%2, %k0|%k0, %2}"
7654   [(set_attr "type" "alu")
7655    (set_attr "mode" "SI")])
7656
7657 (define_insn "*subsi_2"
7658   [(set (reg FLAGS_REG)
7659         (compare
7660           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7661                     (match_operand:SI 2 "general_operand" "ri,rm"))
7662           (const_int 0)))
7663    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7664         (minus:SI (match_dup 1) (match_dup 2)))]
7665   "ix86_match_ccmode (insn, CCGOCmode)
7666    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7667   "sub{l}\t{%2, %0|%0, %2}"
7668   [(set_attr "type" "alu")
7669    (set_attr "mode" "SI")])
7670
7671 (define_insn "*subsi_2_zext"
7672   [(set (reg FLAGS_REG)
7673         (compare
7674           (minus:SI (match_operand:SI 1 "register_operand" "0")
7675                     (match_operand:SI 2 "general_operand" "g"))
7676           (const_int 0)))
7677    (set (match_operand:DI 0 "register_operand" "=r")
7678         (zero_extend:DI
7679           (minus:SI (match_dup 1)
7680                     (match_dup 2))))]
7681   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7682    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7683   "sub{l}\t{%2, %k0|%k0, %2}"
7684   [(set_attr "type" "alu")
7685    (set_attr "mode" "SI")])
7686
7687 (define_insn "*subsi_3"
7688   [(set (reg FLAGS_REG)
7689         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7690                  (match_operand:SI 2 "general_operand" "ri,rm")))
7691    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7692         (minus:SI (match_dup 1) (match_dup 2)))]
7693   "ix86_match_ccmode (insn, CCmode)
7694    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7695   "sub{l}\t{%2, %0|%0, %2}"
7696   [(set_attr "type" "alu")
7697    (set_attr "mode" "SI")])
7698
7699 (define_insn "*subsi_3_zext"
7700   [(set (reg FLAGS_REG)
7701         (compare (match_operand:SI 1 "register_operand" "0")
7702                  (match_operand:SI 2 "general_operand" "g")))
7703    (set (match_operand:DI 0 "register_operand" "=r")
7704         (zero_extend:DI
7705           (minus:SI (match_dup 1)
7706                     (match_dup 2))))]
7707   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7708    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7709   "sub{l}\t{%2, %1|%1, %2}"
7710   [(set_attr "type" "alu")
7711    (set_attr "mode" "DI")])
7712
7713 (define_expand "subhi3"
7714   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7715         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7716                   (match_operand:HI 2 "general_operand" "")))]
7717   "TARGET_HIMODE_MATH"
7718   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7719
7720 (define_insn "*subhi_1"
7721   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7722         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7723                   (match_operand:HI 2 "general_operand" "rn,rm")))
7724    (clobber (reg:CC FLAGS_REG))]
7725   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7726   "sub{w}\t{%2, %0|%0, %2}"
7727   [(set_attr "type" "alu")
7728    (set_attr "mode" "HI")])
7729
7730 (define_insn "*subhi_2"
7731   [(set (reg FLAGS_REG)
7732         (compare
7733           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7734                     (match_operand:HI 2 "general_operand" "rn,rm"))
7735           (const_int 0)))
7736    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7737         (minus:HI (match_dup 1) (match_dup 2)))]
7738   "ix86_match_ccmode (insn, CCGOCmode)
7739    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7740   "sub{w}\t{%2, %0|%0, %2}"
7741   [(set_attr "type" "alu")
7742    (set_attr "mode" "HI")])
7743
7744 (define_insn "*subhi_3"
7745   [(set (reg FLAGS_REG)
7746         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7747                  (match_operand:HI 2 "general_operand" "rn,rm")))
7748    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7749         (minus:HI (match_dup 1) (match_dup 2)))]
7750   "ix86_match_ccmode (insn, CCmode)
7751    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7752   "sub{w}\t{%2, %0|%0, %2}"
7753   [(set_attr "type" "alu")
7754    (set_attr "mode" "HI")])
7755
7756 (define_expand "subqi3"
7757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7758         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7759                   (match_operand:QI 2 "general_operand" "")))]
7760   "TARGET_QIMODE_MATH"
7761   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7762
7763 (define_insn "*subqi_1"
7764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7765         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7766                   (match_operand:QI 2 "general_operand" "qn,qm")))
7767    (clobber (reg:CC FLAGS_REG))]
7768   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7769   "sub{b}\t{%2, %0|%0, %2}"
7770   [(set_attr "type" "alu")
7771    (set_attr "mode" "QI")])
7772
7773 (define_insn "*subqi_1_slp"
7774   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7775         (minus:QI (match_dup 0)
7776                   (match_operand:QI 1 "general_operand" "qn,qm")))
7777    (clobber (reg:CC FLAGS_REG))]
7778   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7780   "sub{b}\t{%1, %0|%0, %1}"
7781   [(set_attr "type" "alu1")
7782    (set_attr "mode" "QI")])
7783
7784 (define_insn "*subqi_2"
7785   [(set (reg FLAGS_REG)
7786         (compare
7787           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7788                     (match_operand:QI 2 "general_operand" "qn,qm"))
7789           (const_int 0)))
7790    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7791         (minus:QI (match_dup 1) (match_dup 2)))]
7792   "ix86_match_ccmode (insn, CCGOCmode)
7793    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7794   "sub{b}\t{%2, %0|%0, %2}"
7795   [(set_attr "type" "alu")
7796    (set_attr "mode" "QI")])
7797
7798 (define_insn "*subqi_3"
7799   [(set (reg FLAGS_REG)
7800         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7801                  (match_operand:QI 2 "general_operand" "qn,qm")))
7802    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7803         (minus:QI (match_dup 1) (match_dup 2)))]
7804   "ix86_match_ccmode (insn, CCmode)
7805    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7806   "sub{b}\t{%2, %0|%0, %2}"
7807   [(set_attr "type" "alu")
7808    (set_attr "mode" "QI")])
7809
7810 ;; The patterns that match these are at the end of this file.
7811
7812 (define_expand "subxf3"
7813   [(set (match_operand:XF 0 "register_operand" "")
7814         (minus:XF (match_operand:XF 1 "register_operand" "")
7815                   (match_operand:XF 2 "register_operand" "")))]
7816   "TARGET_80387"
7817   "")
7818
7819 (define_expand "sub<mode>3"
7820   [(set (match_operand:MODEF 0 "register_operand" "")
7821         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7822                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7823   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7824   "")
7825 \f
7826 ;; Multiply instructions
7827
7828 (define_expand "muldi3"
7829   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7830                    (mult:DI (match_operand:DI 1 "register_operand" "")
7831                             (match_operand:DI 2 "x86_64_general_operand" "")))
7832               (clobber (reg:CC FLAGS_REG))])]
7833   "TARGET_64BIT"
7834   "")
7835
7836 ;; On AMDFAM10
7837 ;; IMUL reg64, reg64, imm8      Direct
7838 ;; IMUL reg64, mem64, imm8      VectorPath
7839 ;; IMUL reg64, reg64, imm32     Direct
7840 ;; IMUL reg64, mem64, imm32     VectorPath
7841 ;; IMUL reg64, reg64            Direct
7842 ;; IMUL reg64, mem64            Direct
7843
7844 (define_insn "*muldi3_1_rex64"
7845   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7846         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7847                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7848    (clobber (reg:CC FLAGS_REG))]
7849   "TARGET_64BIT
7850    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7851   "@
7852    imul{q}\t{%2, %1, %0|%0, %1, %2}
7853    imul{q}\t{%2, %1, %0|%0, %1, %2}
7854    imul{q}\t{%2, %0|%0, %2}"
7855   [(set_attr "type" "imul")
7856    (set_attr "prefix_0f" "0,0,1")
7857    (set (attr "athlon_decode")
7858         (cond [(eq_attr "cpu" "athlon")
7859                   (const_string "vector")
7860                (eq_attr "alternative" "1")
7861                   (const_string "vector")
7862                (and (eq_attr "alternative" "2")
7863                     (match_operand 1 "memory_operand" ""))
7864                   (const_string "vector")]
7865               (const_string "direct")))
7866    (set (attr "amdfam10_decode")
7867         (cond [(and (eq_attr "alternative" "0,1")
7868                     (match_operand 1 "memory_operand" ""))
7869                   (const_string "vector")]
7870               (const_string "direct")))
7871    (set_attr "mode" "DI")])
7872
7873 (define_expand "mulsi3"
7874   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7875                    (mult:SI (match_operand:SI 1 "register_operand" "")
7876                             (match_operand:SI 2 "general_operand" "")))
7877               (clobber (reg:CC FLAGS_REG))])]
7878   ""
7879   "")
7880
7881 ;; On AMDFAM10
7882 ;; IMUL reg32, reg32, imm8      Direct
7883 ;; IMUL reg32, mem32, imm8      VectorPath
7884 ;; IMUL reg32, reg32, imm32     Direct
7885 ;; IMUL reg32, mem32, imm32     VectorPath
7886 ;; IMUL reg32, reg32            Direct
7887 ;; IMUL reg32, mem32            Direct
7888
7889 (define_insn "*mulsi3_1"
7890   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7891         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7892                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7893    (clobber (reg:CC FLAGS_REG))]
7894   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7895   "@
7896    imul{l}\t{%2, %1, %0|%0, %1, %2}
7897    imul{l}\t{%2, %1, %0|%0, %1, %2}
7898    imul{l}\t{%2, %0|%0, %2}"
7899   [(set_attr "type" "imul")
7900    (set_attr "prefix_0f" "0,0,1")
7901    (set (attr "athlon_decode")
7902         (cond [(eq_attr "cpu" "athlon")
7903                   (const_string "vector")
7904                (eq_attr "alternative" "1")
7905                   (const_string "vector")
7906                (and (eq_attr "alternative" "2")
7907                     (match_operand 1 "memory_operand" ""))
7908                   (const_string "vector")]
7909               (const_string "direct")))
7910    (set (attr "amdfam10_decode")
7911         (cond [(and (eq_attr "alternative" "0,1")
7912                     (match_operand 1 "memory_operand" ""))
7913                   (const_string "vector")]
7914               (const_string "direct")))
7915    (set_attr "mode" "SI")])
7916
7917 (define_insn "*mulsi3_1_zext"
7918   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7919         (zero_extend:DI
7920           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7921                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7922    (clobber (reg:CC FLAGS_REG))]
7923   "TARGET_64BIT
7924    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925   "@
7926    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7928    imul{l}\t{%2, %k0|%k0, %2}"
7929   [(set_attr "type" "imul")
7930    (set_attr "prefix_0f" "0,0,1")
7931    (set (attr "athlon_decode")
7932         (cond [(eq_attr "cpu" "athlon")
7933                   (const_string "vector")
7934                (eq_attr "alternative" "1")
7935                   (const_string "vector")
7936                (and (eq_attr "alternative" "2")
7937                     (match_operand 1 "memory_operand" ""))
7938                   (const_string "vector")]
7939               (const_string "direct")))
7940    (set (attr "amdfam10_decode")
7941         (cond [(and (eq_attr "alternative" "0,1")
7942                     (match_operand 1 "memory_operand" ""))
7943                   (const_string "vector")]
7944               (const_string "direct")))
7945    (set_attr "mode" "SI")])
7946
7947 (define_expand "mulhi3"
7948   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7949                    (mult:HI (match_operand:HI 1 "register_operand" "")
7950                             (match_operand:HI 2 "general_operand" "")))
7951               (clobber (reg:CC FLAGS_REG))])]
7952   "TARGET_HIMODE_MATH"
7953   "")
7954
7955 ;; On AMDFAM10
7956 ;; IMUL reg16, reg16, imm8      VectorPath
7957 ;; IMUL reg16, mem16, imm8      VectorPath
7958 ;; IMUL reg16, reg16, imm16     VectorPath
7959 ;; IMUL reg16, mem16, imm16     VectorPath
7960 ;; IMUL reg16, reg16            Direct
7961 ;; IMUL reg16, mem16            Direct
7962 (define_insn "*mulhi3_1"
7963   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7964         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7965                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7966    (clobber (reg:CC FLAGS_REG))]
7967   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7968   "@
7969    imul{w}\t{%2, %1, %0|%0, %1, %2}
7970    imul{w}\t{%2, %1, %0|%0, %1, %2}
7971    imul{w}\t{%2, %0|%0, %2}"
7972   [(set_attr "type" "imul")
7973    (set_attr "prefix_0f" "0,0,1")
7974    (set (attr "athlon_decode")
7975         (cond [(eq_attr "cpu" "athlon")
7976                   (const_string "vector")
7977                (eq_attr "alternative" "1,2")
7978                   (const_string "vector")]
7979               (const_string "direct")))
7980    (set (attr "amdfam10_decode")
7981         (cond [(eq_attr "alternative" "0,1")
7982                   (const_string "vector")]
7983               (const_string "direct")))
7984    (set_attr "mode" "HI")])
7985
7986 (define_expand "mulqi3"
7987   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7988                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7989                             (match_operand:QI 2 "register_operand" "")))
7990               (clobber (reg:CC FLAGS_REG))])]
7991   "TARGET_QIMODE_MATH"
7992   "")
7993
7994 ;;On AMDFAM10
7995 ;; MUL reg8     Direct
7996 ;; MUL mem8     Direct
7997
7998 (define_insn "*mulqi3_1"
7999   [(set (match_operand:QI 0 "register_operand" "=a")
8000         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8001                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8002    (clobber (reg:CC FLAGS_REG))]
8003   "TARGET_QIMODE_MATH
8004    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005   "mul{b}\t%2"
8006   [(set_attr "type" "imul")
8007    (set_attr "length_immediate" "0")
8008    (set (attr "athlon_decode")
8009      (if_then_else (eq_attr "cpu" "athlon")
8010         (const_string "vector")
8011         (const_string "direct")))
8012    (set_attr "amdfam10_decode" "direct")
8013    (set_attr "mode" "QI")])
8014
8015 (define_expand "umulqihi3"
8016   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8017                    (mult:HI (zero_extend:HI
8018                               (match_operand:QI 1 "nonimmediate_operand" ""))
8019                             (zero_extend:HI
8020                               (match_operand:QI 2 "register_operand" ""))))
8021               (clobber (reg:CC FLAGS_REG))])]
8022   "TARGET_QIMODE_MATH"
8023   "")
8024
8025 (define_insn "*umulqihi3_1"
8026   [(set (match_operand:HI 0 "register_operand" "=a")
8027         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8028                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "TARGET_QIMODE_MATH
8031    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8032   "mul{b}\t%2"
8033   [(set_attr "type" "imul")
8034    (set_attr "length_immediate" "0")
8035    (set (attr "athlon_decode")
8036      (if_then_else (eq_attr "cpu" "athlon")
8037         (const_string "vector")
8038         (const_string "direct")))
8039    (set_attr "amdfam10_decode" "direct")
8040    (set_attr "mode" "QI")])
8041
8042 (define_expand "mulqihi3"
8043   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8044                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8045                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8046               (clobber (reg:CC FLAGS_REG))])]
8047   "TARGET_QIMODE_MATH"
8048   "")
8049
8050 (define_insn "*mulqihi3_insn"
8051   [(set (match_operand:HI 0 "register_operand" "=a")
8052         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8053                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8054    (clobber (reg:CC FLAGS_REG))]
8055   "TARGET_QIMODE_MATH
8056    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8057   "imul{b}\t%2"
8058   [(set_attr "type" "imul")
8059    (set_attr "length_immediate" "0")
8060    (set (attr "athlon_decode")
8061      (if_then_else (eq_attr "cpu" "athlon")
8062         (const_string "vector")
8063         (const_string "direct")))
8064    (set_attr "amdfam10_decode" "direct")
8065    (set_attr "mode" "QI")])
8066
8067 (define_expand "umulditi3"
8068   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8069                    (mult:TI (zero_extend:TI
8070                               (match_operand:DI 1 "nonimmediate_operand" ""))
8071                             (zero_extend:TI
8072                               (match_operand:DI 2 "register_operand" ""))))
8073               (clobber (reg:CC FLAGS_REG))])]
8074   "TARGET_64BIT"
8075   "")
8076
8077 (define_insn "*umulditi3_insn"
8078   [(set (match_operand:TI 0 "register_operand" "=A")
8079         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8080                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8081    (clobber (reg:CC FLAGS_REG))]
8082   "TARGET_64BIT
8083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8084   "mul{q}\t%2"
8085   [(set_attr "type" "imul")
8086    (set_attr "length_immediate" "0")
8087    (set (attr "athlon_decode")
8088      (if_then_else (eq_attr "cpu" "athlon")
8089         (const_string "vector")
8090         (const_string "double")))
8091    (set_attr "amdfam10_decode" "double")
8092    (set_attr "mode" "DI")])
8093
8094 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8095 (define_expand "umulsidi3"
8096   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8097                    (mult:DI (zero_extend:DI
8098                               (match_operand:SI 1 "nonimmediate_operand" ""))
8099                             (zero_extend:DI
8100                               (match_operand:SI 2 "register_operand" ""))))
8101               (clobber (reg:CC FLAGS_REG))])]
8102   "!TARGET_64BIT"
8103   "")
8104
8105 (define_insn "*umulsidi3_insn"
8106   [(set (match_operand:DI 0 "register_operand" "=A")
8107         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8108                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8109    (clobber (reg:CC FLAGS_REG))]
8110   "!TARGET_64BIT
8111    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8112   "mul{l}\t%2"
8113   [(set_attr "type" "imul")
8114    (set_attr "length_immediate" "0")
8115    (set (attr "athlon_decode")
8116      (if_then_else (eq_attr "cpu" "athlon")
8117         (const_string "vector")
8118         (const_string "double")))
8119    (set_attr "amdfam10_decode" "double")
8120    (set_attr "mode" "SI")])
8121
8122 (define_expand "mulditi3"
8123   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8124                    (mult:TI (sign_extend:TI
8125                               (match_operand:DI 1 "nonimmediate_operand" ""))
8126                             (sign_extend:TI
8127                               (match_operand:DI 2 "register_operand" ""))))
8128               (clobber (reg:CC FLAGS_REG))])]
8129   "TARGET_64BIT"
8130   "")
8131
8132 (define_insn "*mulditi3_insn"
8133   [(set (match_operand:TI 0 "register_operand" "=A")
8134         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8135                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "TARGET_64BIT
8138    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139   "imul{q}\t%2"
8140   [(set_attr "type" "imul")
8141    (set_attr "length_immediate" "0")
8142    (set (attr "athlon_decode")
8143      (if_then_else (eq_attr "cpu" "athlon")
8144         (const_string "vector")
8145         (const_string "double")))
8146    (set_attr "amdfam10_decode" "double")
8147    (set_attr "mode" "DI")])
8148
8149 (define_expand "mulsidi3"
8150   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8151                    (mult:DI (sign_extend:DI
8152                               (match_operand:SI 1 "nonimmediate_operand" ""))
8153                             (sign_extend:DI
8154                               (match_operand:SI 2 "register_operand" ""))))
8155               (clobber (reg:CC FLAGS_REG))])]
8156   "!TARGET_64BIT"
8157   "")
8158
8159 (define_insn "*mulsidi3_insn"
8160   [(set (match_operand:DI 0 "register_operand" "=A")
8161         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8162                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8163    (clobber (reg:CC FLAGS_REG))]
8164   "!TARGET_64BIT
8165    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8166   "imul{l}\t%2"
8167   [(set_attr "type" "imul")
8168    (set_attr "length_immediate" "0")
8169    (set (attr "athlon_decode")
8170      (if_then_else (eq_attr "cpu" "athlon")
8171         (const_string "vector")
8172         (const_string "double")))
8173    (set_attr "amdfam10_decode" "double")
8174    (set_attr "mode" "SI")])
8175
8176 (define_expand "umuldi3_highpart"
8177   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8178                    (truncate:DI
8179                      (lshiftrt:TI
8180                        (mult:TI (zero_extend:TI
8181                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8182                                 (zero_extend:TI
8183                                   (match_operand:DI 2 "register_operand" "")))
8184                        (const_int 64))))
8185               (clobber (match_scratch:DI 3 ""))
8186               (clobber (reg:CC FLAGS_REG))])]
8187   "TARGET_64BIT"
8188   "")
8189
8190 (define_insn "*umuldi3_highpart_rex64"
8191   [(set (match_operand:DI 0 "register_operand" "=d")
8192         (truncate:DI
8193           (lshiftrt:TI
8194             (mult:TI (zero_extend:TI
8195                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8196                      (zero_extend:TI
8197                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8198             (const_int 64))))
8199    (clobber (match_scratch:DI 3 "=1"))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "TARGET_64BIT
8202    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8203   "mul{q}\t%2"
8204   [(set_attr "type" "imul")
8205    (set_attr "length_immediate" "0")
8206    (set (attr "athlon_decode")
8207      (if_then_else (eq_attr "cpu" "athlon")
8208         (const_string "vector")
8209         (const_string "double")))
8210    (set_attr "amdfam10_decode" "double")
8211    (set_attr "mode" "DI")])
8212
8213 (define_expand "umulsi3_highpart"
8214   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8215                    (truncate:SI
8216                      (lshiftrt:DI
8217                        (mult:DI (zero_extend:DI
8218                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8219                                 (zero_extend:DI
8220                                   (match_operand:SI 2 "register_operand" "")))
8221                        (const_int 32))))
8222               (clobber (match_scratch:SI 3 ""))
8223               (clobber (reg:CC FLAGS_REG))])]
8224   ""
8225   "")
8226
8227 (define_insn "*umulsi3_highpart_insn"
8228   [(set (match_operand:SI 0 "register_operand" "=d")
8229         (truncate:SI
8230           (lshiftrt:DI
8231             (mult:DI (zero_extend:DI
8232                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8233                      (zero_extend:DI
8234                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8235             (const_int 32))))
8236    (clobber (match_scratch:SI 3 "=1"))
8237    (clobber (reg:CC FLAGS_REG))]
8238   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8239   "mul{l}\t%2"
8240   [(set_attr "type" "imul")
8241    (set_attr "length_immediate" "0")
8242    (set (attr "athlon_decode")
8243      (if_then_else (eq_attr "cpu" "athlon")
8244         (const_string "vector")
8245         (const_string "double")))
8246    (set_attr "amdfam10_decode" "double")
8247    (set_attr "mode" "SI")])
8248
8249 (define_insn "*umulsi3_highpart_zext"
8250   [(set (match_operand:DI 0 "register_operand" "=d")
8251         (zero_extend:DI (truncate:SI
8252           (lshiftrt:DI
8253             (mult:DI (zero_extend:DI
8254                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8255                      (zero_extend:DI
8256                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8257             (const_int 32)))))
8258    (clobber (match_scratch:SI 3 "=1"))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "TARGET_64BIT
8261    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8262   "mul{l}\t%2"
8263   [(set_attr "type" "imul")
8264    (set_attr "length_immediate" "0")
8265    (set (attr "athlon_decode")
8266      (if_then_else (eq_attr "cpu" "athlon")
8267         (const_string "vector")
8268         (const_string "double")))
8269    (set_attr "amdfam10_decode" "double")
8270    (set_attr "mode" "SI")])
8271
8272 (define_expand "smuldi3_highpart"
8273   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8274                    (truncate:DI
8275                      (lshiftrt:TI
8276                        (mult:TI (sign_extend:TI
8277                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8278                                 (sign_extend:TI
8279                                   (match_operand:DI 2 "register_operand" "")))
8280                        (const_int 64))))
8281               (clobber (match_scratch:DI 3 ""))
8282               (clobber (reg:CC FLAGS_REG))])]
8283   "TARGET_64BIT"
8284   "")
8285
8286 (define_insn "*smuldi3_highpart_rex64"
8287   [(set (match_operand:DI 0 "register_operand" "=d")
8288         (truncate:DI
8289           (lshiftrt:TI
8290             (mult:TI (sign_extend:TI
8291                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8292                      (sign_extend:TI
8293                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8294             (const_int 64))))
8295    (clobber (match_scratch:DI 3 "=1"))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "TARGET_64BIT
8298    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299   "imul{q}\t%2"
8300   [(set_attr "type" "imul")
8301    (set (attr "athlon_decode")
8302      (if_then_else (eq_attr "cpu" "athlon")
8303         (const_string "vector")
8304         (const_string "double")))
8305    (set_attr "amdfam10_decode" "double")
8306    (set_attr "mode" "DI")])
8307
8308 (define_expand "smulsi3_highpart"
8309   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8310                    (truncate:SI
8311                      (lshiftrt:DI
8312                        (mult:DI (sign_extend:DI
8313                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8314                                 (sign_extend:DI
8315                                   (match_operand:SI 2 "register_operand" "")))
8316                        (const_int 32))))
8317               (clobber (match_scratch:SI 3 ""))
8318               (clobber (reg:CC FLAGS_REG))])]
8319   ""
8320   "")
8321
8322 (define_insn "*smulsi3_highpart_insn"
8323   [(set (match_operand:SI 0 "register_operand" "=d")
8324         (truncate:SI
8325           (lshiftrt:DI
8326             (mult:DI (sign_extend:DI
8327                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8328                      (sign_extend:DI
8329                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8330             (const_int 32))))
8331    (clobber (match_scratch:SI 3 "=1"))
8332    (clobber (reg:CC FLAGS_REG))]
8333   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8334   "imul{l}\t%2"
8335   [(set_attr "type" "imul")
8336    (set (attr "athlon_decode")
8337      (if_then_else (eq_attr "cpu" "athlon")
8338         (const_string "vector")
8339         (const_string "double")))
8340    (set_attr "amdfam10_decode" "double")
8341    (set_attr "mode" "SI")])
8342
8343 (define_insn "*smulsi3_highpart_zext"
8344   [(set (match_operand:DI 0 "register_operand" "=d")
8345         (zero_extend:DI (truncate:SI
8346           (lshiftrt:DI
8347             (mult:DI (sign_extend:DI
8348                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8349                      (sign_extend:DI
8350                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8351             (const_int 32)))))
8352    (clobber (match_scratch:SI 3 "=1"))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "TARGET_64BIT
8355    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8356   "imul{l}\t%2"
8357   [(set_attr "type" "imul")
8358    (set (attr "athlon_decode")
8359      (if_then_else (eq_attr "cpu" "athlon")
8360         (const_string "vector")
8361         (const_string "double")))
8362    (set_attr "amdfam10_decode" "double")
8363    (set_attr "mode" "SI")])
8364
8365 ;; The patterns that match these are at the end of this file.
8366
8367 (define_expand "mulxf3"
8368   [(set (match_operand:XF 0 "register_operand" "")
8369         (mult:XF (match_operand:XF 1 "register_operand" "")
8370                  (match_operand:XF 2 "register_operand" "")))]
8371   "TARGET_80387"
8372   "")
8373
8374 (define_expand "mul<mode>3"
8375   [(set (match_operand:MODEF 0 "register_operand" "")
8376         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8377                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8378   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8379   "")
8380
8381 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8382
8383 \f
8384 ;; Divide instructions
8385
8386 (define_insn "divqi3"
8387   [(set (match_operand:QI 0 "register_operand" "=a")
8388         (div:QI (match_operand:HI 1 "register_operand" "0")
8389                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "TARGET_QIMODE_MATH"
8392   "idiv{b}\t%2"
8393   [(set_attr "type" "idiv")
8394    (set_attr "mode" "QI")])
8395
8396 (define_insn "udivqi3"
8397   [(set (match_operand:QI 0 "register_operand" "=a")
8398         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8399                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8400    (clobber (reg:CC FLAGS_REG))]
8401   "TARGET_QIMODE_MATH"
8402   "div{b}\t%2"
8403   [(set_attr "type" "idiv")
8404    (set_attr "mode" "QI")])
8405
8406 ;; The patterns that match these are at the end of this file.
8407
8408 (define_expand "divxf3"
8409   [(set (match_operand:XF 0 "register_operand" "")
8410         (div:XF (match_operand:XF 1 "register_operand" "")
8411                 (match_operand:XF 2 "register_operand" "")))]
8412   "TARGET_80387"
8413   "")
8414
8415 (define_expand "divdf3"
8416   [(set (match_operand:DF 0 "register_operand" "")
8417         (div:DF (match_operand:DF 1 "register_operand" "")
8418                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8419    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8420    "")
8421
8422 (define_expand "divsf3"
8423   [(set (match_operand:SF 0 "register_operand" "")
8424         (div:SF (match_operand:SF 1 "register_operand" "")
8425                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8426   "TARGET_80387 || TARGET_SSE_MATH"
8427 {
8428   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8429       && flag_finite_math_only && !flag_trapping_math
8430       && flag_unsafe_math_optimizations)
8431     {
8432       ix86_emit_swdivsf (operands[0], operands[1],
8433                          operands[2], SFmode);
8434       DONE;
8435     }
8436 })
8437 \f
8438 ;; Remainder instructions.
8439
8440 (define_expand "divmoddi4"
8441   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8442                    (div:DI (match_operand:DI 1 "register_operand" "")
8443                            (match_operand:DI 2 "nonimmediate_operand" "")))
8444               (set (match_operand:DI 3 "register_operand" "")
8445                    (mod:DI (match_dup 1) (match_dup 2)))
8446               (clobber (reg:CC FLAGS_REG))])]
8447   "TARGET_64BIT"
8448   "")
8449
8450 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8451 ;; Penalize eax case slightly because it results in worse scheduling
8452 ;; of code.
8453 (define_insn "*divmoddi4_nocltd_rex64"
8454   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8455         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8456                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8457    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8458         (mod:DI (match_dup 2) (match_dup 3)))
8459    (clobber (reg:CC FLAGS_REG))]
8460   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8461   "#"
8462   [(set_attr "type" "multi")])
8463
8464 (define_insn "*divmoddi4_cltd_rex64"
8465   [(set (match_operand:DI 0 "register_operand" "=a")
8466         (div:DI (match_operand:DI 2 "register_operand" "a")
8467                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8468    (set (match_operand:DI 1 "register_operand" "=&d")
8469         (mod:DI (match_dup 2) (match_dup 3)))
8470    (clobber (reg:CC FLAGS_REG))]
8471   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8472   "#"
8473   [(set_attr "type" "multi")])
8474
8475 (define_insn "*divmoddi_noext_rex64"
8476   [(set (match_operand:DI 0 "register_operand" "=a")
8477         (div:DI (match_operand:DI 1 "register_operand" "0")
8478                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8479    (set (match_operand:DI 3 "register_operand" "=d")
8480         (mod:DI (match_dup 1) (match_dup 2)))
8481    (use (match_operand:DI 4 "register_operand" "3"))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "TARGET_64BIT"
8484   "idiv{q}\t%2"
8485   [(set_attr "type" "idiv")
8486    (set_attr "mode" "DI")])
8487
8488 (define_split
8489   [(set (match_operand:DI 0 "register_operand" "")
8490         (div:DI (match_operand:DI 1 "register_operand" "")
8491                 (match_operand:DI 2 "nonimmediate_operand" "")))
8492    (set (match_operand:DI 3 "register_operand" "")
8493         (mod:DI (match_dup 1) (match_dup 2)))
8494    (clobber (reg:CC FLAGS_REG))]
8495   "TARGET_64BIT && reload_completed"
8496   [(parallel [(set (match_dup 3)
8497                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8498               (clobber (reg:CC FLAGS_REG))])
8499    (parallel [(set (match_dup 0)
8500                    (div:DI (reg:DI 0) (match_dup 2)))
8501               (set (match_dup 3)
8502                    (mod:DI (reg:DI 0) (match_dup 2)))
8503               (use (match_dup 3))
8504               (clobber (reg:CC FLAGS_REG))])]
8505 {
8506   /* Avoid use of cltd in favor of a mov+shift.  */
8507   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8508     {
8509       if (true_regnum (operands[1]))
8510         emit_move_insn (operands[0], operands[1]);
8511       else
8512         emit_move_insn (operands[3], operands[1]);
8513       operands[4] = operands[3];
8514     }
8515   else
8516     {
8517       gcc_assert (!true_regnum (operands[1]));
8518       operands[4] = operands[1];
8519     }
8520 })
8521
8522
8523 (define_expand "divmodsi4"
8524   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8525                    (div:SI (match_operand:SI 1 "register_operand" "")
8526                            (match_operand:SI 2 "nonimmediate_operand" "")))
8527               (set (match_operand:SI 3 "register_operand" "")
8528                    (mod:SI (match_dup 1) (match_dup 2)))
8529               (clobber (reg:CC FLAGS_REG))])]
8530   ""
8531   "")
8532
8533 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8534 ;; Penalize eax case slightly because it results in worse scheduling
8535 ;; of code.
8536 (define_insn "*divmodsi4_nocltd"
8537   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8538         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8539                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8540    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8541         (mod:SI (match_dup 2) (match_dup 3)))
8542    (clobber (reg:CC FLAGS_REG))]
8543   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8544   "#"
8545   [(set_attr "type" "multi")])
8546
8547 (define_insn "*divmodsi4_cltd"
8548   [(set (match_operand:SI 0 "register_operand" "=a")
8549         (div:SI (match_operand:SI 2 "register_operand" "a")
8550                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8551    (set (match_operand:SI 1 "register_operand" "=&d")
8552         (mod:SI (match_dup 2) (match_dup 3)))
8553    (clobber (reg:CC FLAGS_REG))]
8554   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8555   "#"
8556   [(set_attr "type" "multi")])
8557
8558 (define_insn "*divmodsi_noext"
8559   [(set (match_operand:SI 0 "register_operand" "=a")
8560         (div:SI (match_operand:SI 1 "register_operand" "0")
8561                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8562    (set (match_operand:SI 3 "register_operand" "=d")
8563         (mod:SI (match_dup 1) (match_dup 2)))
8564    (use (match_operand:SI 4 "register_operand" "3"))
8565    (clobber (reg:CC FLAGS_REG))]
8566   ""
8567   "idiv{l}\t%2"
8568   [(set_attr "type" "idiv")
8569    (set_attr "mode" "SI")])
8570
8571 (define_split
8572   [(set (match_operand:SI 0 "register_operand" "")
8573         (div:SI (match_operand:SI 1 "register_operand" "")
8574                 (match_operand:SI 2 "nonimmediate_operand" "")))
8575    (set (match_operand:SI 3 "register_operand" "")
8576         (mod:SI (match_dup 1) (match_dup 2)))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "reload_completed"
8579   [(parallel [(set (match_dup 3)
8580                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8581               (clobber (reg:CC FLAGS_REG))])
8582    (parallel [(set (match_dup 0)
8583                    (div:SI (reg:SI 0) (match_dup 2)))
8584               (set (match_dup 3)
8585                    (mod:SI (reg:SI 0) (match_dup 2)))
8586               (use (match_dup 3))
8587               (clobber (reg:CC FLAGS_REG))])]
8588 {
8589   /* Avoid use of cltd in favor of a mov+shift.  */
8590   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8591     {
8592       if (true_regnum (operands[1]))
8593         emit_move_insn (operands[0], operands[1]);
8594       else
8595         emit_move_insn (operands[3], operands[1]);
8596       operands[4] = operands[3];
8597     }
8598   else
8599     {
8600       gcc_assert (!true_regnum (operands[1]));
8601       operands[4] = operands[1];
8602     }
8603 })
8604 ;; %%% Split me.
8605 (define_insn "divmodhi4"
8606   [(set (match_operand:HI 0 "register_operand" "=a")
8607         (div:HI (match_operand:HI 1 "register_operand" "0")
8608                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8609    (set (match_operand:HI 3 "register_operand" "=&d")
8610         (mod:HI (match_dup 1) (match_dup 2)))
8611    (clobber (reg:CC FLAGS_REG))]
8612   "TARGET_HIMODE_MATH"
8613   "cwtd\;idiv{w}\t%2"
8614   [(set_attr "type" "multi")
8615    (set_attr "length_immediate" "0")
8616    (set_attr "mode" "SI")])
8617
8618 (define_insn "udivmoddi4"
8619   [(set (match_operand:DI 0 "register_operand" "=a")
8620         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8621                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8622    (set (match_operand:DI 3 "register_operand" "=&d")
8623         (umod:DI (match_dup 1) (match_dup 2)))
8624    (clobber (reg:CC FLAGS_REG))]
8625   "TARGET_64BIT"
8626   "xor{q}\t%3, %3\;div{q}\t%2"
8627   [(set_attr "type" "multi")
8628    (set_attr "length_immediate" "0")
8629    (set_attr "mode" "DI")])
8630
8631 (define_insn "*udivmoddi4_noext"
8632   [(set (match_operand:DI 0 "register_operand" "=a")
8633         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8634                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8635    (set (match_operand:DI 3 "register_operand" "=d")
8636         (umod:DI (match_dup 1) (match_dup 2)))
8637    (use (match_dup 3))
8638    (clobber (reg:CC FLAGS_REG))]
8639   "TARGET_64BIT"
8640   "div{q}\t%2"
8641   [(set_attr "type" "idiv")
8642    (set_attr "mode" "DI")])
8643
8644 (define_split
8645   [(set (match_operand:DI 0 "register_operand" "")
8646         (udiv:DI (match_operand:DI 1 "register_operand" "")
8647                  (match_operand:DI 2 "nonimmediate_operand" "")))
8648    (set (match_operand:DI 3 "register_operand" "")
8649         (umod:DI (match_dup 1) (match_dup 2)))
8650    (clobber (reg:CC FLAGS_REG))]
8651   "TARGET_64BIT && reload_completed"
8652   [(set (match_dup 3) (const_int 0))
8653    (parallel [(set (match_dup 0)
8654                    (udiv:DI (match_dup 1) (match_dup 2)))
8655               (set (match_dup 3)
8656                    (umod:DI (match_dup 1) (match_dup 2)))
8657               (use (match_dup 3))
8658               (clobber (reg:CC FLAGS_REG))])]
8659   "")
8660
8661 (define_insn "udivmodsi4"
8662   [(set (match_operand:SI 0 "register_operand" "=a")
8663         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8664                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8665    (set (match_operand:SI 3 "register_operand" "=&d")
8666         (umod:SI (match_dup 1) (match_dup 2)))
8667    (clobber (reg:CC FLAGS_REG))]
8668   ""
8669   "xor{l}\t%3, %3\;div{l}\t%2"
8670   [(set_attr "type" "multi")
8671    (set_attr "length_immediate" "0")
8672    (set_attr "mode" "SI")])
8673
8674 (define_insn "*udivmodsi4_noext"
8675   [(set (match_operand:SI 0 "register_operand" "=a")
8676         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8677                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8678    (set (match_operand:SI 3 "register_operand" "=d")
8679         (umod:SI (match_dup 1) (match_dup 2)))
8680    (use (match_dup 3))
8681    (clobber (reg:CC FLAGS_REG))]
8682   ""
8683   "div{l}\t%2"
8684   [(set_attr "type" "idiv")
8685    (set_attr "mode" "SI")])
8686
8687 (define_split
8688   [(set (match_operand:SI 0 "register_operand" "")
8689         (udiv:SI (match_operand:SI 1 "register_operand" "")
8690                  (match_operand:SI 2 "nonimmediate_operand" "")))
8691    (set (match_operand:SI 3 "register_operand" "")
8692         (umod:SI (match_dup 1) (match_dup 2)))
8693    (clobber (reg:CC FLAGS_REG))]
8694   "reload_completed"
8695   [(set (match_dup 3) (const_int 0))
8696    (parallel [(set (match_dup 0)
8697                    (udiv:SI (match_dup 1) (match_dup 2)))
8698               (set (match_dup 3)
8699                    (umod:SI (match_dup 1) (match_dup 2)))
8700               (use (match_dup 3))
8701               (clobber (reg:CC FLAGS_REG))])]
8702   "")
8703
8704 (define_expand "udivmodhi4"
8705   [(set (match_dup 4) (const_int 0))
8706    (parallel [(set (match_operand:HI 0 "register_operand" "")
8707                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8708                             (match_operand:HI 2 "nonimmediate_operand" "")))
8709               (set (match_operand:HI 3 "register_operand" "")
8710                    (umod:HI (match_dup 1) (match_dup 2)))
8711               (use (match_dup 4))
8712               (clobber (reg:CC FLAGS_REG))])]
8713   "TARGET_HIMODE_MATH"
8714   "operands[4] = gen_reg_rtx (HImode);")
8715
8716 (define_insn "*udivmodhi_noext"
8717   [(set (match_operand:HI 0 "register_operand" "=a")
8718         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8719                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8720    (set (match_operand:HI 3 "register_operand" "=d")
8721         (umod:HI (match_dup 1) (match_dup 2)))
8722    (use (match_operand:HI 4 "register_operand" "3"))
8723    (clobber (reg:CC FLAGS_REG))]
8724   ""
8725   "div{w}\t%2"
8726   [(set_attr "type" "idiv")
8727    (set_attr "mode" "HI")])
8728
8729 ;; We cannot use div/idiv for double division, because it causes
8730 ;; "division by zero" on the overflow and that's not what we expect
8731 ;; from truncate.  Because true (non truncating) double division is
8732 ;; never generated, we can't create this insn anyway.
8733 ;
8734 ;(define_insn ""
8735 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8736 ;       (truncate:SI
8737 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8738 ;                  (zero_extend:DI
8739 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8740 ;   (set (match_operand:SI 3 "register_operand" "=d")
8741 ;       (truncate:SI
8742 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8743 ;   (clobber (reg:CC FLAGS_REG))]
8744 ;  ""
8745 ;  "div{l}\t{%2, %0|%0, %2}"
8746 ;  [(set_attr "type" "idiv")])
8747 \f
8748 ;;- Logical AND instructions
8749
8750 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8751 ;; Note that this excludes ah.
8752
8753 (define_insn "*testdi_1_rex64"
8754   [(set (reg FLAGS_REG)
8755         (compare
8756           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8757                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8758           (const_int 0)))]
8759   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8760    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8761   "@
8762    test{l}\t{%k1, %k0|%k0, %k1}
8763    test{l}\t{%k1, %k0|%k0, %k1}
8764    test{q}\t{%1, %0|%0, %1}
8765    test{q}\t{%1, %0|%0, %1}
8766    test{q}\t{%1, %0|%0, %1}"
8767   [(set_attr "type" "test")
8768    (set_attr "modrm" "0,1,0,1,1")
8769    (set_attr "mode" "SI,SI,DI,DI,DI")
8770    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8771
8772 (define_insn "testsi_1"
8773   [(set (reg FLAGS_REG)
8774         (compare
8775           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8776                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8777           (const_int 0)))]
8778   "ix86_match_ccmode (insn, CCNOmode)
8779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8780   "test{l}\t{%1, %0|%0, %1}"
8781   [(set_attr "type" "test")
8782    (set_attr "modrm" "0,1,1")
8783    (set_attr "mode" "SI")
8784    (set_attr "pent_pair" "uv,np,uv")])
8785
8786 (define_expand "testsi_ccno_1"
8787   [(set (reg:CCNO FLAGS_REG)
8788         (compare:CCNO
8789           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8790                   (match_operand:SI 1 "nonmemory_operand" ""))
8791           (const_int 0)))]
8792   ""
8793   "")
8794
8795 (define_insn "*testhi_1"
8796   [(set (reg FLAGS_REG)
8797         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8798                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8799                  (const_int 0)))]
8800   "ix86_match_ccmode (insn, CCNOmode)
8801    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8802   "test{w}\t{%1, %0|%0, %1}"
8803   [(set_attr "type" "test")
8804    (set_attr "modrm" "0,1,1")
8805    (set_attr "mode" "HI")
8806    (set_attr "pent_pair" "uv,np,uv")])
8807
8808 (define_expand "testqi_ccz_1"
8809   [(set (reg:CCZ FLAGS_REG)
8810         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8811                              (match_operand:QI 1 "nonmemory_operand" ""))
8812                  (const_int 0)))]
8813   ""
8814   "")
8815
8816 (define_insn "*testqi_1_maybe_si"
8817   [(set (reg FLAGS_REG)
8818         (compare
8819           (and:QI
8820             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8821             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8822           (const_int 0)))]
8823    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8824     && ix86_match_ccmode (insn,
8825                          CONST_INT_P (operands[1])
8826                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8827 {
8828   if (which_alternative == 3)
8829     {
8830       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8831         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8832       return "test{l}\t{%1, %k0|%k0, %1}";
8833     }
8834   return "test{b}\t{%1, %0|%0, %1}";
8835 }
8836   [(set_attr "type" "test")
8837    (set_attr "modrm" "0,1,1,1")
8838    (set_attr "mode" "QI,QI,QI,SI")
8839    (set_attr "pent_pair" "uv,np,uv,np")])
8840
8841 (define_insn "*testqi_1"
8842   [(set (reg FLAGS_REG)
8843         (compare
8844           (and:QI
8845             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8846             (match_operand:QI 1 "general_operand" "n,n,qn"))
8847           (const_int 0)))]
8848   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8849    && ix86_match_ccmode (insn, CCNOmode)"
8850   "test{b}\t{%1, %0|%0, %1}"
8851   [(set_attr "type" "test")
8852    (set_attr "modrm" "0,1,1")
8853    (set_attr "mode" "QI")
8854    (set_attr "pent_pair" "uv,np,uv")])
8855
8856 (define_expand "testqi_ext_ccno_0"
8857   [(set (reg:CCNO FLAGS_REG)
8858         (compare:CCNO
8859           (and:SI
8860             (zero_extract:SI
8861               (match_operand 0 "ext_register_operand" "")
8862               (const_int 8)
8863               (const_int 8))
8864             (match_operand 1 "const_int_operand" ""))
8865           (const_int 0)))]
8866   ""
8867   "")
8868
8869 (define_insn "*testqi_ext_0"
8870   [(set (reg FLAGS_REG)
8871         (compare
8872           (and:SI
8873             (zero_extract:SI
8874               (match_operand 0 "ext_register_operand" "Q")
8875               (const_int 8)
8876               (const_int 8))
8877             (match_operand 1 "const_int_operand" "n"))
8878           (const_int 0)))]
8879   "ix86_match_ccmode (insn, CCNOmode)"
8880   "test{b}\t{%1, %h0|%h0, %1}"
8881   [(set_attr "type" "test")
8882    (set_attr "mode" "QI")
8883    (set_attr "length_immediate" "1")
8884    (set_attr "pent_pair" "np")])
8885
8886 (define_insn "*testqi_ext_1"
8887   [(set (reg FLAGS_REG)
8888         (compare
8889           (and:SI
8890             (zero_extract:SI
8891               (match_operand 0 "ext_register_operand" "Q")
8892               (const_int 8)
8893               (const_int 8))
8894             (zero_extend:SI
8895               (match_operand:QI 1 "general_operand" "Qm")))
8896           (const_int 0)))]
8897   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8898    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8899   "test{b}\t{%1, %h0|%h0, %1}"
8900   [(set_attr "type" "test")
8901    (set_attr "mode" "QI")])
8902
8903 (define_insn "*testqi_ext_1_rex64"
8904   [(set (reg FLAGS_REG)
8905         (compare
8906           (and:SI
8907             (zero_extract:SI
8908               (match_operand 0 "ext_register_operand" "Q")
8909               (const_int 8)
8910               (const_int 8))
8911             (zero_extend:SI
8912               (match_operand:QI 1 "register_operand" "Q")))
8913           (const_int 0)))]
8914   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8915   "test{b}\t{%1, %h0|%h0, %1}"
8916   [(set_attr "type" "test")
8917    (set_attr "mode" "QI")])
8918
8919 (define_insn "*testqi_ext_2"
8920   [(set (reg FLAGS_REG)
8921         (compare
8922           (and:SI
8923             (zero_extract:SI
8924               (match_operand 0 "ext_register_operand" "Q")
8925               (const_int 8)
8926               (const_int 8))
8927             (zero_extract:SI
8928               (match_operand 1 "ext_register_operand" "Q")
8929               (const_int 8)
8930               (const_int 8)))
8931           (const_int 0)))]
8932   "ix86_match_ccmode (insn, CCNOmode)"
8933   "test{b}\t{%h1, %h0|%h0, %h1}"
8934   [(set_attr "type" "test")
8935    (set_attr "mode" "QI")])
8936
8937 ;; Combine likes to form bit extractions for some tests.  Humor it.
8938 (define_insn "*testqi_ext_3"
8939   [(set (reg FLAGS_REG)
8940         (compare (zero_extract:SI
8941                    (match_operand 0 "nonimmediate_operand" "rm")
8942                    (match_operand:SI 1 "const_int_operand" "")
8943                    (match_operand:SI 2 "const_int_operand" ""))
8944                  (const_int 0)))]
8945   "ix86_match_ccmode (insn, CCNOmode)
8946    && INTVAL (operands[1]) > 0
8947    && INTVAL (operands[2]) >= 0
8948    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8949    && (GET_MODE (operands[0]) == SImode
8950        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8951        || GET_MODE (operands[0]) == HImode
8952        || GET_MODE (operands[0]) == QImode)"
8953   "#")
8954
8955 (define_insn "*testqi_ext_3_rex64"
8956   [(set (reg FLAGS_REG)
8957         (compare (zero_extract:DI
8958                    (match_operand 0 "nonimmediate_operand" "rm")
8959                    (match_operand:DI 1 "const_int_operand" "")
8960                    (match_operand:DI 2 "const_int_operand" ""))
8961                  (const_int 0)))]
8962   "TARGET_64BIT
8963    && ix86_match_ccmode (insn, CCNOmode)
8964    && INTVAL (operands[1]) > 0
8965    && INTVAL (operands[2]) >= 0
8966    /* Ensure that resulting mask is zero or sign extended operand.  */
8967    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8968        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8969            && INTVAL (operands[1]) > 32))
8970    && (GET_MODE (operands[0]) == SImode
8971        || GET_MODE (operands[0]) == DImode
8972        || GET_MODE (operands[0]) == HImode
8973        || GET_MODE (operands[0]) == QImode)"
8974   "#")
8975
8976 (define_split
8977   [(set (match_operand 0 "flags_reg_operand" "")
8978         (match_operator 1 "compare_operator"
8979           [(zero_extract
8980              (match_operand 2 "nonimmediate_operand" "")
8981              (match_operand 3 "const_int_operand" "")
8982              (match_operand 4 "const_int_operand" ""))
8983            (const_int 0)]))]
8984   "ix86_match_ccmode (insn, CCNOmode)"
8985   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8986 {
8987   rtx val = operands[2];
8988   HOST_WIDE_INT len = INTVAL (operands[3]);
8989   HOST_WIDE_INT pos = INTVAL (operands[4]);
8990   HOST_WIDE_INT mask;
8991   enum machine_mode mode, submode;
8992
8993   mode = GET_MODE (val);
8994   if (MEM_P (val))
8995     {
8996       /* ??? Combine likes to put non-volatile mem extractions in QImode
8997          no matter the size of the test.  So find a mode that works.  */
8998       if (! MEM_VOLATILE_P (val))
8999         {
9000           mode = smallest_mode_for_size (pos + len, MODE_INT);
9001           val = adjust_address (val, mode, 0);
9002         }
9003     }
9004   else if (GET_CODE (val) == SUBREG
9005            && (submode = GET_MODE (SUBREG_REG (val)),
9006                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9007            && pos + len <= GET_MODE_BITSIZE (submode))
9008     {
9009       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9010       mode = submode;
9011       val = SUBREG_REG (val);
9012     }
9013   else if (mode == HImode && pos + len <= 8)
9014     {
9015       /* Small HImode tests can be converted to QImode.  */
9016       mode = QImode;
9017       val = gen_lowpart (QImode, val);
9018     }
9019
9020   if (len == HOST_BITS_PER_WIDE_INT)
9021     mask = -1;
9022   else
9023     mask = ((HOST_WIDE_INT)1 << len) - 1;
9024   mask <<= pos;
9025
9026   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9027 })
9028
9029 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9030 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9031 ;; this is relatively important trick.
9032 ;; Do the conversion only post-reload to avoid limiting of the register class
9033 ;; to QI regs.
9034 (define_split
9035   [(set (match_operand 0 "flags_reg_operand" "")
9036         (match_operator 1 "compare_operator"
9037           [(and (match_operand 2 "register_operand" "")
9038                 (match_operand 3 "const_int_operand" ""))
9039            (const_int 0)]))]
9040    "reload_completed
9041     && QI_REG_P (operands[2])
9042     && GET_MODE (operands[2]) != QImode
9043     && ((ix86_match_ccmode (insn, CCZmode)
9044          && !(INTVAL (operands[3]) & ~(255 << 8)))
9045         || (ix86_match_ccmode (insn, CCNOmode)
9046             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9047   [(set (match_dup 0)
9048         (match_op_dup 1
9049           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9050                    (match_dup 3))
9051            (const_int 0)]))]
9052   "operands[2] = gen_lowpart (SImode, operands[2]);
9053    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9054
9055 (define_split
9056   [(set (match_operand 0 "flags_reg_operand" "")
9057         (match_operator 1 "compare_operator"
9058           [(and (match_operand 2 "nonimmediate_operand" "")
9059                 (match_operand 3 "const_int_operand" ""))
9060            (const_int 0)]))]
9061    "reload_completed
9062     && GET_MODE (operands[2]) != QImode
9063     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9064     && ((ix86_match_ccmode (insn, CCZmode)
9065          && !(INTVAL (operands[3]) & ~255))
9066         || (ix86_match_ccmode (insn, CCNOmode)
9067             && !(INTVAL (operands[3]) & ~127)))"
9068   [(set (match_dup 0)
9069         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9070                          (const_int 0)]))]
9071   "operands[2] = gen_lowpart (QImode, operands[2]);
9072    operands[3] = gen_lowpart (QImode, operands[3]);")
9073
9074
9075 ;; %%% This used to optimize known byte-wide and operations to memory,
9076 ;; and sometimes to QImode registers.  If this is considered useful,
9077 ;; it should be done with splitters.
9078
9079 (define_expand "anddi3"
9080   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9081         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9082                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9083   "TARGET_64BIT"
9084   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9085
9086 (define_insn "*anddi_1_rex64"
9087   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9088         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9089                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9092 {
9093   switch (get_attr_type (insn))
9094     {
9095     case TYPE_IMOVX:
9096       {
9097         enum machine_mode mode;
9098
9099         gcc_assert (CONST_INT_P (operands[2]));
9100         if (INTVAL (operands[2]) == 0xff)
9101           mode = QImode;
9102         else
9103           {
9104             gcc_assert (INTVAL (operands[2]) == 0xffff);
9105             mode = HImode;
9106           }
9107
9108         operands[1] = gen_lowpart (mode, operands[1]);
9109         if (mode == QImode)
9110           return "movz{bq|x}\t{%1,%0|%0, %1}";
9111         else
9112           return "movz{wq|x}\t{%1,%0|%0, %1}";
9113       }
9114
9115     default:
9116       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9117       if (get_attr_mode (insn) == MODE_SI)
9118         return "and{l}\t{%k2, %k0|%k0, %k2}";
9119       else
9120         return "and{q}\t{%2, %0|%0, %2}";
9121     }
9122 }
9123   [(set_attr "type" "alu,alu,alu,imovx")
9124    (set_attr "length_immediate" "*,*,*,0")
9125    (set_attr "mode" "SI,DI,DI,DI")])
9126
9127 (define_insn "*anddi_2"
9128   [(set (reg FLAGS_REG)
9129         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9130                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9131                  (const_int 0)))
9132    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9133         (and:DI (match_dup 1) (match_dup 2)))]
9134   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9135    && ix86_binary_operator_ok (AND, DImode, operands)"
9136   "@
9137    and{l}\t{%k2, %k0|%k0, %k2}
9138    and{q}\t{%2, %0|%0, %2}
9139    and{q}\t{%2, %0|%0, %2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "mode" "SI,DI,DI")])
9142
9143 (define_expand "andsi3"
9144   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9145         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9146                 (match_operand:SI 2 "general_operand" "")))]
9147   ""
9148   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9149
9150 (define_insn "*andsi_1"
9151   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9152         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9153                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9154    (clobber (reg:CC FLAGS_REG))]
9155   "ix86_binary_operator_ok (AND, SImode, operands)"
9156 {
9157   switch (get_attr_type (insn))
9158     {
9159     case TYPE_IMOVX:
9160       {
9161         enum machine_mode mode;
9162
9163         gcc_assert (CONST_INT_P (operands[2]));
9164         if (INTVAL (operands[2]) == 0xff)
9165           mode = QImode;
9166         else
9167           {
9168             gcc_assert (INTVAL (operands[2]) == 0xffff);
9169             mode = HImode;
9170           }
9171
9172         operands[1] = gen_lowpart (mode, operands[1]);
9173         if (mode == QImode)
9174           return "movz{bl|x}\t{%1,%0|%0, %1}";
9175         else
9176           return "movz{wl|x}\t{%1,%0|%0, %1}";
9177       }
9178
9179     default:
9180       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9181       return "and{l}\t{%2, %0|%0, %2}";
9182     }
9183 }
9184   [(set_attr "type" "alu,alu,imovx")
9185    (set_attr "length_immediate" "*,*,0")
9186    (set_attr "mode" "SI")])
9187
9188 (define_split
9189   [(set (match_operand 0 "register_operand" "")
9190         (and (match_dup 0)
9191              (const_int -65536)))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9194   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9195   "operands[1] = gen_lowpart (HImode, operands[0]);")
9196
9197 (define_split
9198   [(set (match_operand 0 "ext_register_operand" "")
9199         (and (match_dup 0)
9200              (const_int -256)))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9203   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9204   "operands[1] = gen_lowpart (QImode, operands[0]);")
9205
9206 (define_split
9207   [(set (match_operand 0 "ext_register_operand" "")
9208         (and (match_dup 0)
9209              (const_int -65281)))
9210    (clobber (reg:CC FLAGS_REG))]
9211   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9212   [(parallel [(set (zero_extract:SI (match_dup 0)
9213                                     (const_int 8)
9214                                     (const_int 8))
9215                    (xor:SI
9216                      (zero_extract:SI (match_dup 0)
9217                                       (const_int 8)
9218                                       (const_int 8))
9219                      (zero_extract:SI (match_dup 0)
9220                                       (const_int 8)
9221                                       (const_int 8))))
9222               (clobber (reg:CC FLAGS_REG))])]
9223   "operands[0] = gen_lowpart (SImode, operands[0]);")
9224
9225 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9226 (define_insn "*andsi_1_zext"
9227   [(set (match_operand:DI 0 "register_operand" "=r")
9228         (zero_extend:DI
9229           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9230                   (match_operand:SI 2 "general_operand" "g"))))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9233   "and{l}\t{%2, %k0|%k0, %2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "mode" "SI")])
9236
9237 (define_insn "*andsi_2"
9238   [(set (reg FLAGS_REG)
9239         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9240                          (match_operand:SI 2 "general_operand" "g,ri"))
9241                  (const_int 0)))
9242    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9243         (and:SI (match_dup 1) (match_dup 2)))]
9244   "ix86_match_ccmode (insn, CCNOmode)
9245    && ix86_binary_operator_ok (AND, SImode, operands)"
9246   "and{l}\t{%2, %0|%0, %2}"
9247   [(set_attr "type" "alu")
9248    (set_attr "mode" "SI")])
9249
9250 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9251 (define_insn "*andsi_2_zext"
9252   [(set (reg FLAGS_REG)
9253         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9254                          (match_operand:SI 2 "general_operand" "g"))
9255                  (const_int 0)))
9256    (set (match_operand:DI 0 "register_operand" "=r")
9257         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9258   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9259    && ix86_binary_operator_ok (AND, SImode, operands)"
9260   "and{l}\t{%2, %k0|%k0, %2}"
9261   [(set_attr "type" "alu")
9262    (set_attr "mode" "SI")])
9263
9264 (define_expand "andhi3"
9265   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9266         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9267                 (match_operand:HI 2 "general_operand" "")))]
9268   "TARGET_HIMODE_MATH"
9269   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9270
9271 (define_insn "*andhi_1"
9272   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9273         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9274                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9275    (clobber (reg:CC FLAGS_REG))]
9276   "ix86_binary_operator_ok (AND, HImode, operands)"
9277 {
9278   switch (get_attr_type (insn))
9279     {
9280     case TYPE_IMOVX:
9281       gcc_assert (CONST_INT_P (operands[2]));
9282       gcc_assert (INTVAL (operands[2]) == 0xff);
9283       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9284
9285     default:
9286       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9287
9288       return "and{w}\t{%2, %0|%0, %2}";
9289     }
9290 }
9291   [(set_attr "type" "alu,alu,imovx")
9292    (set_attr "length_immediate" "*,*,0")
9293    (set_attr "mode" "HI,HI,SI")])
9294
9295 (define_insn "*andhi_2"
9296   [(set (reg FLAGS_REG)
9297         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9298                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9299                  (const_int 0)))
9300    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9301         (and:HI (match_dup 1) (match_dup 2)))]
9302   "ix86_match_ccmode (insn, CCNOmode)
9303    && ix86_binary_operator_ok (AND, HImode, operands)"
9304   "and{w}\t{%2, %0|%0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "mode" "HI")])
9307
9308 (define_expand "andqi3"
9309   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9310         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9311                 (match_operand:QI 2 "general_operand" "")))]
9312   "TARGET_QIMODE_MATH"
9313   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9314
9315 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9316 (define_insn "*andqi_1"
9317   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9318         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9319                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9320    (clobber (reg:CC FLAGS_REG))]
9321   "ix86_binary_operator_ok (AND, QImode, operands)"
9322   "@
9323    and{b}\t{%2, %0|%0, %2}
9324    and{b}\t{%2, %0|%0, %2}
9325    and{l}\t{%k2, %k0|%k0, %k2}"
9326   [(set_attr "type" "alu")
9327    (set_attr "mode" "QI,QI,SI")])
9328
9329 (define_insn "*andqi_1_slp"
9330   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9331         (and:QI (match_dup 0)
9332                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9333    (clobber (reg:CC FLAGS_REG))]
9334   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9335    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9336   "and{b}\t{%1, %0|%0, %1}"
9337   [(set_attr "type" "alu1")
9338    (set_attr "mode" "QI")])
9339
9340 (define_insn "*andqi_2_maybe_si"
9341   [(set (reg FLAGS_REG)
9342         (compare (and:QI
9343                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9344                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9345                  (const_int 0)))
9346    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9347         (and:QI (match_dup 1) (match_dup 2)))]
9348   "ix86_binary_operator_ok (AND, QImode, operands)
9349    && ix86_match_ccmode (insn,
9350                          CONST_INT_P (operands[2])
9351                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9352 {
9353   if (which_alternative == 2)
9354     {
9355       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9356         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9357       return "and{l}\t{%2, %k0|%k0, %2}";
9358     }
9359   return "and{b}\t{%2, %0|%0, %2}";
9360 }
9361   [(set_attr "type" "alu")
9362    (set_attr "mode" "QI,QI,SI")])
9363
9364 (define_insn "*andqi_2"
9365   [(set (reg FLAGS_REG)
9366         (compare (and:QI
9367                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9368                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9369                  (const_int 0)))
9370    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9371         (and:QI (match_dup 1) (match_dup 2)))]
9372   "ix86_match_ccmode (insn, CCNOmode)
9373    && ix86_binary_operator_ok (AND, QImode, operands)"
9374   "and{b}\t{%2, %0|%0, %2}"
9375   [(set_attr "type" "alu")
9376    (set_attr "mode" "QI")])
9377
9378 (define_insn "*andqi_2_slp"
9379   [(set (reg FLAGS_REG)
9380         (compare (and:QI
9381                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9382                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9383                  (const_int 0)))
9384    (set (strict_low_part (match_dup 0))
9385         (and:QI (match_dup 0) (match_dup 1)))]
9386   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9387    && ix86_match_ccmode (insn, CCNOmode)
9388    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9389   "and{b}\t{%1, %0|%0, %1}"
9390   [(set_attr "type" "alu1")
9391    (set_attr "mode" "QI")])
9392
9393 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9394 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9395 ;; for a QImode operand, which of course failed.
9396
9397 (define_insn "andqi_ext_0"
9398   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9399                          (const_int 8)
9400                          (const_int 8))
9401         (and:SI
9402           (zero_extract:SI
9403             (match_operand 1 "ext_register_operand" "0")
9404             (const_int 8)
9405             (const_int 8))
9406           (match_operand 2 "const_int_operand" "n")))
9407    (clobber (reg:CC FLAGS_REG))]
9408   ""
9409   "and{b}\t{%2, %h0|%h0, %2}"
9410   [(set_attr "type" "alu")
9411    (set_attr "length_immediate" "1")
9412    (set_attr "mode" "QI")])
9413
9414 ;; Generated by peephole translating test to and.  This shows up
9415 ;; often in fp comparisons.
9416
9417 (define_insn "*andqi_ext_0_cc"
9418   [(set (reg FLAGS_REG)
9419         (compare
9420           (and:SI
9421             (zero_extract:SI
9422               (match_operand 1 "ext_register_operand" "0")
9423               (const_int 8)
9424               (const_int 8))
9425             (match_operand 2 "const_int_operand" "n"))
9426           (const_int 0)))
9427    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9428                          (const_int 8)
9429                          (const_int 8))
9430         (and:SI
9431           (zero_extract:SI
9432             (match_dup 1)
9433             (const_int 8)
9434             (const_int 8))
9435           (match_dup 2)))]
9436   "ix86_match_ccmode (insn, CCNOmode)"
9437   "and{b}\t{%2, %h0|%h0, %2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "length_immediate" "1")
9440    (set_attr "mode" "QI")])
9441
9442 (define_insn "*andqi_ext_1"
9443   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9444                          (const_int 8)
9445                          (const_int 8))
9446         (and:SI
9447           (zero_extract:SI
9448             (match_operand 1 "ext_register_operand" "0")
9449             (const_int 8)
9450             (const_int 8))
9451           (zero_extend:SI
9452             (match_operand:QI 2 "general_operand" "Qm"))))
9453    (clobber (reg:CC FLAGS_REG))]
9454   "!TARGET_64BIT"
9455   "and{b}\t{%2, %h0|%h0, %2}"
9456   [(set_attr "type" "alu")
9457    (set_attr "length_immediate" "0")
9458    (set_attr "mode" "QI")])
9459
9460 (define_insn "*andqi_ext_1_rex64"
9461   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9462                          (const_int 8)
9463                          (const_int 8))
9464         (and:SI
9465           (zero_extract:SI
9466             (match_operand 1 "ext_register_operand" "0")
9467             (const_int 8)
9468             (const_int 8))
9469           (zero_extend:SI
9470             (match_operand 2 "ext_register_operand" "Q"))))
9471    (clobber (reg:CC FLAGS_REG))]
9472   "TARGET_64BIT"
9473   "and{b}\t{%2, %h0|%h0, %2}"
9474   [(set_attr "type" "alu")
9475    (set_attr "length_immediate" "0")
9476    (set_attr "mode" "QI")])
9477
9478 (define_insn "*andqi_ext_2"
9479   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9480                          (const_int 8)
9481                          (const_int 8))
9482         (and:SI
9483           (zero_extract:SI
9484             (match_operand 1 "ext_register_operand" "%0")
9485             (const_int 8)
9486             (const_int 8))
9487           (zero_extract:SI
9488             (match_operand 2 "ext_register_operand" "Q")
9489             (const_int 8)
9490             (const_int 8))))
9491    (clobber (reg:CC FLAGS_REG))]
9492   ""
9493   "and{b}\t{%h2, %h0|%h0, %h2}"
9494   [(set_attr "type" "alu")
9495    (set_attr "length_immediate" "0")
9496    (set_attr "mode" "QI")])
9497
9498 ;; Convert wide AND instructions with immediate operand to shorter QImode
9499 ;; equivalents when possible.
9500 ;; Don't do the splitting with memory operands, since it introduces risk
9501 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9502 ;; for size, but that can (should?) be handled by generic code instead.
9503 (define_split
9504   [(set (match_operand 0 "register_operand" "")
9505         (and (match_operand 1 "register_operand" "")
9506              (match_operand 2 "const_int_operand" "")))
9507    (clobber (reg:CC FLAGS_REG))]
9508    "reload_completed
9509     && QI_REG_P (operands[0])
9510     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9511     && !(~INTVAL (operands[2]) & ~(255 << 8))
9512     && GET_MODE (operands[0]) != QImode"
9513   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9514                    (and:SI (zero_extract:SI (match_dup 1)
9515                                             (const_int 8) (const_int 8))
9516                            (match_dup 2)))
9517               (clobber (reg:CC FLAGS_REG))])]
9518   "operands[0] = gen_lowpart (SImode, operands[0]);
9519    operands[1] = gen_lowpart (SImode, operands[1]);
9520    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9521
9522 ;; Since AND can be encoded with sign extended immediate, this is only
9523 ;; profitable when 7th bit is not set.
9524 (define_split
9525   [(set (match_operand 0 "register_operand" "")
9526         (and (match_operand 1 "general_operand" "")
9527              (match_operand 2 "const_int_operand" "")))
9528    (clobber (reg:CC FLAGS_REG))]
9529    "reload_completed
9530     && ANY_QI_REG_P (operands[0])
9531     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9532     && !(~INTVAL (operands[2]) & ~255)
9533     && !(INTVAL (operands[2]) & 128)
9534     && GET_MODE (operands[0]) != QImode"
9535   [(parallel [(set (strict_low_part (match_dup 0))
9536                    (and:QI (match_dup 1)
9537                            (match_dup 2)))
9538               (clobber (reg:CC FLAGS_REG))])]
9539   "operands[0] = gen_lowpart (QImode, operands[0]);
9540    operands[1] = gen_lowpart (QImode, operands[1]);
9541    operands[2] = gen_lowpart (QImode, operands[2]);")
9542 \f
9543 ;; Logical inclusive OR instructions
9544
9545 ;; %%% This used to optimize known byte-wide and operations to memory.
9546 ;; If this is considered useful, it should be done with splitters.
9547
9548 (define_expand "iordi3"
9549   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9550         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9551                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9552   "TARGET_64BIT"
9553   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9554
9555 (define_insn "*iordi_1_rex64"
9556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9557         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9558                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9559    (clobber (reg:CC FLAGS_REG))]
9560   "TARGET_64BIT
9561    && ix86_binary_operator_ok (IOR, DImode, operands)"
9562   "or{q}\t{%2, %0|%0, %2}"
9563   [(set_attr "type" "alu")
9564    (set_attr "mode" "DI")])
9565
9566 (define_insn "*iordi_2_rex64"
9567   [(set (reg FLAGS_REG)
9568         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9569                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9570                  (const_int 0)))
9571    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9572         (ior:DI (match_dup 1) (match_dup 2)))]
9573   "TARGET_64BIT
9574    && ix86_match_ccmode (insn, CCNOmode)
9575    && ix86_binary_operator_ok (IOR, DImode, operands)"
9576   "or{q}\t{%2, %0|%0, %2}"
9577   [(set_attr "type" "alu")
9578    (set_attr "mode" "DI")])
9579
9580 (define_insn "*iordi_3_rex64"
9581   [(set (reg FLAGS_REG)
9582         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9583                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9584                  (const_int 0)))
9585    (clobber (match_scratch:DI 0 "=r"))]
9586   "TARGET_64BIT
9587    && ix86_match_ccmode (insn, CCNOmode)
9588    && ix86_binary_operator_ok (IOR, DImode, operands)"
9589   "or{q}\t{%2, %0|%0, %2}"
9590   [(set_attr "type" "alu")
9591    (set_attr "mode" "DI")])
9592
9593
9594 (define_expand "iorsi3"
9595   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9596         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9597                 (match_operand:SI 2 "general_operand" "")))]
9598   ""
9599   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9600
9601 (define_insn "*iorsi_1"
9602   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9603         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9604                 (match_operand:SI 2 "general_operand" "ri,g")))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "ix86_binary_operator_ok (IOR, SImode, operands)"
9607   "or{l}\t{%2, %0|%0, %2}"
9608   [(set_attr "type" "alu")
9609    (set_attr "mode" "SI")])
9610
9611 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9612 (define_insn "*iorsi_1_zext"
9613   [(set (match_operand:DI 0 "register_operand" "=r")
9614         (zero_extend:DI
9615           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9616                   (match_operand:SI 2 "general_operand" "g"))))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9619   "or{l}\t{%2, %k0|%k0, %2}"
9620   [(set_attr "type" "alu")
9621    (set_attr "mode" "SI")])
9622
9623 (define_insn "*iorsi_1_zext_imm"
9624   [(set (match_operand:DI 0 "register_operand" "=r")
9625         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9626                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_64BIT"
9629   "or{l}\t{%2, %k0|%k0, %2}"
9630   [(set_attr "type" "alu")
9631    (set_attr "mode" "SI")])
9632
9633 (define_insn "*iorsi_2"
9634   [(set (reg FLAGS_REG)
9635         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9636                          (match_operand:SI 2 "general_operand" "g,ri"))
9637                  (const_int 0)))
9638    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9639         (ior:SI (match_dup 1) (match_dup 2)))]
9640   "ix86_match_ccmode (insn, CCNOmode)
9641    && ix86_binary_operator_ok (IOR, SImode, operands)"
9642   "or{l}\t{%2, %0|%0, %2}"
9643   [(set_attr "type" "alu")
9644    (set_attr "mode" "SI")])
9645
9646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9647 ;; ??? Special case for immediate operand is missing - it is tricky.
9648 (define_insn "*iorsi_2_zext"
9649   [(set (reg FLAGS_REG)
9650         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9651                          (match_operand:SI 2 "general_operand" "g"))
9652                  (const_int 0)))
9653    (set (match_operand:DI 0 "register_operand" "=r")
9654         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9655   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9656    && ix86_binary_operator_ok (IOR, SImode, operands)"
9657   "or{l}\t{%2, %k0|%k0, %2}"
9658   [(set_attr "type" "alu")
9659    (set_attr "mode" "SI")])
9660
9661 (define_insn "*iorsi_2_zext_imm"
9662   [(set (reg FLAGS_REG)
9663         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9664                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9665                  (const_int 0)))
9666    (set (match_operand:DI 0 "register_operand" "=r")
9667         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9668   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9669    && ix86_binary_operator_ok (IOR, SImode, operands)"
9670   "or{l}\t{%2, %k0|%k0, %2}"
9671   [(set_attr "type" "alu")
9672    (set_attr "mode" "SI")])
9673
9674 (define_insn "*iorsi_3"
9675   [(set (reg FLAGS_REG)
9676         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9677                          (match_operand:SI 2 "general_operand" "g"))
9678                  (const_int 0)))
9679    (clobber (match_scratch:SI 0 "=r"))]
9680   "ix86_match_ccmode (insn, CCNOmode)
9681    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9682   "or{l}\t{%2, %0|%0, %2}"
9683   [(set_attr "type" "alu")
9684    (set_attr "mode" "SI")])
9685
9686 (define_expand "iorhi3"
9687   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9688         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9689                 (match_operand:HI 2 "general_operand" "")))]
9690   "TARGET_HIMODE_MATH"
9691   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9692
9693 (define_insn "*iorhi_1"
9694   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9695         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9696                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9697    (clobber (reg:CC FLAGS_REG))]
9698   "ix86_binary_operator_ok (IOR, HImode, operands)"
9699   "or{w}\t{%2, %0|%0, %2}"
9700   [(set_attr "type" "alu")
9701    (set_attr "mode" "HI")])
9702
9703 (define_insn "*iorhi_2"
9704   [(set (reg FLAGS_REG)
9705         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9706                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9707                  (const_int 0)))
9708    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9709         (ior:HI (match_dup 1) (match_dup 2)))]
9710   "ix86_match_ccmode (insn, CCNOmode)
9711    && ix86_binary_operator_ok (IOR, HImode, operands)"
9712   "or{w}\t{%2, %0|%0, %2}"
9713   [(set_attr "type" "alu")
9714    (set_attr "mode" "HI")])
9715
9716 (define_insn "*iorhi_3"
9717   [(set (reg FLAGS_REG)
9718         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9719                          (match_operand:HI 2 "general_operand" "rmn"))
9720                  (const_int 0)))
9721    (clobber (match_scratch:HI 0 "=r"))]
9722   "ix86_match_ccmode (insn, CCNOmode)
9723    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9724   "or{w}\t{%2, %0|%0, %2}"
9725   [(set_attr "type" "alu")
9726    (set_attr "mode" "HI")])
9727
9728 (define_expand "iorqi3"
9729   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9730         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9731                 (match_operand:QI 2 "general_operand" "")))]
9732   "TARGET_QIMODE_MATH"
9733   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9734
9735 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9736 (define_insn "*iorqi_1"
9737   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9738         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9739                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9740    (clobber (reg:CC FLAGS_REG))]
9741   "ix86_binary_operator_ok (IOR, QImode, operands)"
9742   "@
9743    or{b}\t{%2, %0|%0, %2}
9744    or{b}\t{%2, %0|%0, %2}
9745    or{l}\t{%k2, %k0|%k0, %k2}"
9746   [(set_attr "type" "alu")
9747    (set_attr "mode" "QI,QI,SI")])
9748
9749 (define_insn "*iorqi_1_slp"
9750   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9751         (ior:QI (match_dup 0)
9752                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9753    (clobber (reg:CC FLAGS_REG))]
9754   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9755    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9756   "or{b}\t{%1, %0|%0, %1}"
9757   [(set_attr "type" "alu1")
9758    (set_attr "mode" "QI")])
9759
9760 (define_insn "*iorqi_2"
9761   [(set (reg FLAGS_REG)
9762         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9763                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9764                  (const_int 0)))
9765    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9766         (ior:QI (match_dup 1) (match_dup 2)))]
9767   "ix86_match_ccmode (insn, CCNOmode)
9768    && ix86_binary_operator_ok (IOR, QImode, operands)"
9769   "or{b}\t{%2, %0|%0, %2}"
9770   [(set_attr "type" "alu")
9771    (set_attr "mode" "QI")])
9772
9773 (define_insn "*iorqi_2_slp"
9774   [(set (reg FLAGS_REG)
9775         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9776                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9777                  (const_int 0)))
9778    (set (strict_low_part (match_dup 0))
9779         (ior:QI (match_dup 0) (match_dup 1)))]
9780   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9781    && ix86_match_ccmode (insn, CCNOmode)
9782    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9783   "or{b}\t{%1, %0|%0, %1}"
9784   [(set_attr "type" "alu1")
9785    (set_attr "mode" "QI")])
9786
9787 (define_insn "*iorqi_3"
9788   [(set (reg FLAGS_REG)
9789         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9790                          (match_operand:QI 2 "general_operand" "qmn"))
9791                  (const_int 0)))
9792    (clobber (match_scratch:QI 0 "=q"))]
9793   "ix86_match_ccmode (insn, CCNOmode)
9794    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9795   "or{b}\t{%2, %0|%0, %2}"
9796   [(set_attr "type" "alu")
9797    (set_attr "mode" "QI")])
9798
9799 (define_insn "*iorqi_ext_0"
9800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9801                          (const_int 8)
9802                          (const_int 8))
9803         (ior:SI
9804           (zero_extract:SI
9805             (match_operand 1 "ext_register_operand" "0")
9806             (const_int 8)
9807             (const_int 8))
9808           (match_operand 2 "const_int_operand" "n")))
9809    (clobber (reg:CC FLAGS_REG))]
9810   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9811   "or{b}\t{%2, %h0|%h0, %2}"
9812   [(set_attr "type" "alu")
9813    (set_attr "length_immediate" "1")
9814    (set_attr "mode" "QI")])
9815
9816 (define_insn "*iorqi_ext_1"
9817   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9818                          (const_int 8)
9819                          (const_int 8))
9820         (ior:SI
9821           (zero_extract:SI
9822             (match_operand 1 "ext_register_operand" "0")
9823             (const_int 8)
9824             (const_int 8))
9825           (zero_extend:SI
9826             (match_operand:QI 2 "general_operand" "Qm"))))
9827    (clobber (reg:CC FLAGS_REG))]
9828   "!TARGET_64BIT
9829    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9830   "or{b}\t{%2, %h0|%h0, %2}"
9831   [(set_attr "type" "alu")
9832    (set_attr "length_immediate" "0")
9833    (set_attr "mode" "QI")])
9834
9835 (define_insn "*iorqi_ext_1_rex64"
9836   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9837                          (const_int 8)
9838                          (const_int 8))
9839         (ior:SI
9840           (zero_extract:SI
9841             (match_operand 1 "ext_register_operand" "0")
9842             (const_int 8)
9843             (const_int 8))
9844           (zero_extend:SI
9845             (match_operand 2 "ext_register_operand" "Q"))))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "TARGET_64BIT
9848    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9849   "or{b}\t{%2, %h0|%h0, %2}"
9850   [(set_attr "type" "alu")
9851    (set_attr "length_immediate" "0")
9852    (set_attr "mode" "QI")])
9853
9854 (define_insn "*iorqi_ext_2"
9855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9856                          (const_int 8)
9857                          (const_int 8))
9858         (ior:SI
9859           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9860                            (const_int 8)
9861                            (const_int 8))
9862           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9863                            (const_int 8)
9864                            (const_int 8))))
9865    (clobber (reg:CC FLAGS_REG))]
9866   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9867   "ior{b}\t{%h2, %h0|%h0, %h2}"
9868   [(set_attr "type" "alu")
9869    (set_attr "length_immediate" "0")
9870    (set_attr "mode" "QI")])
9871
9872 (define_split
9873   [(set (match_operand 0 "register_operand" "")
9874         (ior (match_operand 1 "register_operand" "")
9875              (match_operand 2 "const_int_operand" "")))
9876    (clobber (reg:CC FLAGS_REG))]
9877    "reload_completed
9878     && QI_REG_P (operands[0])
9879     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9880     && !(INTVAL (operands[2]) & ~(255 << 8))
9881     && GET_MODE (operands[0]) != QImode"
9882   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9883                    (ior:SI (zero_extract:SI (match_dup 1)
9884                                             (const_int 8) (const_int 8))
9885                            (match_dup 2)))
9886               (clobber (reg:CC FLAGS_REG))])]
9887   "operands[0] = gen_lowpart (SImode, operands[0]);
9888    operands[1] = gen_lowpart (SImode, operands[1]);
9889    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9890
9891 ;; Since OR can be encoded with sign extended immediate, this is only
9892 ;; profitable when 7th bit is set.
9893 (define_split
9894   [(set (match_operand 0 "register_operand" "")
9895         (ior (match_operand 1 "general_operand" "")
9896              (match_operand 2 "const_int_operand" "")))
9897    (clobber (reg:CC FLAGS_REG))]
9898    "reload_completed
9899     && ANY_QI_REG_P (operands[0])
9900     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9901     && !(INTVAL (operands[2]) & ~255)
9902     && (INTVAL (operands[2]) & 128)
9903     && GET_MODE (operands[0]) != QImode"
9904   [(parallel [(set (strict_low_part (match_dup 0))
9905                    (ior:QI (match_dup 1)
9906                            (match_dup 2)))
9907               (clobber (reg:CC FLAGS_REG))])]
9908   "operands[0] = gen_lowpart (QImode, operands[0]);
9909    operands[1] = gen_lowpart (QImode, operands[1]);
9910    operands[2] = gen_lowpart (QImode, operands[2]);")
9911 \f
9912 ;; Logical XOR instructions
9913
9914 ;; %%% This used to optimize known byte-wide and operations to memory.
9915 ;; If this is considered useful, it should be done with splitters.
9916
9917 (define_expand "xordi3"
9918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9919         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9920                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9921   "TARGET_64BIT"
9922   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9923
9924 (define_insn "*xordi_1_rex64"
9925   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9926         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9927                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9928    (clobber (reg:CC FLAGS_REG))]
9929   "TARGET_64BIT
9930    && ix86_binary_operator_ok (XOR, DImode, operands)"
9931   "xor{q}\t{%2, %0|%0, %2}"
9932   [(set_attr "type" "alu")
9933    (set_attr "mode" "DI")])
9934
9935 (define_insn "*xordi_2_rex64"
9936   [(set (reg FLAGS_REG)
9937         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9938                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9939                  (const_int 0)))
9940    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9941         (xor:DI (match_dup 1) (match_dup 2)))]
9942   "TARGET_64BIT
9943    && ix86_match_ccmode (insn, CCNOmode)
9944    && ix86_binary_operator_ok (XOR, DImode, operands)"
9945   "xor{q}\t{%2, %0|%0, %2}"
9946   [(set_attr "type" "alu")
9947    (set_attr "mode" "DI")])
9948
9949 (define_insn "*xordi_3_rex64"
9950   [(set (reg FLAGS_REG)
9951         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9952                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9953                  (const_int 0)))
9954    (clobber (match_scratch:DI 0 "=r"))]
9955   "TARGET_64BIT
9956    && ix86_match_ccmode (insn, CCNOmode)
9957    && ix86_binary_operator_ok (XOR, DImode, operands)"
9958   "xor{q}\t{%2, %0|%0, %2}"
9959   [(set_attr "type" "alu")
9960    (set_attr "mode" "DI")])
9961
9962 (define_expand "xorsi3"
9963   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9964         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9965                 (match_operand:SI 2 "general_operand" "")))]
9966   ""
9967   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9968
9969 (define_insn "*xorsi_1"
9970   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9971         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9972                 (match_operand:SI 2 "general_operand" "ri,rm")))
9973    (clobber (reg:CC FLAGS_REG))]
9974   "ix86_binary_operator_ok (XOR, SImode, operands)"
9975   "xor{l}\t{%2, %0|%0, %2}"
9976   [(set_attr "type" "alu")
9977    (set_attr "mode" "SI")])
9978
9979 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9980 ;; Add speccase for immediates
9981 (define_insn "*xorsi_1_zext"
9982   [(set (match_operand:DI 0 "register_operand" "=r")
9983         (zero_extend:DI
9984           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9985                   (match_operand:SI 2 "general_operand" "g"))))
9986    (clobber (reg:CC FLAGS_REG))]
9987   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9988   "xor{l}\t{%2, %k0|%k0, %2}"
9989   [(set_attr "type" "alu")
9990    (set_attr "mode" "SI")])
9991
9992 (define_insn "*xorsi_1_zext_imm"
9993   [(set (match_operand:DI 0 "register_operand" "=r")
9994         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9995                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9996    (clobber (reg:CC FLAGS_REG))]
9997   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9998   "xor{l}\t{%2, %k0|%k0, %2}"
9999   [(set_attr "type" "alu")
10000    (set_attr "mode" "SI")])
10001
10002 (define_insn "*xorsi_2"
10003   [(set (reg FLAGS_REG)
10004         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10005                          (match_operand:SI 2 "general_operand" "g,ri"))
10006                  (const_int 0)))
10007    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10008         (xor:SI (match_dup 1) (match_dup 2)))]
10009   "ix86_match_ccmode (insn, CCNOmode)
10010    && ix86_binary_operator_ok (XOR, SImode, operands)"
10011   "xor{l}\t{%2, %0|%0, %2}"
10012   [(set_attr "type" "alu")
10013    (set_attr "mode" "SI")])
10014
10015 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10016 ;; ??? Special case for immediate operand is missing - it is tricky.
10017 (define_insn "*xorsi_2_zext"
10018   [(set (reg FLAGS_REG)
10019         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10020                          (match_operand:SI 2 "general_operand" "g"))
10021                  (const_int 0)))
10022    (set (match_operand:DI 0 "register_operand" "=r")
10023         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10024   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10025    && ix86_binary_operator_ok (XOR, SImode, operands)"
10026   "xor{l}\t{%2, %k0|%k0, %2}"
10027   [(set_attr "type" "alu")
10028    (set_attr "mode" "SI")])
10029
10030 (define_insn "*xorsi_2_zext_imm"
10031   [(set (reg FLAGS_REG)
10032         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10033                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10034                  (const_int 0)))
10035    (set (match_operand:DI 0 "register_operand" "=r")
10036         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10037   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10038    && ix86_binary_operator_ok (XOR, SImode, operands)"
10039   "xor{l}\t{%2, %k0|%k0, %2}"
10040   [(set_attr "type" "alu")
10041    (set_attr "mode" "SI")])
10042
10043 (define_insn "*xorsi_3"
10044   [(set (reg FLAGS_REG)
10045         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10046                          (match_operand:SI 2 "general_operand" "g"))
10047                  (const_int 0)))
10048    (clobber (match_scratch:SI 0 "=r"))]
10049   "ix86_match_ccmode (insn, CCNOmode)
10050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10051   "xor{l}\t{%2, %0|%0, %2}"
10052   [(set_attr "type" "alu")
10053    (set_attr "mode" "SI")])
10054
10055 (define_expand "xorhi3"
10056   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10057         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10058                 (match_operand:HI 2 "general_operand" "")))]
10059   "TARGET_HIMODE_MATH"
10060   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10061
10062 (define_insn "*xorhi_1"
10063   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10064         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10065                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10066    (clobber (reg:CC FLAGS_REG))]
10067   "ix86_binary_operator_ok (XOR, HImode, operands)"
10068   "xor{w}\t{%2, %0|%0, %2}"
10069   [(set_attr "type" "alu")
10070    (set_attr "mode" "HI")])
10071
10072 (define_insn "*xorhi_2"
10073   [(set (reg FLAGS_REG)
10074         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10075                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10076                  (const_int 0)))
10077    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10078         (xor:HI (match_dup 1) (match_dup 2)))]
10079   "ix86_match_ccmode (insn, CCNOmode)
10080    && ix86_binary_operator_ok (XOR, HImode, operands)"
10081   "xor{w}\t{%2, %0|%0, %2}"
10082   [(set_attr "type" "alu")
10083    (set_attr "mode" "HI")])
10084
10085 (define_insn "*xorhi_3"
10086   [(set (reg FLAGS_REG)
10087         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10088                          (match_operand:HI 2 "general_operand" "rmn"))
10089                  (const_int 0)))
10090    (clobber (match_scratch:HI 0 "=r"))]
10091   "ix86_match_ccmode (insn, CCNOmode)
10092    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10093   "xor{w}\t{%2, %0|%0, %2}"
10094   [(set_attr "type" "alu")
10095    (set_attr "mode" "HI")])
10096
10097 (define_expand "xorqi3"
10098   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10099         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10100                 (match_operand:QI 2 "general_operand" "")))]
10101   "TARGET_QIMODE_MATH"
10102   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10103
10104 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10105 (define_insn "*xorqi_1"
10106   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10107         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10108                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "ix86_binary_operator_ok (XOR, QImode, operands)"
10111   "@
10112    xor{b}\t{%2, %0|%0, %2}
10113    xor{b}\t{%2, %0|%0, %2}
10114    xor{l}\t{%k2, %k0|%k0, %k2}"
10115   [(set_attr "type" "alu")
10116    (set_attr "mode" "QI,QI,SI")])
10117
10118 (define_insn "*xorqi_1_slp"
10119   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10120         (xor:QI (match_dup 0)
10121                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10122    (clobber (reg:CC FLAGS_REG))]
10123   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10124    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10125   "xor{b}\t{%1, %0|%0, %1}"
10126   [(set_attr "type" "alu1")
10127    (set_attr "mode" "QI")])
10128
10129 (define_insn "*xorqi_ext_0"
10130   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10131                          (const_int 8)
10132                          (const_int 8))
10133         (xor:SI
10134           (zero_extract:SI
10135             (match_operand 1 "ext_register_operand" "0")
10136             (const_int 8)
10137             (const_int 8))
10138           (match_operand 2 "const_int_operand" "n")))
10139    (clobber (reg:CC FLAGS_REG))]
10140   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10141   "xor{b}\t{%2, %h0|%h0, %2}"
10142   [(set_attr "type" "alu")
10143    (set_attr "length_immediate" "1")
10144    (set_attr "mode" "QI")])
10145
10146 (define_insn "*xorqi_ext_1"
10147   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10148                          (const_int 8)
10149                          (const_int 8))
10150         (xor:SI
10151           (zero_extract:SI
10152             (match_operand 1 "ext_register_operand" "0")
10153             (const_int 8)
10154             (const_int 8))
10155           (zero_extend:SI
10156             (match_operand:QI 2 "general_operand" "Qm"))))
10157    (clobber (reg:CC FLAGS_REG))]
10158   "!TARGET_64BIT
10159    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10160   "xor{b}\t{%2, %h0|%h0, %2}"
10161   [(set_attr "type" "alu")
10162    (set_attr "length_immediate" "0")
10163    (set_attr "mode" "QI")])
10164
10165 (define_insn "*xorqi_ext_1_rex64"
10166   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10167                          (const_int 8)
10168                          (const_int 8))
10169         (xor:SI
10170           (zero_extract:SI
10171             (match_operand 1 "ext_register_operand" "0")
10172             (const_int 8)
10173             (const_int 8))
10174           (zero_extend:SI
10175             (match_operand 2 "ext_register_operand" "Q"))))
10176    (clobber (reg:CC FLAGS_REG))]
10177   "TARGET_64BIT
10178    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10179   "xor{b}\t{%2, %h0|%h0, %2}"
10180   [(set_attr "type" "alu")
10181    (set_attr "length_immediate" "0")
10182    (set_attr "mode" "QI")])
10183
10184 (define_insn "*xorqi_ext_2"
10185   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10186                          (const_int 8)
10187                          (const_int 8))
10188         (xor:SI
10189           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10190                            (const_int 8)
10191                            (const_int 8))
10192           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10193                            (const_int 8)
10194                            (const_int 8))))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10197   "xor{b}\t{%h2, %h0|%h0, %h2}"
10198   [(set_attr "type" "alu")
10199    (set_attr "length_immediate" "0")
10200    (set_attr "mode" "QI")])
10201
10202 (define_insn "*xorqi_cc_1"
10203   [(set (reg FLAGS_REG)
10204         (compare
10205           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10206                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10207           (const_int 0)))
10208    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10209         (xor:QI (match_dup 1) (match_dup 2)))]
10210   "ix86_match_ccmode (insn, CCNOmode)
10211    && ix86_binary_operator_ok (XOR, QImode, operands)"
10212   "xor{b}\t{%2, %0|%0, %2}"
10213   [(set_attr "type" "alu")
10214    (set_attr "mode" "QI")])
10215
10216 (define_insn "*xorqi_2_slp"
10217   [(set (reg FLAGS_REG)
10218         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10219                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10220                  (const_int 0)))
10221    (set (strict_low_part (match_dup 0))
10222         (xor:QI (match_dup 0) (match_dup 1)))]
10223   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10224    && ix86_match_ccmode (insn, CCNOmode)
10225    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10226   "xor{b}\t{%1, %0|%0, %1}"
10227   [(set_attr "type" "alu1")
10228    (set_attr "mode" "QI")])
10229
10230 (define_insn "*xorqi_cc_2"
10231   [(set (reg FLAGS_REG)
10232         (compare
10233           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10234                   (match_operand:QI 2 "general_operand" "qmn"))
10235           (const_int 0)))
10236    (clobber (match_scratch:QI 0 "=q"))]
10237   "ix86_match_ccmode (insn, CCNOmode)
10238    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10239   "xor{b}\t{%2, %0|%0, %2}"
10240   [(set_attr "type" "alu")
10241    (set_attr "mode" "QI")])
10242
10243 (define_insn "*xorqi_cc_ext_1"
10244   [(set (reg FLAGS_REG)
10245         (compare
10246           (xor:SI
10247             (zero_extract:SI
10248               (match_operand 1 "ext_register_operand" "0")
10249               (const_int 8)
10250               (const_int 8))
10251             (match_operand:QI 2 "general_operand" "qmn"))
10252           (const_int 0)))
10253    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10254                          (const_int 8)
10255                          (const_int 8))
10256         (xor:SI
10257           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10258           (match_dup 2)))]
10259   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10260   "xor{b}\t{%2, %h0|%h0, %2}"
10261   [(set_attr "type" "alu")
10262    (set_attr "mode" "QI")])
10263
10264 (define_insn "*xorqi_cc_ext_1_rex64"
10265   [(set (reg FLAGS_REG)
10266         (compare
10267           (xor:SI
10268             (zero_extract:SI
10269               (match_operand 1 "ext_register_operand" "0")
10270               (const_int 8)
10271               (const_int 8))
10272             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10273           (const_int 0)))
10274    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10275                          (const_int 8)
10276                          (const_int 8))
10277         (xor:SI
10278           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10279           (match_dup 2)))]
10280   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10281   "xor{b}\t{%2, %h0|%h0, %2}"
10282   [(set_attr "type" "alu")
10283    (set_attr "mode" "QI")])
10284
10285 (define_expand "xorqi_cc_ext_1"
10286   [(parallel [
10287      (set (reg:CCNO FLAGS_REG)
10288           (compare:CCNO
10289             (xor:SI
10290               (zero_extract:SI
10291                 (match_operand 1 "ext_register_operand" "")
10292                 (const_int 8)
10293                 (const_int 8))
10294               (match_operand:QI 2 "general_operand" ""))
10295             (const_int 0)))
10296      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10297                            (const_int 8)
10298                            (const_int 8))
10299           (xor:SI
10300             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10301             (match_dup 2)))])]
10302   ""
10303   "")
10304
10305 (define_split
10306   [(set (match_operand 0 "register_operand" "")
10307         (xor (match_operand 1 "register_operand" "")
10308              (match_operand 2 "const_int_operand" "")))
10309    (clobber (reg:CC FLAGS_REG))]
10310    "reload_completed
10311     && QI_REG_P (operands[0])
10312     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10313     && !(INTVAL (operands[2]) & ~(255 << 8))
10314     && GET_MODE (operands[0]) != QImode"
10315   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10316                    (xor:SI (zero_extract:SI (match_dup 1)
10317                                             (const_int 8) (const_int 8))
10318                            (match_dup 2)))
10319               (clobber (reg:CC FLAGS_REG))])]
10320   "operands[0] = gen_lowpart (SImode, operands[0]);
10321    operands[1] = gen_lowpart (SImode, operands[1]);
10322    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10323
10324 ;; Since XOR can be encoded with sign extended immediate, this is only
10325 ;; profitable when 7th bit is set.
10326 (define_split
10327   [(set (match_operand 0 "register_operand" "")
10328         (xor (match_operand 1 "general_operand" "")
10329              (match_operand 2 "const_int_operand" "")))
10330    (clobber (reg:CC FLAGS_REG))]
10331    "reload_completed
10332     && ANY_QI_REG_P (operands[0])
10333     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10334     && !(INTVAL (operands[2]) & ~255)
10335     && (INTVAL (operands[2]) & 128)
10336     && GET_MODE (operands[0]) != QImode"
10337   [(parallel [(set (strict_low_part (match_dup 0))
10338                    (xor:QI (match_dup 1)
10339                            (match_dup 2)))
10340               (clobber (reg:CC FLAGS_REG))])]
10341   "operands[0] = gen_lowpart (QImode, operands[0]);
10342    operands[1] = gen_lowpart (QImode, operands[1]);
10343    operands[2] = gen_lowpart (QImode, operands[2]);")
10344 \f
10345 ;; Negation instructions
10346
10347 (define_expand "negti2"
10348   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10349         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10350   "TARGET_64BIT"
10351   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10352
10353 (define_insn "*negti2_1"
10354   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10355         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10356    (clobber (reg:CC FLAGS_REG))]
10357   "TARGET_64BIT
10358    && ix86_unary_operator_ok (NEG, TImode, operands)"
10359   "#")
10360
10361 (define_split
10362   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10363         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10364    (clobber (reg:CC FLAGS_REG))]
10365   "TARGET_64BIT && reload_completed"
10366   [(parallel
10367     [(set (reg:CCZ FLAGS_REG)
10368           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10369      (set (match_dup 0) (neg:DI (match_dup 1)))])
10370    (parallel
10371     [(set (match_dup 2)
10372           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10373                             (match_dup 3))
10374                    (const_int 0)))
10375      (clobber (reg:CC FLAGS_REG))])
10376    (parallel
10377     [(set (match_dup 2)
10378           (neg:DI (match_dup 2)))
10379      (clobber (reg:CC FLAGS_REG))])]
10380   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10381
10382 (define_expand "negdi2"
10383   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10384         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10385   ""
10386   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10387
10388 (define_insn "*negdi2_1"
10389   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10390         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10391    (clobber (reg:CC FLAGS_REG))]
10392   "!TARGET_64BIT
10393    && ix86_unary_operator_ok (NEG, DImode, operands)"
10394   "#")
10395
10396 (define_split
10397   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10398         (neg:DI (match_operand:DI 1 "general_operand" "")))
10399    (clobber (reg:CC FLAGS_REG))]
10400   "!TARGET_64BIT && reload_completed"
10401   [(parallel
10402     [(set (reg:CCZ FLAGS_REG)
10403           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10404      (set (match_dup 0) (neg:SI (match_dup 1)))])
10405    (parallel
10406     [(set (match_dup 2)
10407           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10408                             (match_dup 3))
10409                    (const_int 0)))
10410      (clobber (reg:CC FLAGS_REG))])
10411    (parallel
10412     [(set (match_dup 2)
10413           (neg:SI (match_dup 2)))
10414      (clobber (reg:CC FLAGS_REG))])]
10415   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10416
10417 (define_insn "*negdi2_1_rex64"
10418   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10419         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10420    (clobber (reg:CC FLAGS_REG))]
10421   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10422   "neg{q}\t%0"
10423   [(set_attr "type" "negnot")
10424    (set_attr "mode" "DI")])
10425
10426 ;; The problem with neg is that it does not perform (compare x 0),
10427 ;; it really performs (compare 0 x), which leaves us with the zero
10428 ;; flag being the only useful item.
10429
10430 (define_insn "*negdi2_cmpz_rex64"
10431   [(set (reg:CCZ FLAGS_REG)
10432         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10433                      (const_int 0)))
10434    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10435         (neg:DI (match_dup 1)))]
10436   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10437   "neg{q}\t%0"
10438   [(set_attr "type" "negnot")
10439    (set_attr "mode" "DI")])
10440
10441
10442 (define_expand "negsi2"
10443   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10444         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10445   ""
10446   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10447
10448 (define_insn "*negsi2_1"
10449   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10450         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10451    (clobber (reg:CC FLAGS_REG))]
10452   "ix86_unary_operator_ok (NEG, SImode, operands)"
10453   "neg{l}\t%0"
10454   [(set_attr "type" "negnot")
10455    (set_attr "mode" "SI")])
10456
10457 ;; Combine is quite creative about this pattern.
10458 (define_insn "*negsi2_1_zext"
10459   [(set (match_operand:DI 0 "register_operand" "=r")
10460         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10461                                         (const_int 32)))
10462                      (const_int 32)))
10463    (clobber (reg:CC FLAGS_REG))]
10464   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10465   "neg{l}\t%k0"
10466   [(set_attr "type" "negnot")
10467    (set_attr "mode" "SI")])
10468
10469 ;; The problem with neg is that it does not perform (compare x 0),
10470 ;; it really performs (compare 0 x), which leaves us with the zero
10471 ;; flag being the only useful item.
10472
10473 (define_insn "*negsi2_cmpz"
10474   [(set (reg:CCZ FLAGS_REG)
10475         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10476                      (const_int 0)))
10477    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10478         (neg:SI (match_dup 1)))]
10479   "ix86_unary_operator_ok (NEG, SImode, operands)"
10480   "neg{l}\t%0"
10481   [(set_attr "type" "negnot")
10482    (set_attr "mode" "SI")])
10483
10484 (define_insn "*negsi2_cmpz_zext"
10485   [(set (reg:CCZ FLAGS_REG)
10486         (compare:CCZ (lshiftrt:DI
10487                        (neg:DI (ashift:DI
10488                                  (match_operand:DI 1 "register_operand" "0")
10489                                  (const_int 32)))
10490                        (const_int 32))
10491                      (const_int 0)))
10492    (set (match_operand:DI 0 "register_operand" "=r")
10493         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10494                                         (const_int 32)))
10495                      (const_int 32)))]
10496   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10497   "neg{l}\t%k0"
10498   [(set_attr "type" "negnot")
10499    (set_attr "mode" "SI")])
10500
10501 (define_expand "neghi2"
10502   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504   "TARGET_HIMODE_MATH"
10505   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10506
10507 (define_insn "*neghi2_1"
10508   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10510    (clobber (reg:CC FLAGS_REG))]
10511   "ix86_unary_operator_ok (NEG, HImode, operands)"
10512   "neg{w}\t%0"
10513   [(set_attr "type" "negnot")
10514    (set_attr "mode" "HI")])
10515
10516 (define_insn "*neghi2_cmpz"
10517   [(set (reg:CCZ FLAGS_REG)
10518         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10519                      (const_int 0)))
10520    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10521         (neg:HI (match_dup 1)))]
10522   "ix86_unary_operator_ok (NEG, HImode, operands)"
10523   "neg{w}\t%0"
10524   [(set_attr "type" "negnot")
10525    (set_attr "mode" "HI")])
10526
10527 (define_expand "negqi2"
10528   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10529         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10530   "TARGET_QIMODE_MATH"
10531   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10532
10533 (define_insn "*negqi2_1"
10534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10535         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10536    (clobber (reg:CC FLAGS_REG))]
10537   "ix86_unary_operator_ok (NEG, QImode, operands)"
10538   "neg{b}\t%0"
10539   [(set_attr "type" "negnot")
10540    (set_attr "mode" "QI")])
10541
10542 (define_insn "*negqi2_cmpz"
10543   [(set (reg:CCZ FLAGS_REG)
10544         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10545                      (const_int 0)))
10546    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10547         (neg:QI (match_dup 1)))]
10548   "ix86_unary_operator_ok (NEG, QImode, operands)"
10549   "neg{b}\t%0"
10550   [(set_attr "type" "negnot")
10551    (set_attr "mode" "QI")])
10552
10553 ;; Changing of sign for FP values is doable using integer unit too.
10554
10555 (define_expand "<code><mode>2"
10556   [(set (match_operand:X87MODEF 0 "register_operand" "")
10557         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10558   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10559   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10560
10561 (define_insn "*absneg<mode>2_mixed"
10562   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10563         (match_operator:MODEF 3 "absneg_operator"
10564           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10565    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10566    (clobber (reg:CC FLAGS_REG))]
10567   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10568   "#")
10569
10570 (define_insn "*absneg<mode>2_sse"
10571   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10572         (match_operator:MODEF 3 "absneg_operator"
10573           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10574    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10575    (clobber (reg:CC FLAGS_REG))]
10576   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10577   "#")
10578
10579 (define_insn "*absneg<mode>2_i387"
10580   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10581         (match_operator:X87MODEF 3 "absneg_operator"
10582           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10583    (use (match_operand 2 "" ""))
10584    (clobber (reg:CC FLAGS_REG))]
10585   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10586   "#")
10587
10588 (define_expand "<code>tf2"
10589   [(set (match_operand:TF 0 "register_operand" "")
10590         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10591   "TARGET_SSE2"
10592   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10593
10594 (define_insn "*absnegtf2_sse"
10595   [(set (match_operand:TF 0 "register_operand" "=x,x")
10596         (match_operator:TF 3 "absneg_operator"
10597           [(match_operand:TF 1 "register_operand" "0,x")]))
10598    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "TARGET_SSE2"
10601   "#")
10602
10603 ;; Splitters for fp abs and neg.
10604
10605 (define_split
10606   [(set (match_operand 0 "fp_register_operand" "")
10607         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10608    (use (match_operand 2 "" ""))
10609    (clobber (reg:CC FLAGS_REG))]
10610   "reload_completed"
10611   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10612
10613 (define_split
10614   [(set (match_operand 0 "register_operand" "")
10615         (match_operator 3 "absneg_operator"
10616           [(match_operand 1 "register_operand" "")]))
10617    (use (match_operand 2 "nonimmediate_operand" ""))
10618    (clobber (reg:CC FLAGS_REG))]
10619   "reload_completed && SSE_REG_P (operands[0])"
10620   [(set (match_dup 0) (match_dup 3))]
10621 {
10622   enum machine_mode mode = GET_MODE (operands[0]);
10623   enum machine_mode vmode = GET_MODE (operands[2]);
10624   rtx tmp;
10625
10626   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10627   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10628   if (operands_match_p (operands[0], operands[2]))
10629     {
10630       tmp = operands[1];
10631       operands[1] = operands[2];
10632       operands[2] = tmp;
10633     }
10634   if (GET_CODE (operands[3]) == ABS)
10635     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10636   else
10637     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10638   operands[3] = tmp;
10639 })
10640
10641 (define_split
10642   [(set (match_operand:SF 0 "register_operand" "")
10643         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10644    (use (match_operand:V4SF 2 "" ""))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "reload_completed"
10647   [(parallel [(set (match_dup 0) (match_dup 1))
10648               (clobber (reg:CC FLAGS_REG))])]
10649 {
10650   rtx tmp;
10651   operands[0] = gen_lowpart (SImode, operands[0]);
10652   if (GET_CODE (operands[1]) == ABS)
10653     {
10654       tmp = gen_int_mode (0x7fffffff, SImode);
10655       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10656     }
10657   else
10658     {
10659       tmp = gen_int_mode (0x80000000, SImode);
10660       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10661     }
10662   operands[1] = tmp;
10663 })
10664
10665 (define_split
10666   [(set (match_operand:DF 0 "register_operand" "")
10667         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10668    (use (match_operand 2 "" ""))
10669    (clobber (reg:CC FLAGS_REG))]
10670   "reload_completed"
10671   [(parallel [(set (match_dup 0) (match_dup 1))
10672               (clobber (reg:CC FLAGS_REG))])]
10673 {
10674   rtx tmp;
10675   if (TARGET_64BIT)
10676     {
10677       tmp = gen_lowpart (DImode, operands[0]);
10678       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10679       operands[0] = tmp;
10680
10681       if (GET_CODE (operands[1]) == ABS)
10682         tmp = const0_rtx;
10683       else
10684         tmp = gen_rtx_NOT (DImode, tmp);
10685     }
10686   else
10687     {
10688       operands[0] = gen_highpart (SImode, operands[0]);
10689       if (GET_CODE (operands[1]) == ABS)
10690         {
10691           tmp = gen_int_mode (0x7fffffff, SImode);
10692           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10693         }
10694       else
10695         {
10696           tmp = gen_int_mode (0x80000000, SImode);
10697           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10698         }
10699     }
10700   operands[1] = tmp;
10701 })
10702
10703 (define_split
10704   [(set (match_operand:XF 0 "register_operand" "")
10705         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10706    (use (match_operand 2 "" ""))
10707    (clobber (reg:CC FLAGS_REG))]
10708   "reload_completed"
10709   [(parallel [(set (match_dup 0) (match_dup 1))
10710               (clobber (reg:CC FLAGS_REG))])]
10711 {
10712   rtx tmp;
10713   operands[0] = gen_rtx_REG (SImode,
10714                              true_regnum (operands[0])
10715                              + (TARGET_64BIT ? 1 : 2));
10716   if (GET_CODE (operands[1]) == ABS)
10717     {
10718       tmp = GEN_INT (0x7fff);
10719       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10720     }
10721   else
10722     {
10723       tmp = GEN_INT (0x8000);
10724       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10725     }
10726   operands[1] = tmp;
10727 })
10728
10729 ;; Conditionalize these after reload. If they match before reload, we
10730 ;; lose the clobber and ability to use integer instructions.
10731
10732 (define_insn "*<code><mode>2_1"
10733   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10734         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10735   "TARGET_80387
10736    && (reload_completed
10737        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10738   "f<absnegprefix>"
10739   [(set_attr "type" "fsgn")
10740    (set_attr "mode" "<MODE>")])
10741
10742 (define_insn "*<code>extendsfdf2"
10743   [(set (match_operand:DF 0 "register_operand" "=f")
10744         (absneg:DF (float_extend:DF
10745                      (match_operand:SF 1 "register_operand" "0"))))]
10746   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10747   "f<absnegprefix>"
10748   [(set_attr "type" "fsgn")
10749    (set_attr "mode" "DF")])
10750
10751 (define_insn "*<code>extendsfxf2"
10752   [(set (match_operand:XF 0 "register_operand" "=f")
10753         (absneg:XF (float_extend:XF
10754                      (match_operand:SF 1 "register_operand" "0"))))]
10755   "TARGET_80387"
10756   "f<absnegprefix>"
10757   [(set_attr "type" "fsgn")
10758    (set_attr "mode" "XF")])
10759
10760 (define_insn "*<code>extenddfxf2"
10761   [(set (match_operand:XF 0 "register_operand" "=f")
10762         (absneg:XF (float_extend:XF
10763                       (match_operand:DF 1 "register_operand" "0"))))]
10764   "TARGET_80387"
10765   "f<absnegprefix>"
10766   [(set_attr "type" "fsgn")
10767    (set_attr "mode" "XF")])
10768
10769 ;; Copysign instructions
10770
10771 (define_mode_iterator CSGNMODE [SF DF TF])
10772 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10773
10774 (define_expand "copysign<mode>3"
10775   [(match_operand:CSGNMODE 0 "register_operand" "")
10776    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10777    (match_operand:CSGNMODE 2 "register_operand" "")]
10778   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10779    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10780 {
10781   ix86_expand_copysign (operands);
10782   DONE;
10783 })
10784
10785 (define_insn_and_split "copysign<mode>3_const"
10786   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10787         (unspec:CSGNMODE
10788           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10789            (match_operand:CSGNMODE 2 "register_operand" "0")
10790            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10791           UNSPEC_COPYSIGN))]
10792   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10793    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10794   "#"
10795   "&& reload_completed"
10796   [(const_int 0)]
10797 {
10798   ix86_split_copysign_const (operands);
10799   DONE;
10800 })
10801
10802 (define_insn "copysign<mode>3_var"
10803   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10804         (unspec:CSGNMODE
10805           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10806            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10807            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10808            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10809           UNSPEC_COPYSIGN))
10810    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10811   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10813   "#")
10814
10815 (define_split
10816   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10817         (unspec:CSGNMODE
10818           [(match_operand:CSGNMODE 2 "register_operand" "")
10819            (match_operand:CSGNMODE 3 "register_operand" "")
10820            (match_operand:<CSGNVMODE> 4 "" "")
10821            (match_operand:<CSGNVMODE> 5 "" "")]
10822           UNSPEC_COPYSIGN))
10823    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10824   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10825     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10826    && reload_completed"
10827   [(const_int 0)]
10828 {
10829   ix86_split_copysign_var (operands);
10830   DONE;
10831 })
10832 \f
10833 ;; One complement instructions
10834
10835 (define_expand "one_cmpldi2"
10836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10837         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10838   "TARGET_64BIT"
10839   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10840
10841 (define_insn "*one_cmpldi2_1_rex64"
10842   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10843         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10844   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10845   "not{q}\t%0"
10846   [(set_attr "type" "negnot")
10847    (set_attr "mode" "DI")])
10848
10849 (define_insn "*one_cmpldi2_2_rex64"
10850   [(set (reg FLAGS_REG)
10851         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10852                  (const_int 0)))
10853    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10854         (not:DI (match_dup 1)))]
10855   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10856    && ix86_unary_operator_ok (NOT, DImode, operands)"
10857   "#"
10858   [(set_attr "type" "alu1")
10859    (set_attr "mode" "DI")])
10860
10861 (define_split
10862   [(set (match_operand 0 "flags_reg_operand" "")
10863         (match_operator 2 "compare_operator"
10864           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10865            (const_int 0)]))
10866    (set (match_operand:DI 1 "nonimmediate_operand" "")
10867         (not:DI (match_dup 3)))]
10868   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10869   [(parallel [(set (match_dup 0)
10870                    (match_op_dup 2
10871                      [(xor:DI (match_dup 3) (const_int -1))
10872                       (const_int 0)]))
10873               (set (match_dup 1)
10874                    (xor:DI (match_dup 3) (const_int -1)))])]
10875   "")
10876
10877 (define_expand "one_cmplsi2"
10878   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10879         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10880   ""
10881   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10882
10883 (define_insn "*one_cmplsi2_1"
10884   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10885         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10886   "ix86_unary_operator_ok (NOT, SImode, operands)"
10887   "not{l}\t%0"
10888   [(set_attr "type" "negnot")
10889    (set_attr "mode" "SI")])
10890
10891 ;; ??? Currently never generated - xor is used instead.
10892 (define_insn "*one_cmplsi2_1_zext"
10893   [(set (match_operand:DI 0 "register_operand" "=r")
10894         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10895   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10896   "not{l}\t%k0"
10897   [(set_attr "type" "negnot")
10898    (set_attr "mode" "SI")])
10899
10900 (define_insn "*one_cmplsi2_2"
10901   [(set (reg FLAGS_REG)
10902         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10903                  (const_int 0)))
10904    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10905         (not:SI (match_dup 1)))]
10906   "ix86_match_ccmode (insn, CCNOmode)
10907    && ix86_unary_operator_ok (NOT, SImode, operands)"
10908   "#"
10909   [(set_attr "type" "alu1")
10910    (set_attr "mode" "SI")])
10911
10912 (define_split
10913   [(set (match_operand 0 "flags_reg_operand" "")
10914         (match_operator 2 "compare_operator"
10915           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10916            (const_int 0)]))
10917    (set (match_operand:SI 1 "nonimmediate_operand" "")
10918         (not:SI (match_dup 3)))]
10919   "ix86_match_ccmode (insn, CCNOmode)"
10920   [(parallel [(set (match_dup 0)
10921                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10922                                     (const_int 0)]))
10923               (set (match_dup 1)
10924                    (xor:SI (match_dup 3) (const_int -1)))])]
10925   "")
10926
10927 ;; ??? Currently never generated - xor is used instead.
10928 (define_insn "*one_cmplsi2_2_zext"
10929   [(set (reg FLAGS_REG)
10930         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10931                  (const_int 0)))
10932    (set (match_operand:DI 0 "register_operand" "=r")
10933         (zero_extend:DI (not:SI (match_dup 1))))]
10934   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10935    && ix86_unary_operator_ok (NOT, SImode, operands)"
10936   "#"
10937   [(set_attr "type" "alu1")
10938    (set_attr "mode" "SI")])
10939
10940 (define_split
10941   [(set (match_operand 0 "flags_reg_operand" "")
10942         (match_operator 2 "compare_operator"
10943           [(not:SI (match_operand:SI 3 "register_operand" ""))
10944            (const_int 0)]))
10945    (set (match_operand:DI 1 "register_operand" "")
10946         (zero_extend:DI (not:SI (match_dup 3))))]
10947   "ix86_match_ccmode (insn, CCNOmode)"
10948   [(parallel [(set (match_dup 0)
10949                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10950                                     (const_int 0)]))
10951               (set (match_dup 1)
10952                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10953   "")
10954
10955 (define_expand "one_cmplhi2"
10956   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10957         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10958   "TARGET_HIMODE_MATH"
10959   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10960
10961 (define_insn "*one_cmplhi2_1"
10962   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10963         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10964   "ix86_unary_operator_ok (NOT, HImode, operands)"
10965   "not{w}\t%0"
10966   [(set_attr "type" "negnot")
10967    (set_attr "mode" "HI")])
10968
10969 (define_insn "*one_cmplhi2_2"
10970   [(set (reg FLAGS_REG)
10971         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10972                  (const_int 0)))
10973    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10974         (not:HI (match_dup 1)))]
10975   "ix86_match_ccmode (insn, CCNOmode)
10976    && ix86_unary_operator_ok (NEG, HImode, operands)"
10977   "#"
10978   [(set_attr "type" "alu1")
10979    (set_attr "mode" "HI")])
10980
10981 (define_split
10982   [(set (match_operand 0 "flags_reg_operand" "")
10983         (match_operator 2 "compare_operator"
10984           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10985            (const_int 0)]))
10986    (set (match_operand:HI 1 "nonimmediate_operand" "")
10987         (not:HI (match_dup 3)))]
10988   "ix86_match_ccmode (insn, CCNOmode)"
10989   [(parallel [(set (match_dup 0)
10990                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10991                                     (const_int 0)]))
10992               (set (match_dup 1)
10993                    (xor:HI (match_dup 3) (const_int -1)))])]
10994   "")
10995
10996 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10997 (define_expand "one_cmplqi2"
10998   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10999         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11000   "TARGET_QIMODE_MATH"
11001   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11002
11003 (define_insn "*one_cmplqi2_1"
11004   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11005         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11006   "ix86_unary_operator_ok (NOT, QImode, operands)"
11007   "@
11008    not{b}\t%0
11009    not{l}\t%k0"
11010   [(set_attr "type" "negnot")
11011    (set_attr "mode" "QI,SI")])
11012
11013 (define_insn "*one_cmplqi2_2"
11014   [(set (reg FLAGS_REG)
11015         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11016                  (const_int 0)))
11017    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11018         (not:QI (match_dup 1)))]
11019   "ix86_match_ccmode (insn, CCNOmode)
11020    && ix86_unary_operator_ok (NOT, QImode, operands)"
11021   "#"
11022   [(set_attr "type" "alu1")
11023    (set_attr "mode" "QI")])
11024
11025 (define_split
11026   [(set (match_operand 0 "flags_reg_operand" "")
11027         (match_operator 2 "compare_operator"
11028           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11029            (const_int 0)]))
11030    (set (match_operand:QI 1 "nonimmediate_operand" "")
11031         (not:QI (match_dup 3)))]
11032   "ix86_match_ccmode (insn, CCNOmode)"
11033   [(parallel [(set (match_dup 0)
11034                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11035                                     (const_int 0)]))
11036               (set (match_dup 1)
11037                    (xor:QI (match_dup 3) (const_int -1)))])]
11038   "")
11039 \f
11040 ;; Arithmetic shift instructions
11041
11042 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11043 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11044 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11045 ;; from the assembler input.
11046 ;;
11047 ;; This instruction shifts the target reg/mem as usual, but instead of
11048 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11049 ;; is a left shift double, bits are taken from the high order bits of
11050 ;; reg, else if the insn is a shift right double, bits are taken from the
11051 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11052 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11053 ;;
11054 ;; Since sh[lr]d does not change the `reg' operand, that is done
11055 ;; separately, making all shifts emit pairs of shift double and normal
11056 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11057 ;; support a 63 bit shift, each shift where the count is in a reg expands
11058 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11059 ;;
11060 ;; If the shift count is a constant, we need never emit more than one
11061 ;; shift pair, instead using moves and sign extension for counts greater
11062 ;; than 31.
11063
11064 (define_expand "ashlti3"
11065   [(set (match_operand:TI 0 "register_operand" "")
11066         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11067                    (match_operand:QI 2 "nonmemory_operand" "")))]
11068   "TARGET_64BIT"
11069   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11070
11071 ;; This pattern must be defined before *ashlti3_1 to prevent
11072 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11073
11074 (define_insn "*avx_ashlti3"
11075   [(set (match_operand:TI 0 "register_operand" "=x")
11076         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11077                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11078   "TARGET_AVX"
11079 {
11080   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11081   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11082 }
11083   [(set_attr "type" "sseishft")
11084    (set_attr "prefix" "vex")
11085    (set_attr "mode" "TI")])
11086
11087 (define_insn "sse2_ashlti3"
11088   [(set (match_operand:TI 0 "register_operand" "=x")
11089         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11090                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11091   "TARGET_SSE2"
11092 {
11093   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11094   return "pslldq\t{%2, %0|%0, %2}";
11095 }
11096   [(set_attr "type" "sseishft")
11097    (set_attr "prefix_data16" "1")
11098    (set_attr "mode" "TI")])
11099
11100 (define_insn "*ashlti3_1"
11101   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11102         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11103                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11104    (clobber (reg:CC FLAGS_REG))]
11105   "TARGET_64BIT"
11106   "#"
11107   [(set_attr "type" "multi")])
11108
11109 (define_peephole2
11110   [(match_scratch:DI 3 "r")
11111    (parallel [(set (match_operand:TI 0 "register_operand" "")
11112                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11113                               (match_operand:QI 2 "nonmemory_operand" "")))
11114               (clobber (reg:CC FLAGS_REG))])
11115    (match_dup 3)]
11116   "TARGET_64BIT"
11117   [(const_int 0)]
11118   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11119
11120 (define_split
11121   [(set (match_operand:TI 0 "register_operand" "")
11122         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11123                    (match_operand:QI 2 "nonmemory_operand" "")))
11124    (clobber (reg:CC FLAGS_REG))]
11125   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11126                     ? epilogue_completed : reload_completed)"
11127   [(const_int 0)]
11128   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11129
11130 (define_insn "x86_64_shld"
11131   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11132         (ior:DI (ashift:DI (match_dup 0)
11133                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11134                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11135                   (minus:QI (const_int 64) (match_dup 2)))))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_64BIT"
11138   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11139   [(set_attr "type" "ishift")
11140    (set_attr "prefix_0f" "1")
11141    (set_attr "mode" "DI")
11142    (set_attr "athlon_decode" "vector")
11143    (set_attr "amdfam10_decode" "vector")])
11144
11145 (define_expand "x86_64_shift_adj_1"
11146   [(set (reg:CCZ FLAGS_REG)
11147         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11148                              (const_int 64))
11149                      (const_int 0)))
11150    (set (match_operand:DI 0 "register_operand" "")
11151         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11152                          (match_operand:DI 1 "register_operand" "")
11153                          (match_dup 0)))
11154    (set (match_dup 1)
11155         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11156                          (match_operand:DI 3 "register_operand" "r")
11157                          (match_dup 1)))]
11158   "TARGET_64BIT"
11159   "")
11160
11161 (define_expand "x86_64_shift_adj_2"
11162   [(use (match_operand:DI 0 "register_operand" ""))
11163    (use (match_operand:DI 1 "register_operand" ""))
11164    (use (match_operand:QI 2 "register_operand" ""))]
11165   "TARGET_64BIT"
11166 {
11167   rtx label = gen_label_rtx ();
11168   rtx tmp;
11169
11170   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11171
11172   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11173   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11174   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11175                               gen_rtx_LABEL_REF (VOIDmode, label),
11176                               pc_rtx);
11177   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11178   JUMP_LABEL (tmp) = label;
11179
11180   emit_move_insn (operands[0], operands[1]);
11181   ix86_expand_clear (operands[1]);
11182
11183   emit_label (label);
11184   LABEL_NUSES (label) = 1;
11185
11186   DONE;
11187 })
11188
11189 (define_expand "ashldi3"
11190   [(set (match_operand:DI 0 "shiftdi_operand" "")
11191         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11192                    (match_operand:QI 2 "nonmemory_operand" "")))]
11193   ""
11194   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11195
11196 (define_insn "*ashldi3_1_rex64"
11197   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11198         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11199                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11200    (clobber (reg:CC FLAGS_REG))]
11201   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11202 {
11203   switch (get_attr_type (insn))
11204     {
11205     case TYPE_ALU:
11206       gcc_assert (operands[2] == const1_rtx);
11207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11208       return "add{q}\t%0, %0";
11209
11210     case TYPE_LEA:
11211       gcc_assert (CONST_INT_P (operands[2]));
11212       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11213       operands[1] = gen_rtx_MULT (DImode, operands[1],
11214                                   GEN_INT (1 << INTVAL (operands[2])));
11215       return "lea{q}\t{%a1, %0|%0, %a1}";
11216
11217     default:
11218       if (REG_P (operands[2]))
11219         return "sal{q}\t{%b2, %0|%0, %b2}";
11220       else if (operands[2] == const1_rtx
11221                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11222         return "sal{q}\t%0";
11223       else
11224         return "sal{q}\t{%2, %0|%0, %2}";
11225     }
11226 }
11227   [(set (attr "type")
11228      (cond [(eq_attr "alternative" "1")
11229               (const_string "lea")
11230             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11231                           (const_int 0))
11232                       (match_operand 0 "register_operand" ""))
11233                  (match_operand 2 "const1_operand" ""))
11234               (const_string "alu")
11235            ]
11236            (const_string "ishift")))
11237    (set_attr "mode" "DI")])
11238
11239 ;; Convert lea to the lea pattern to avoid flags dependency.
11240 (define_split
11241   [(set (match_operand:DI 0 "register_operand" "")
11242         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11243                    (match_operand:QI 2 "immediate_operand" "")))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "TARGET_64BIT && reload_completed
11246    && true_regnum (operands[0]) != true_regnum (operands[1])"
11247   [(set (match_dup 0)
11248         (mult:DI (match_dup 1)
11249                  (match_dup 2)))]
11250   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11251
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags.  We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashldi3_cmp_rex64"
11256   [(set (reg FLAGS_REG)
11257         (compare
11258           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11259                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11260           (const_int 0)))
11261    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11262         (ashift:DI (match_dup 1) (match_dup 2)))]
11263   "TARGET_64BIT
11264    && (optimize_function_for_size_p (cfun)
11265        || !TARGET_PARTIAL_FLAG_REG_STALL
11266        || (operands[2] == const1_rtx
11267            && (TARGET_SHIFT1
11268                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11269    && ix86_match_ccmode (insn, CCGOCmode)
11270    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11271 {
11272   switch (get_attr_type (insn))
11273     {
11274     case TYPE_ALU:
11275       gcc_assert (operands[2] == const1_rtx);
11276       return "add{q}\t%0, %0";
11277
11278     default:
11279       if (REG_P (operands[2]))
11280         return "sal{q}\t{%b2, %0|%0, %b2}";
11281       else if (operands[2] == const1_rtx
11282                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11283         return "sal{q}\t%0";
11284       else
11285         return "sal{q}\t{%2, %0|%0, %2}";
11286     }
11287 }
11288   [(set (attr "type")
11289      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11290                           (const_int 0))
11291                       (match_operand 0 "register_operand" ""))
11292                  (match_operand 2 "const1_operand" ""))
11293               (const_string "alu")
11294            ]
11295            (const_string "ishift")))
11296    (set_attr "mode" "DI")])
11297
11298 (define_insn "*ashldi3_cconly_rex64"
11299   [(set (reg FLAGS_REG)
11300         (compare
11301           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11302                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11303           (const_int 0)))
11304    (clobber (match_scratch:DI 0 "=r"))]
11305   "TARGET_64BIT
11306    && (optimize_function_for_size_p (cfun)
11307        || !TARGET_PARTIAL_FLAG_REG_STALL
11308        || (operands[2] == const1_rtx
11309            && (TARGET_SHIFT1
11310                || TARGET_DOUBLE_WITH_ADD)))
11311    && ix86_match_ccmode (insn, CCGOCmode)
11312    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11313 {
11314   switch (get_attr_type (insn))
11315     {
11316     case TYPE_ALU:
11317       gcc_assert (operands[2] == const1_rtx);
11318       return "add{q}\t%0, %0";
11319
11320     default:
11321       if (REG_P (operands[2]))
11322         return "sal{q}\t{%b2, %0|%0, %b2}";
11323       else if (operands[2] == const1_rtx
11324                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11325         return "sal{q}\t%0";
11326       else
11327         return "sal{q}\t{%2, %0|%0, %2}";
11328     }
11329 }
11330   [(set (attr "type")
11331      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332                           (const_int 0))
11333                       (match_operand 0 "register_operand" ""))
11334                  (match_operand 2 "const1_operand" ""))
11335               (const_string "alu")
11336            ]
11337            (const_string "ishift")))
11338    (set_attr "mode" "DI")])
11339
11340 (define_insn "*ashldi3_1"
11341   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11342         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11343                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11344    (clobber (reg:CC FLAGS_REG))]
11345   "!TARGET_64BIT"
11346   "#"
11347   [(set_attr "type" "multi")])
11348
11349 ;; By default we don't ask for a scratch register, because when DImode
11350 ;; values are manipulated, registers are already at a premium.  But if
11351 ;; we have one handy, we won't turn it away.
11352 (define_peephole2
11353   [(match_scratch:SI 3 "r")
11354    (parallel [(set (match_operand:DI 0 "register_operand" "")
11355                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11356                               (match_operand:QI 2 "nonmemory_operand" "")))
11357               (clobber (reg:CC FLAGS_REG))])
11358    (match_dup 3)]
11359   "!TARGET_64BIT && TARGET_CMOVE"
11360   [(const_int 0)]
11361   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11362
11363 (define_split
11364   [(set (match_operand:DI 0 "register_operand" "")
11365         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11366                    (match_operand:QI 2 "nonmemory_operand" "")))
11367    (clobber (reg:CC FLAGS_REG))]
11368   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11369                      ? epilogue_completed : reload_completed)"
11370   [(const_int 0)]
11371   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11372
11373 (define_insn "x86_shld"
11374   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11375         (ior:SI (ashift:SI (match_dup 0)
11376                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11377                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11378                   (minus:QI (const_int 32) (match_dup 2)))))
11379    (clobber (reg:CC FLAGS_REG))]
11380   ""
11381   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11382   [(set_attr "type" "ishift")
11383    (set_attr "prefix_0f" "1")
11384    (set_attr "mode" "SI")
11385    (set_attr "pent_pair" "np")
11386    (set_attr "athlon_decode" "vector")
11387    (set_attr "amdfam10_decode" "vector")])
11388
11389 (define_expand "x86_shift_adj_1"
11390   [(set (reg:CCZ FLAGS_REG)
11391         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11392                              (const_int 32))
11393                      (const_int 0)))
11394    (set (match_operand:SI 0 "register_operand" "")
11395         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11396                          (match_operand:SI 1 "register_operand" "")
11397                          (match_dup 0)))
11398    (set (match_dup 1)
11399         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11400                          (match_operand:SI 3 "register_operand" "r")
11401                          (match_dup 1)))]
11402   "TARGET_CMOVE"
11403   "")
11404
11405 (define_expand "x86_shift_adj_2"
11406   [(use (match_operand:SI 0 "register_operand" ""))
11407    (use (match_operand:SI 1 "register_operand" ""))
11408    (use (match_operand:QI 2 "register_operand" ""))]
11409   ""
11410 {
11411   rtx label = gen_label_rtx ();
11412   rtx tmp;
11413
11414   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11415
11416   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11417   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11418   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11419                               gen_rtx_LABEL_REF (VOIDmode, label),
11420                               pc_rtx);
11421   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11422   JUMP_LABEL (tmp) = label;
11423
11424   emit_move_insn (operands[0], operands[1]);
11425   ix86_expand_clear (operands[1]);
11426
11427   emit_label (label);
11428   LABEL_NUSES (label) = 1;
11429
11430   DONE;
11431 })
11432
11433 (define_expand "ashlsi3"
11434   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11435         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11436                    (match_operand:QI 2 "nonmemory_operand" "")))]
11437   ""
11438   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11439
11440 (define_insn "*ashlsi3_1"
11441   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11442         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11443                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11444    (clobber (reg:CC FLAGS_REG))]
11445   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11446 {
11447   switch (get_attr_type (insn))
11448     {
11449     case TYPE_ALU:
11450       gcc_assert (operands[2] == const1_rtx);
11451       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11452       return "add{l}\t%0, %0";
11453
11454     case TYPE_LEA:
11455       return "#";
11456
11457     default:
11458       if (REG_P (operands[2]))
11459         return "sal{l}\t{%b2, %0|%0, %b2}";
11460       else if (operands[2] == const1_rtx
11461                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11462         return "sal{l}\t%0";
11463       else
11464         return "sal{l}\t{%2, %0|%0, %2}";
11465     }
11466 }
11467   [(set (attr "type")
11468      (cond [(eq_attr "alternative" "1")
11469               (const_string "lea")
11470             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11471                           (const_int 0))
11472                       (match_operand 0 "register_operand" ""))
11473                  (match_operand 2 "const1_operand" ""))
11474               (const_string "alu")
11475            ]
11476            (const_string "ishift")))
11477    (set_attr "mode" "SI")])
11478
11479 ;; Convert lea to the lea pattern to avoid flags dependency.
11480 (define_split
11481   [(set (match_operand 0 "register_operand" "")
11482         (ashift (match_operand 1 "index_register_operand" "")
11483                 (match_operand:QI 2 "const_int_operand" "")))
11484    (clobber (reg:CC FLAGS_REG))]
11485   "reload_completed
11486    && true_regnum (operands[0]) != true_regnum (operands[1])
11487    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11488   [(const_int 0)]
11489 {
11490   rtx pat;
11491   enum machine_mode mode = GET_MODE (operands[0]);
11492
11493   if (GET_MODE_SIZE (mode) < 4)
11494     operands[0] = gen_lowpart (SImode, operands[0]);
11495   if (mode != Pmode)
11496     operands[1] = gen_lowpart (Pmode, operands[1]);
11497   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11498
11499   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11500   if (Pmode != SImode)
11501     pat = gen_rtx_SUBREG (SImode, pat, 0);
11502   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11503   DONE;
11504 })
11505
11506 ;; Rare case of shifting RSP is handled by generating move and shift
11507 (define_split
11508   [(set (match_operand 0 "register_operand" "")
11509         (ashift (match_operand 1 "register_operand" "")
11510                 (match_operand:QI 2 "const_int_operand" "")))
11511    (clobber (reg:CC FLAGS_REG))]
11512   "reload_completed
11513    && true_regnum (operands[0]) != true_regnum (operands[1])"
11514   [(const_int 0)]
11515 {
11516   rtx pat, clob;
11517   emit_move_insn (operands[0], operands[1]);
11518   pat = gen_rtx_SET (VOIDmode, operands[0],
11519                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11520                                      operands[0], operands[2]));
11521   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11522   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11523   DONE;
11524 })
11525
11526 (define_insn "*ashlsi3_1_zext"
11527   [(set (match_operand:DI 0 "register_operand" "=r,r")
11528         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11529                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11530    (clobber (reg:CC FLAGS_REG))]
11531   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11532 {
11533   switch (get_attr_type (insn))
11534     {
11535     case TYPE_ALU:
11536       gcc_assert (operands[2] == const1_rtx);
11537       return "add{l}\t%k0, %k0";
11538
11539     case TYPE_LEA:
11540       return "#";
11541
11542     default:
11543       if (REG_P (operands[2]))
11544         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11545       else if (operands[2] == const1_rtx
11546                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11547         return "sal{l}\t%k0";
11548       else
11549         return "sal{l}\t{%2, %k0|%k0, %2}";
11550     }
11551 }
11552   [(set (attr "type")
11553      (cond [(eq_attr "alternative" "1")
11554               (const_string "lea")
11555             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11556                      (const_int 0))
11557                  (match_operand 2 "const1_operand" ""))
11558               (const_string "alu")
11559            ]
11560            (const_string "ishift")))
11561    (set_attr "mode" "SI")])
11562
11563 ;; Convert lea to the lea pattern to avoid flags dependency.
11564 (define_split
11565   [(set (match_operand:DI 0 "register_operand" "")
11566         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11567                                 (match_operand:QI 2 "const_int_operand" ""))))
11568    (clobber (reg:CC FLAGS_REG))]
11569   "TARGET_64BIT && reload_completed
11570    && true_regnum (operands[0]) != true_regnum (operands[1])"
11571   [(set (match_dup 0) (zero_extend:DI
11572                         (subreg:SI (mult:SI (match_dup 1)
11573                                             (match_dup 2)) 0)))]
11574 {
11575   operands[1] = gen_lowpart (Pmode, operands[1]);
11576   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11577 })
11578
11579 ;; This pattern can't accept a variable shift count, since shifts by
11580 ;; zero don't affect the flags.  We assume that shifts by constant
11581 ;; zero are optimized away.
11582 (define_insn "*ashlsi3_cmp"
11583   [(set (reg FLAGS_REG)
11584         (compare
11585           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11586                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11587           (const_int 0)))
11588    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11589         (ashift:SI (match_dup 1) (match_dup 2)))]
11590    "(optimize_function_for_size_p (cfun)
11591      || !TARGET_PARTIAL_FLAG_REG_STALL
11592      || (operands[2] == const1_rtx
11593          && (TARGET_SHIFT1
11594              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11595    && ix86_match_ccmode (insn, CCGOCmode)
11596    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11597 {
11598   switch (get_attr_type (insn))
11599     {
11600     case TYPE_ALU:
11601       gcc_assert (operands[2] == const1_rtx);
11602       return "add{l}\t%0, %0";
11603
11604     default:
11605       if (REG_P (operands[2]))
11606         return "sal{l}\t{%b2, %0|%0, %b2}";
11607       else if (operands[2] == const1_rtx
11608                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11609         return "sal{l}\t%0";
11610       else
11611         return "sal{l}\t{%2, %0|%0, %2}";
11612     }
11613 }
11614   [(set (attr "type")
11615      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11616                           (const_int 0))
11617                       (match_operand 0 "register_operand" ""))
11618                  (match_operand 2 "const1_operand" ""))
11619               (const_string "alu")
11620            ]
11621            (const_string "ishift")))
11622    (set_attr "mode" "SI")])
11623
11624 (define_insn "*ashlsi3_cconly"
11625   [(set (reg FLAGS_REG)
11626         (compare
11627           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11628                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11629           (const_int 0)))
11630    (clobber (match_scratch:SI 0 "=r"))]
11631   "(optimize_function_for_size_p (cfun)
11632     || !TARGET_PARTIAL_FLAG_REG_STALL
11633     || (operands[2] == const1_rtx
11634         && (TARGET_SHIFT1
11635             || TARGET_DOUBLE_WITH_ADD)))
11636    && ix86_match_ccmode (insn, CCGOCmode)
11637    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11638 {
11639   switch (get_attr_type (insn))
11640     {
11641     case TYPE_ALU:
11642       gcc_assert (operands[2] == const1_rtx);
11643       return "add{l}\t%0, %0";
11644
11645     default:
11646       if (REG_P (operands[2]))
11647         return "sal{l}\t{%b2, %0|%0, %b2}";
11648       else if (operands[2] == const1_rtx
11649                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11650         return "sal{l}\t%0";
11651       else
11652         return "sal{l}\t{%2, %0|%0, %2}";
11653     }
11654 }
11655   [(set (attr "type")
11656      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11657                           (const_int 0))
11658                       (match_operand 0 "register_operand" ""))
11659                  (match_operand 2 "const1_operand" ""))
11660               (const_string "alu")
11661            ]
11662            (const_string "ishift")))
11663    (set_attr "mode" "SI")])
11664
11665 (define_insn "*ashlsi3_cmp_zext"
11666   [(set (reg FLAGS_REG)
11667         (compare
11668           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11669                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11670           (const_int 0)))
11671    (set (match_operand:DI 0 "register_operand" "=r")
11672         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11673   "TARGET_64BIT
11674    && (optimize_function_for_size_p (cfun)
11675        || !TARGET_PARTIAL_FLAG_REG_STALL
11676        || (operands[2] == const1_rtx
11677            && (TARGET_SHIFT1
11678                || TARGET_DOUBLE_WITH_ADD)))
11679    && ix86_match_ccmode (insn, CCGOCmode)
11680    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11681 {
11682   switch (get_attr_type (insn))
11683     {
11684     case TYPE_ALU:
11685       gcc_assert (operands[2] == const1_rtx);
11686       return "add{l}\t%k0, %k0";
11687
11688     default:
11689       if (REG_P (operands[2]))
11690         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11691       else if (operands[2] == const1_rtx
11692                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11693         return "sal{l}\t%k0";
11694       else
11695         return "sal{l}\t{%2, %k0|%k0, %2}";
11696     }
11697 }
11698   [(set (attr "type")
11699      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700                      (const_int 0))
11701                  (match_operand 2 "const1_operand" ""))
11702               (const_string "alu")
11703            ]
11704            (const_string "ishift")))
11705    (set_attr "mode" "SI")])
11706
11707 (define_expand "ashlhi3"
11708   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11709         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11710                    (match_operand:QI 2 "nonmemory_operand" "")))]
11711   "TARGET_HIMODE_MATH"
11712   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11713
11714 (define_insn "*ashlhi3_1_lea"
11715   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11716         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11717                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11718    (clobber (reg:CC FLAGS_REG))]
11719   "!TARGET_PARTIAL_REG_STALL
11720    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11721 {
11722   switch (get_attr_type (insn))
11723     {
11724     case TYPE_LEA:
11725       return "#";
11726     case TYPE_ALU:
11727       gcc_assert (operands[2] == const1_rtx);
11728       return "add{w}\t%0, %0";
11729
11730     default:
11731       if (REG_P (operands[2]))
11732         return "sal{w}\t{%b2, %0|%0, %b2}";
11733       else if (operands[2] == const1_rtx
11734                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11735         return "sal{w}\t%0";
11736       else
11737         return "sal{w}\t{%2, %0|%0, %2}";
11738     }
11739 }
11740   [(set (attr "type")
11741      (cond [(eq_attr "alternative" "1")
11742               (const_string "lea")
11743             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11744                           (const_int 0))
11745                       (match_operand 0 "register_operand" ""))
11746                  (match_operand 2 "const1_operand" ""))
11747               (const_string "alu")
11748            ]
11749            (const_string "ishift")))
11750    (set_attr "mode" "HI,SI")])
11751
11752 (define_insn "*ashlhi3_1"
11753   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11755                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "TARGET_PARTIAL_REG_STALL
11758    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11759 {
11760   switch (get_attr_type (insn))
11761     {
11762     case TYPE_ALU:
11763       gcc_assert (operands[2] == const1_rtx);
11764       return "add{w}\t%0, %0";
11765
11766     default:
11767       if (REG_P (operands[2]))
11768         return "sal{w}\t{%b2, %0|%0, %b2}";
11769       else if (operands[2] == const1_rtx
11770                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11771         return "sal{w}\t%0";
11772       else
11773         return "sal{w}\t{%2, %0|%0, %2}";
11774     }
11775 }
11776   [(set (attr "type")
11777      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778                           (const_int 0))
11779                       (match_operand 0 "register_operand" ""))
11780                  (match_operand 2 "const1_operand" ""))
11781               (const_string "alu")
11782            ]
11783            (const_string "ishift")))
11784    (set_attr "mode" "HI")])
11785
11786 ;; This pattern can't accept a variable shift count, since shifts by
11787 ;; zero don't affect the flags.  We assume that shifts by constant
11788 ;; zero are optimized away.
11789 (define_insn "*ashlhi3_cmp"
11790   [(set (reg FLAGS_REG)
11791         (compare
11792           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11793                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11794           (const_int 0)))
11795    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11796         (ashift:HI (match_dup 1) (match_dup 2)))]
11797   "(optimize_function_for_size_p (cfun)
11798     || !TARGET_PARTIAL_FLAG_REG_STALL
11799     || (operands[2] == const1_rtx
11800         && (TARGET_SHIFT1
11801             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11802    && ix86_match_ccmode (insn, CCGOCmode)
11803    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11804 {
11805   switch (get_attr_type (insn))
11806     {
11807     case TYPE_ALU:
11808       gcc_assert (operands[2] == const1_rtx);
11809       return "add{w}\t%0, %0";
11810
11811     default:
11812       if (REG_P (operands[2]))
11813         return "sal{w}\t{%b2, %0|%0, %b2}";
11814       else if (operands[2] == const1_rtx
11815                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11816         return "sal{w}\t%0";
11817       else
11818         return "sal{w}\t{%2, %0|%0, %2}";
11819     }
11820 }
11821   [(set (attr "type")
11822      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11823                           (const_int 0))
11824                       (match_operand 0 "register_operand" ""))
11825                  (match_operand 2 "const1_operand" ""))
11826               (const_string "alu")
11827            ]
11828            (const_string "ishift")))
11829    (set_attr "mode" "HI")])
11830
11831 (define_insn "*ashlhi3_cconly"
11832   [(set (reg FLAGS_REG)
11833         (compare
11834           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11835                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11836           (const_int 0)))
11837    (clobber (match_scratch:HI 0 "=r"))]
11838   "(optimize_function_for_size_p (cfun)
11839     || !TARGET_PARTIAL_FLAG_REG_STALL
11840     || (operands[2] == const1_rtx
11841         && (TARGET_SHIFT1
11842             || TARGET_DOUBLE_WITH_ADD)))
11843    && ix86_match_ccmode (insn, CCGOCmode)
11844    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11845 {
11846   switch (get_attr_type (insn))
11847     {
11848     case TYPE_ALU:
11849       gcc_assert (operands[2] == const1_rtx);
11850       return "add{w}\t%0, %0";
11851
11852     default:
11853       if (REG_P (operands[2]))
11854         return "sal{w}\t{%b2, %0|%0, %b2}";
11855       else if (operands[2] == const1_rtx
11856                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11857         return "sal{w}\t%0";
11858       else
11859         return "sal{w}\t{%2, %0|%0, %2}";
11860     }
11861 }
11862   [(set (attr "type")
11863      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11864                           (const_int 0))
11865                       (match_operand 0 "register_operand" ""))
11866                  (match_operand 2 "const1_operand" ""))
11867               (const_string "alu")
11868            ]
11869            (const_string "ishift")))
11870    (set_attr "mode" "HI")])
11871
11872 (define_expand "ashlqi3"
11873   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11874         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11875                    (match_operand:QI 2 "nonmemory_operand" "")))]
11876   "TARGET_QIMODE_MATH"
11877   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11878
11879 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11880
11881 (define_insn "*ashlqi3_1_lea"
11882   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11883         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11884                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "!TARGET_PARTIAL_REG_STALL
11887    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11888 {
11889   switch (get_attr_type (insn))
11890     {
11891     case TYPE_LEA:
11892       return "#";
11893     case TYPE_ALU:
11894       gcc_assert (operands[2] == const1_rtx);
11895       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11896         return "add{l}\t%k0, %k0";
11897       else
11898         return "add{b}\t%0, %0";
11899
11900     default:
11901       if (REG_P (operands[2]))
11902         {
11903           if (get_attr_mode (insn) == MODE_SI)
11904             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11905           else
11906             return "sal{b}\t{%b2, %0|%0, %b2}";
11907         }
11908       else if (operands[2] == const1_rtx
11909                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11910         {
11911           if (get_attr_mode (insn) == MODE_SI)
11912             return "sal{l}\t%0";
11913           else
11914             return "sal{b}\t%0";
11915         }
11916       else
11917         {
11918           if (get_attr_mode (insn) == MODE_SI)
11919             return "sal{l}\t{%2, %k0|%k0, %2}";
11920           else
11921             return "sal{b}\t{%2, %0|%0, %2}";
11922         }
11923     }
11924 }
11925   [(set (attr "type")
11926      (cond [(eq_attr "alternative" "2")
11927               (const_string "lea")
11928             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11929                           (const_int 0))
11930                       (match_operand 0 "register_operand" ""))
11931                  (match_operand 2 "const1_operand" ""))
11932               (const_string "alu")
11933            ]
11934            (const_string "ishift")))
11935    (set_attr "mode" "QI,SI,SI")])
11936
11937 (define_insn "*ashlqi3_1"
11938   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11939         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11940                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11941    (clobber (reg:CC FLAGS_REG))]
11942   "TARGET_PARTIAL_REG_STALL
11943    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11944 {
11945   switch (get_attr_type (insn))
11946     {
11947     case TYPE_ALU:
11948       gcc_assert (operands[2] == const1_rtx);
11949       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11950         return "add{l}\t%k0, %k0";
11951       else
11952         return "add{b}\t%0, %0";
11953
11954     default:
11955       if (REG_P (operands[2]))
11956         {
11957           if (get_attr_mode (insn) == MODE_SI)
11958             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11959           else
11960             return "sal{b}\t{%b2, %0|%0, %b2}";
11961         }
11962       else if (operands[2] == const1_rtx
11963                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11964         {
11965           if (get_attr_mode (insn) == MODE_SI)
11966             return "sal{l}\t%0";
11967           else
11968             return "sal{b}\t%0";
11969         }
11970       else
11971         {
11972           if (get_attr_mode (insn) == MODE_SI)
11973             return "sal{l}\t{%2, %k0|%k0, %2}";
11974           else
11975             return "sal{b}\t{%2, %0|%0, %2}";
11976         }
11977     }
11978 }
11979   [(set (attr "type")
11980      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11981                           (const_int 0))
11982                       (match_operand 0 "register_operand" ""))
11983                  (match_operand 2 "const1_operand" ""))
11984               (const_string "alu")
11985            ]
11986            (const_string "ishift")))
11987    (set_attr "mode" "QI,SI")])
11988
11989 ;; This pattern can't accept a variable shift count, since shifts by
11990 ;; zero don't affect the flags.  We assume that shifts by constant
11991 ;; zero are optimized away.
11992 (define_insn "*ashlqi3_cmp"
11993   [(set (reg FLAGS_REG)
11994         (compare
11995           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11996                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11997           (const_int 0)))
11998    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11999         (ashift:QI (match_dup 1) (match_dup 2)))]
12000   "(optimize_function_for_size_p (cfun)
12001     || !TARGET_PARTIAL_FLAG_REG_STALL
12002     || (operands[2] == const1_rtx
12003         && (TARGET_SHIFT1
12004             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12005    && ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12007 {
12008   switch (get_attr_type (insn))
12009     {
12010     case TYPE_ALU:
12011       gcc_assert (operands[2] == const1_rtx);
12012       return "add{b}\t%0, %0";
12013
12014     default:
12015       if (REG_P (operands[2]))
12016         return "sal{b}\t{%b2, %0|%0, %b2}";
12017       else if (operands[2] == const1_rtx
12018                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12019         return "sal{b}\t%0";
12020       else
12021         return "sal{b}\t{%2, %0|%0, %2}";
12022     }
12023 }
12024   [(set (attr "type")
12025      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12026                           (const_int 0))
12027                       (match_operand 0 "register_operand" ""))
12028                  (match_operand 2 "const1_operand" ""))
12029               (const_string "alu")
12030            ]
12031            (const_string "ishift")))
12032    (set_attr "mode" "QI")])
12033
12034 (define_insn "*ashlqi3_cconly"
12035   [(set (reg FLAGS_REG)
12036         (compare
12037           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12038                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12039           (const_int 0)))
12040    (clobber (match_scratch:QI 0 "=q"))]
12041   "(optimize_function_for_size_p (cfun)
12042     || !TARGET_PARTIAL_FLAG_REG_STALL
12043     || (operands[2] == const1_rtx
12044         && (TARGET_SHIFT1
12045             || TARGET_DOUBLE_WITH_ADD)))
12046    && ix86_match_ccmode (insn, CCGOCmode)
12047    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12048 {
12049   switch (get_attr_type (insn))
12050     {
12051     case TYPE_ALU:
12052       gcc_assert (operands[2] == const1_rtx);
12053       return "add{b}\t%0, %0";
12054
12055     default:
12056       if (REG_P (operands[2]))
12057         return "sal{b}\t{%b2, %0|%0, %b2}";
12058       else if (operands[2] == const1_rtx
12059                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12060         return "sal{b}\t%0";
12061       else
12062         return "sal{b}\t{%2, %0|%0, %2}";
12063     }
12064 }
12065   [(set (attr "type")
12066      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12067                           (const_int 0))
12068                       (match_operand 0 "register_operand" ""))
12069                  (match_operand 2 "const1_operand" ""))
12070               (const_string "alu")
12071            ]
12072            (const_string "ishift")))
12073    (set_attr "mode" "QI")])
12074
12075 ;; See comment above `ashldi3' about how this works.
12076
12077 (define_expand "ashrti3"
12078   [(set (match_operand:TI 0 "register_operand" "")
12079         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12080                      (match_operand:QI 2 "nonmemory_operand" "")))]
12081   "TARGET_64BIT"
12082   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12083
12084 (define_insn "*ashrti3_1"
12085   [(set (match_operand:TI 0 "register_operand" "=r")
12086         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12087                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "TARGET_64BIT"
12090   "#"
12091   [(set_attr "type" "multi")])
12092
12093 (define_peephole2
12094   [(match_scratch:DI 3 "r")
12095    (parallel [(set (match_operand:TI 0 "register_operand" "")
12096                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12097                                 (match_operand:QI 2 "nonmemory_operand" "")))
12098               (clobber (reg:CC FLAGS_REG))])
12099    (match_dup 3)]
12100   "TARGET_64BIT"
12101   [(const_int 0)]
12102   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12103
12104 (define_split
12105   [(set (match_operand:TI 0 "register_operand" "")
12106         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12107                      (match_operand:QI 2 "nonmemory_operand" "")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12110                     ? epilogue_completed : reload_completed)"
12111   [(const_int 0)]
12112   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12113
12114 (define_insn "x86_64_shrd"
12115   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12116         (ior:DI (ashiftrt:DI (match_dup 0)
12117                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12118                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12119                   (minus:QI (const_int 64) (match_dup 2)))))
12120    (clobber (reg:CC FLAGS_REG))]
12121   "TARGET_64BIT"
12122   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12123   [(set_attr "type" "ishift")
12124    (set_attr "prefix_0f" "1")
12125    (set_attr "mode" "DI")
12126    (set_attr "athlon_decode" "vector")
12127    (set_attr "amdfam10_decode" "vector")])
12128
12129 (define_expand "ashrdi3"
12130   [(set (match_operand:DI 0 "shiftdi_operand" "")
12131         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12132                      (match_operand:QI 2 "nonmemory_operand" "")))]
12133   ""
12134   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12135
12136 (define_expand "x86_64_shift_adj_3"
12137   [(use (match_operand:DI 0 "register_operand" ""))
12138    (use (match_operand:DI 1 "register_operand" ""))
12139    (use (match_operand:QI 2 "register_operand" ""))]
12140   ""
12141 {
12142   rtx label = gen_label_rtx ();
12143   rtx tmp;
12144
12145   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12146
12147   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12148   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12149   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12150                               gen_rtx_LABEL_REF (VOIDmode, label),
12151                               pc_rtx);
12152   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12153   JUMP_LABEL (tmp) = label;
12154
12155   emit_move_insn (operands[0], operands[1]);
12156   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12157
12158   emit_label (label);
12159   LABEL_NUSES (label) = 1;
12160
12161   DONE;
12162 })
12163
12164 (define_insn "ashrdi3_63_rex64"
12165   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12166         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12167                      (match_operand:DI 2 "const_int_operand" "i,i")))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_64BIT && INTVAL (operands[2]) == 63
12170    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12171    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12172   "@
12173    {cqto|cqo}
12174    sar{q}\t{%2, %0|%0, %2}"
12175   [(set_attr "type" "imovx,ishift")
12176    (set_attr "prefix_0f" "0,*")
12177    (set_attr "length_immediate" "0,*")
12178    (set_attr "modrm" "0,1")
12179    (set_attr "mode" "DI")])
12180
12181 (define_insn "*ashrdi3_1_one_bit_rex64"
12182   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12183         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12184                      (match_operand:QI 2 "const1_operand" "")))
12185    (clobber (reg:CC FLAGS_REG))]
12186   "TARGET_64BIT
12187    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12188    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12189   "sar{q}\t%0"
12190   [(set_attr "type" "ishift")
12191    (set (attr "length")
12192      (if_then_else (match_operand:DI 0 "register_operand" "")
12193         (const_string "2")
12194         (const_string "*")))])
12195
12196 (define_insn "*ashrdi3_1_rex64"
12197   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12198         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12199                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12202   "@
12203    sar{q}\t{%2, %0|%0, %2}
12204    sar{q}\t{%b2, %0|%0, %b2}"
12205   [(set_attr "type" "ishift")
12206    (set_attr "mode" "DI")])
12207
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags.  We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12212   [(set (reg FLAGS_REG)
12213         (compare
12214           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12215                        (match_operand:QI 2 "const1_operand" ""))
12216           (const_int 0)))
12217    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12218         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12219   "TARGET_64BIT
12220    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12221    && ix86_match_ccmode (insn, CCGOCmode)
12222    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12223   "sar{q}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set (attr "length")
12226      (if_then_else (match_operand:DI 0 "register_operand" "")
12227         (const_string "2")
12228         (const_string "*")))])
12229
12230 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" ""))
12235           (const_int 0)))
12236    (clobber (match_scratch:DI 0 "=r"))]
12237   "TARGET_64BIT
12238    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12239    && ix86_match_ccmode (insn, CCGOCmode)
12240    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12241   "sar{q}\t%0"
12242   [(set_attr "type" "ishift")
12243    (set_attr "length" "2")])
12244
12245 ;; This pattern can't accept a variable shift count, since shifts by
12246 ;; zero don't affect the flags.  We assume that shifts by constant
12247 ;; zero are optimized away.
12248 (define_insn "*ashrdi3_cmp_rex64"
12249   [(set (reg FLAGS_REG)
12250         (compare
12251           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12252                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12253           (const_int 0)))
12254    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12255         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12256   "TARGET_64BIT
12257    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12258    && ix86_match_ccmode (insn, CCGOCmode)
12259    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12260   "sar{q}\t{%2, %0|%0, %2}"
12261   [(set_attr "type" "ishift")
12262    (set_attr "mode" "DI")])
12263
12264 (define_insn "*ashrdi3_cconly_rex64"
12265   [(set (reg FLAGS_REG)
12266         (compare
12267           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12268                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12269           (const_int 0)))
12270    (clobber (match_scratch:DI 0 "=r"))]
12271   "TARGET_64BIT
12272    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12273    && ix86_match_ccmode (insn, CCGOCmode)
12274    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12275   "sar{q}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "DI")])
12278
12279 (define_insn "*ashrdi3_1"
12280   [(set (match_operand:DI 0 "register_operand" "=r")
12281         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12282                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12283    (clobber (reg:CC FLAGS_REG))]
12284   "!TARGET_64BIT"
12285   "#"
12286   [(set_attr "type" "multi")])
12287
12288 ;; By default we don't ask for a scratch register, because when DImode
12289 ;; values are manipulated, registers are already at a premium.  But if
12290 ;; we have one handy, we won't turn it away.
12291 (define_peephole2
12292   [(match_scratch:SI 3 "r")
12293    (parallel [(set (match_operand:DI 0 "register_operand" "")
12294                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12295                                 (match_operand:QI 2 "nonmemory_operand" "")))
12296               (clobber (reg:CC FLAGS_REG))])
12297    (match_dup 3)]
12298   "!TARGET_64BIT && TARGET_CMOVE"
12299   [(const_int 0)]
12300   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12301
12302 (define_split
12303   [(set (match_operand:DI 0 "register_operand" "")
12304         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12305                      (match_operand:QI 2 "nonmemory_operand" "")))
12306    (clobber (reg:CC FLAGS_REG))]
12307   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12308                      ? epilogue_completed : reload_completed)"
12309   [(const_int 0)]
12310   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12311
12312 (define_insn "x86_shrd"
12313   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12314         (ior:SI (ashiftrt:SI (match_dup 0)
12315                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12316                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12317                   (minus:QI (const_int 32) (match_dup 2)))))
12318    (clobber (reg:CC FLAGS_REG))]
12319   ""
12320   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12321   [(set_attr "type" "ishift")
12322    (set_attr "prefix_0f" "1")
12323    (set_attr "pent_pair" "np")
12324    (set_attr "mode" "SI")])
12325
12326 (define_expand "x86_shift_adj_3"
12327   [(use (match_operand:SI 0 "register_operand" ""))
12328    (use (match_operand:SI 1 "register_operand" ""))
12329    (use (match_operand:QI 2 "register_operand" ""))]
12330   ""
12331 {
12332   rtx label = gen_label_rtx ();
12333   rtx tmp;
12334
12335   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12336
12337   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12338   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12339   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12340                               gen_rtx_LABEL_REF (VOIDmode, label),
12341                               pc_rtx);
12342   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12343   JUMP_LABEL (tmp) = label;
12344
12345   emit_move_insn (operands[0], operands[1]);
12346   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12347
12348   emit_label (label);
12349   LABEL_NUSES (label) = 1;
12350
12351   DONE;
12352 })
12353
12354 (define_expand "ashrsi3_31"
12355   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12356                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12357                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12358               (clobber (reg:CC FLAGS_REG))])]
12359   "")
12360
12361 (define_insn "*ashrsi3_31"
12362   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12363         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12364                      (match_operand:SI 2 "const_int_operand" "i,i")))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "INTVAL (operands[2]) == 31
12367    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12368    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12369   "@
12370    {cltd|cdq}
12371    sar{l}\t{%2, %0|%0, %2}"
12372   [(set_attr "type" "imovx,ishift")
12373    (set_attr "prefix_0f" "0,*")
12374    (set_attr "length_immediate" "0,*")
12375    (set_attr "modrm" "0,1")
12376    (set_attr "mode" "SI")])
12377
12378 (define_insn "*ashrsi3_31_zext"
12379   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12380         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12381                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12382    (clobber (reg:CC FLAGS_REG))]
12383   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12384    && INTVAL (operands[2]) == 31
12385    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12386   "@
12387    {cltd|cdq}
12388    sar{l}\t{%2, %k0|%k0, %2}"
12389   [(set_attr "type" "imovx,ishift")
12390    (set_attr "prefix_0f" "0,*")
12391    (set_attr "length_immediate" "0,*")
12392    (set_attr "modrm" "0,1")
12393    (set_attr "mode" "SI")])
12394
12395 (define_expand "ashrsi3"
12396   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12397         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12398                      (match_operand:QI 2 "nonmemory_operand" "")))]
12399   ""
12400   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12401
12402 (define_insn "*ashrsi3_1_one_bit"
12403   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12404         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12405                      (match_operand:QI 2 "const1_operand" "")))
12406    (clobber (reg:CC FLAGS_REG))]
12407   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12409   "sar{l}\t%0"
12410   [(set_attr "type" "ishift")
12411    (set (attr "length")
12412      (if_then_else (match_operand:SI 0 "register_operand" "")
12413         (const_string "2")
12414         (const_string "*")))])
12415
12416 (define_insn "*ashrsi3_1_one_bit_zext"
12417   [(set (match_operand:DI 0 "register_operand" "=r")
12418         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12419                                      (match_operand:QI 2 "const1_operand" ""))))
12420    (clobber (reg:CC FLAGS_REG))]
12421   "TARGET_64BIT
12422    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12423    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12424   "sar{l}\t%k0"
12425   [(set_attr "type" "ishift")
12426    (set_attr "length" "2")])
12427
12428 (define_insn "*ashrsi3_1"
12429   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12430         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12431                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12432    (clobber (reg:CC FLAGS_REG))]
12433   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12434   "@
12435    sar{l}\t{%2, %0|%0, %2}
12436    sar{l}\t{%b2, %0|%0, %b2}"
12437   [(set_attr "type" "ishift")
12438    (set_attr "mode" "SI")])
12439
12440 (define_insn "*ashrsi3_1_zext"
12441   [(set (match_operand:DI 0 "register_operand" "=r,r")
12442         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12443                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12444    (clobber (reg:CC FLAGS_REG))]
12445   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12446   "@
12447    sar{l}\t{%2, %k0|%k0, %2}
12448    sar{l}\t{%b2, %k0|%k0, %b2}"
12449   [(set_attr "type" "ishift")
12450    (set_attr "mode" "SI")])
12451
12452 ;; This pattern can't accept a variable shift count, since shifts by
12453 ;; zero don't affect the flags.  We assume that shifts by constant
12454 ;; zero are optimized away.
12455 (define_insn "*ashrsi3_one_bit_cmp"
12456   [(set (reg FLAGS_REG)
12457         (compare
12458           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12459                        (match_operand:QI 2 "const1_operand" ""))
12460           (const_int 0)))
12461    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12462         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12463   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12464    && ix86_match_ccmode (insn, CCGOCmode)
12465    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12466   "sar{l}\t%0"
12467   [(set_attr "type" "ishift")
12468    (set (attr "length")
12469      (if_then_else (match_operand:SI 0 "register_operand" "")
12470         (const_string "2")
12471         (const_string "*")))])
12472
12473 (define_insn "*ashrsi3_one_bit_cconly"
12474   [(set (reg FLAGS_REG)
12475         (compare
12476           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12477                        (match_operand:QI 2 "const1_operand" ""))
12478           (const_int 0)))
12479    (clobber (match_scratch:SI 0 "=r"))]
12480   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12481    && ix86_match_ccmode (insn, CCGOCmode)
12482    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12483   "sar{l}\t%0"
12484   [(set_attr "type" "ishift")
12485    (set_attr "length" "2")])
12486
12487 (define_insn "*ashrsi3_one_bit_cmp_zext"
12488   [(set (reg FLAGS_REG)
12489         (compare
12490           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12491                        (match_operand:QI 2 "const1_operand" ""))
12492           (const_int 0)))
12493    (set (match_operand:DI 0 "register_operand" "=r")
12494         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12495   "TARGET_64BIT
12496    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497    && ix86_match_ccmode (insn, CCmode)
12498    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12499   "sar{l}\t%k0"
12500   [(set_attr "type" "ishift")
12501    (set_attr "length" "2")])
12502
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags.  We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*ashrsi3_cmp"
12507   [(set (reg FLAGS_REG)
12508         (compare
12509           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12511           (const_int 0)))
12512    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12514   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515    && ix86_match_ccmode (insn, CCGOCmode)
12516    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12517   "sar{l}\t{%2, %0|%0, %2}"
12518   [(set_attr "type" "ishift")
12519    (set_attr "mode" "SI")])
12520
12521 (define_insn "*ashrsi3_cconly"
12522   [(set (reg FLAGS_REG)
12523         (compare
12524           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12525                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526           (const_int 0)))
12527    (clobber (match_scratch:SI 0 "=r"))]
12528   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12529    && ix86_match_ccmode (insn, CCGOCmode)
12530    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12531   "sar{l}\t{%2, %0|%0, %2}"
12532   [(set_attr "type" "ishift")
12533    (set_attr "mode" "SI")])
12534
12535 (define_insn "*ashrsi3_cmp_zext"
12536   [(set (reg FLAGS_REG)
12537         (compare
12538           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12539                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12540           (const_int 0)))
12541    (set (match_operand:DI 0 "register_operand" "=r")
12542         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12543   "TARGET_64BIT
12544    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12545    && ix86_match_ccmode (insn, CCGOCmode)
12546    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12547   "sar{l}\t{%2, %k0|%k0, %2}"
12548   [(set_attr "type" "ishift")
12549    (set_attr "mode" "SI")])
12550
12551 (define_expand "ashrhi3"
12552   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12553         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12554                      (match_operand:QI 2 "nonmemory_operand" "")))]
12555   "TARGET_HIMODE_MATH"
12556   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12557
12558 (define_insn "*ashrhi3_1_one_bit"
12559   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12560         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12561                      (match_operand:QI 2 "const1_operand" "")))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12564    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12565   "sar{w}\t%0"
12566   [(set_attr "type" "ishift")
12567    (set (attr "length")
12568      (if_then_else (match_operand 0 "register_operand" "")
12569         (const_string "2")
12570         (const_string "*")))])
12571
12572 (define_insn "*ashrhi3_1"
12573   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12574         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12575                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12576    (clobber (reg:CC FLAGS_REG))]
12577   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12578   "@
12579    sar{w}\t{%2, %0|%0, %2}
12580    sar{w}\t{%b2, %0|%0, %b2}"
12581   [(set_attr "type" "ishift")
12582    (set_attr "mode" "HI")])
12583
12584 ;; This pattern can't accept a variable shift count, since shifts by
12585 ;; zero don't affect the flags.  We assume that shifts by constant
12586 ;; zero are optimized away.
12587 (define_insn "*ashrhi3_one_bit_cmp"
12588   [(set (reg FLAGS_REG)
12589         (compare
12590           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12591                        (match_operand:QI 2 "const1_operand" ""))
12592           (const_int 0)))
12593    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12594         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12595   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12596    && ix86_match_ccmode (insn, CCGOCmode)
12597    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598   "sar{w}\t%0"
12599   [(set_attr "type" "ishift")
12600    (set (attr "length")
12601      (if_then_else (match_operand 0 "register_operand" "")
12602         (const_string "2")
12603         (const_string "*")))])
12604
12605 (define_insn "*ashrhi3_one_bit_cconly"
12606   [(set (reg FLAGS_REG)
12607         (compare
12608           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12609                        (match_operand:QI 2 "const1_operand" ""))
12610           (const_int 0)))
12611    (clobber (match_scratch:HI 0 "=r"))]
12612   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12613    && ix86_match_ccmode (insn, CCGOCmode)
12614    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12615   "sar{w}\t%0"
12616   [(set_attr "type" "ishift")
12617    (set_attr "length" "2")])
12618
12619 ;; This pattern can't accept a variable shift count, since shifts by
12620 ;; zero don't affect the flags.  We assume that shifts by constant
12621 ;; zero are optimized away.
12622 (define_insn "*ashrhi3_cmp"
12623   [(set (reg FLAGS_REG)
12624         (compare
12625           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12626                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12627           (const_int 0)))
12628    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12629         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12630   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12631    && ix86_match_ccmode (insn, CCGOCmode)
12632    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12633   "sar{w}\t{%2, %0|%0, %2}"
12634   [(set_attr "type" "ishift")
12635    (set_attr "mode" "HI")])
12636
12637 (define_insn "*ashrhi3_cconly"
12638   [(set (reg FLAGS_REG)
12639         (compare
12640           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12642           (const_int 0)))
12643    (clobber (match_scratch:HI 0 "=r"))]
12644   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12645    && ix86_match_ccmode (insn, CCGOCmode)
12646    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12647   "sar{w}\t{%2, %0|%0, %2}"
12648   [(set_attr "type" "ishift")
12649    (set_attr "mode" "HI")])
12650
12651 (define_expand "ashrqi3"
12652   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12653         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12654                      (match_operand:QI 2 "nonmemory_operand" "")))]
12655   "TARGET_QIMODE_MATH"
12656   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12657
12658 (define_insn "*ashrqi3_1_one_bit"
12659   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12660         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12661                      (match_operand:QI 2 "const1_operand" "")))
12662    (clobber (reg:CC FLAGS_REG))]
12663   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12664    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12665   "sar{b}\t%0"
12666   [(set_attr "type" "ishift")
12667    (set (attr "length")
12668      (if_then_else (match_operand 0 "register_operand" "")
12669         (const_string "2")
12670         (const_string "*")))])
12671
12672 (define_insn "*ashrqi3_1_one_bit_slp"
12673   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12674         (ashiftrt:QI (match_dup 0)
12675                      (match_operand:QI 1 "const1_operand" "")))
12676    (clobber (reg:CC FLAGS_REG))]
12677   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12678    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12679    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12680   "sar{b}\t%0"
12681   [(set_attr "type" "ishift1")
12682    (set (attr "length")
12683      (if_then_else (match_operand 0 "register_operand" "")
12684         (const_string "2")
12685         (const_string "*")))])
12686
12687 (define_insn "*ashrqi3_1"
12688   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12689         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12690                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12691    (clobber (reg:CC FLAGS_REG))]
12692   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12693   "@
12694    sar{b}\t{%2, %0|%0, %2}
12695    sar{b}\t{%b2, %0|%0, %b2}"
12696   [(set_attr "type" "ishift")
12697    (set_attr "mode" "QI")])
12698
12699 (define_insn "*ashrqi3_1_slp"
12700   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12701         (ashiftrt:QI (match_dup 0)
12702                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12703    (clobber (reg:CC FLAGS_REG))]
12704   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12705    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12706   "@
12707    sar{b}\t{%1, %0|%0, %1}
12708    sar{b}\t{%b1, %0|%0, %b1}"
12709   [(set_attr "type" "ishift1")
12710    (set_attr "mode" "QI")])
12711
12712 ;; This pattern can't accept a variable shift count, since shifts by
12713 ;; zero don't affect the flags.  We assume that shifts by constant
12714 ;; zero are optimized away.
12715 (define_insn "*ashrqi3_one_bit_cmp"
12716   [(set (reg FLAGS_REG)
12717         (compare
12718           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12719                        (match_operand:QI 2 "const1_operand" "I"))
12720           (const_int 0)))
12721    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12722         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12723   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12724    && ix86_match_ccmode (insn, CCGOCmode)
12725    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12726   "sar{b}\t%0"
12727   [(set_attr "type" "ishift")
12728    (set (attr "length")
12729      (if_then_else (match_operand 0 "register_operand" "")
12730         (const_string "2")
12731         (const_string "*")))])
12732
12733 (define_insn "*ashrqi3_one_bit_cconly"
12734   [(set (reg FLAGS_REG)
12735         (compare
12736           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12737                        (match_operand:QI 2 "const1_operand" ""))
12738           (const_int 0)))
12739    (clobber (match_scratch:QI 0 "=q"))]
12740   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12741    && ix86_match_ccmode (insn, CCGOCmode)
12742    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12743   "sar{b}\t%0"
12744   [(set_attr "type" "ishift")
12745    (set_attr "length" "2")])
12746
12747 ;; This pattern can't accept a variable shift count, since shifts by
12748 ;; zero don't affect the flags.  We assume that shifts by constant
12749 ;; zero are optimized away.
12750 (define_insn "*ashrqi3_cmp"
12751   [(set (reg FLAGS_REG)
12752         (compare
12753           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12754                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12755           (const_int 0)))
12756    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12757         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12758   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12759    && ix86_match_ccmode (insn, CCGOCmode)
12760    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12761   "sar{b}\t{%2, %0|%0, %2}"
12762   [(set_attr "type" "ishift")
12763    (set_attr "mode" "QI")])
12764
12765 (define_insn "*ashrqi3_cconly"
12766   [(set (reg FLAGS_REG)
12767         (compare
12768           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770           (const_int 0)))
12771    (clobber (match_scratch:QI 0 "=q"))]
12772   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12773    && ix86_match_ccmode (insn, CCGOCmode)
12774    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12775   "sar{b}\t{%2, %0|%0, %2}"
12776   [(set_attr "type" "ishift")
12777    (set_attr "mode" "QI")])
12778
12779 \f
12780 ;; Logical shift instructions
12781
12782 ;; See comment above `ashldi3' about how this works.
12783
12784 (define_expand "lshrti3"
12785   [(set (match_operand:TI 0 "register_operand" "")
12786         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12787                      (match_operand:QI 2 "nonmemory_operand" "")))]
12788   "TARGET_64BIT"
12789   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12790
12791 ;; This pattern must be defined before *lshrti3_1 to prevent
12792 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12793
12794 (define_insn "*avx_lshrti3"
12795   [(set (match_operand:TI 0 "register_operand" "=x")
12796         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12797                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12798   "TARGET_AVX"
12799 {
12800   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12801   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12802 }
12803   [(set_attr "type" "sseishft")
12804    (set_attr "prefix" "vex")
12805    (set_attr "mode" "TI")])
12806
12807 (define_insn "sse2_lshrti3"
12808   [(set (match_operand:TI 0 "register_operand" "=x")
12809         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12810                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12811   "TARGET_SSE2"
12812 {
12813   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12814   return "psrldq\t{%2, %0|%0, %2}";
12815 }
12816   [(set_attr "type" "sseishft")
12817    (set_attr "prefix_data16" "1")
12818    (set_attr "mode" "TI")])
12819
12820 (define_insn "*lshrti3_1"
12821   [(set (match_operand:TI 0 "register_operand" "=r")
12822         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12823                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12824    (clobber (reg:CC FLAGS_REG))]
12825   "TARGET_64BIT"
12826   "#"
12827   [(set_attr "type" "multi")])
12828
12829 (define_peephole2
12830   [(match_scratch:DI 3 "r")
12831    (parallel [(set (match_operand:TI 0 "register_operand" "")
12832                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12833                                 (match_operand:QI 2 "nonmemory_operand" "")))
12834               (clobber (reg:CC FLAGS_REG))])
12835    (match_dup 3)]
12836   "TARGET_64BIT"
12837   [(const_int 0)]
12838   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12839
12840 (define_split
12841   [(set (match_operand:TI 0 "register_operand" "")
12842         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12843                      (match_operand:QI 2 "nonmemory_operand" "")))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12846                     ? epilogue_completed : reload_completed)"
12847   [(const_int 0)]
12848   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12849
12850 (define_expand "lshrdi3"
12851   [(set (match_operand:DI 0 "shiftdi_operand" "")
12852         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12853                      (match_operand:QI 2 "nonmemory_operand" "")))]
12854   ""
12855   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12856
12857 (define_insn "*lshrdi3_1_one_bit_rex64"
12858   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12859         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12860                      (match_operand:QI 2 "const1_operand" "")))
12861    (clobber (reg:CC FLAGS_REG))]
12862   "TARGET_64BIT
12863    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12864    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865   "shr{q}\t%0"
12866   [(set_attr "type" "ishift")
12867    (set (attr "length")
12868      (if_then_else (match_operand:DI 0 "register_operand" "")
12869         (const_string "2")
12870         (const_string "*")))])
12871
12872 (define_insn "*lshrdi3_1_rex64"
12873   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12874         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12875                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12876    (clobber (reg:CC FLAGS_REG))]
12877   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878   "@
12879    shr{q}\t{%2, %0|%0, %2}
12880    shr{q}\t{%b2, %0|%0, %b2}"
12881   [(set_attr "type" "ishift")
12882    (set_attr "mode" "DI")])
12883
12884 ;; This pattern can't accept a variable shift count, since shifts by
12885 ;; zero don't affect the flags.  We assume that shifts by constant
12886 ;; zero are optimized away.
12887 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12888   [(set (reg FLAGS_REG)
12889         (compare
12890           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12891                        (match_operand:QI 2 "const1_operand" ""))
12892           (const_int 0)))
12893    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12894         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12895   "TARGET_64BIT
12896    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12897    && ix86_match_ccmode (insn, CCGOCmode)
12898    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12899   "shr{q}\t%0"
12900   [(set_attr "type" "ishift")
12901    (set (attr "length")
12902      (if_then_else (match_operand:DI 0 "register_operand" "")
12903         (const_string "2")
12904         (const_string "*")))])
12905
12906 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12907   [(set (reg FLAGS_REG)
12908         (compare
12909           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12910                        (match_operand:QI 2 "const1_operand" ""))
12911           (const_int 0)))
12912    (clobber (match_scratch:DI 0 "=r"))]
12913   "TARGET_64BIT
12914    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12915    && ix86_match_ccmode (insn, CCGOCmode)
12916    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12917   "shr{q}\t%0"
12918   [(set_attr "type" "ishift")
12919    (set_attr "length" "2")])
12920
12921 ;; This pattern can't accept a variable shift count, since shifts by
12922 ;; zero don't affect the flags.  We assume that shifts by constant
12923 ;; zero are optimized away.
12924 (define_insn "*lshrdi3_cmp_rex64"
12925   [(set (reg FLAGS_REG)
12926         (compare
12927           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12928                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12929           (const_int 0)))
12930    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12931         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12932   "TARGET_64BIT
12933    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12934    && ix86_match_ccmode (insn, CCGOCmode)
12935    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12936   "shr{q}\t{%2, %0|%0, %2}"
12937   [(set_attr "type" "ishift")
12938    (set_attr "mode" "DI")])
12939
12940 (define_insn "*lshrdi3_cconly_rex64"
12941   [(set (reg FLAGS_REG)
12942         (compare
12943           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12944                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12945           (const_int 0)))
12946    (clobber (match_scratch:DI 0 "=r"))]
12947   "TARGET_64BIT
12948    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12949    && ix86_match_ccmode (insn, CCGOCmode)
12950    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951   "shr{q}\t{%2, %0|%0, %2}"
12952   [(set_attr "type" "ishift")
12953    (set_attr "mode" "DI")])
12954
12955 (define_insn "*lshrdi3_1"
12956   [(set (match_operand:DI 0 "register_operand" "=r")
12957         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12958                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "!TARGET_64BIT"
12961   "#"
12962   [(set_attr "type" "multi")])
12963
12964 ;; By default we don't ask for a scratch register, because when DImode
12965 ;; values are manipulated, registers are already at a premium.  But if
12966 ;; we have one handy, we won't turn it away.
12967 (define_peephole2
12968   [(match_scratch:SI 3 "r")
12969    (parallel [(set (match_operand:DI 0 "register_operand" "")
12970                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12971                                 (match_operand:QI 2 "nonmemory_operand" "")))
12972               (clobber (reg:CC FLAGS_REG))])
12973    (match_dup 3)]
12974   "!TARGET_64BIT && TARGET_CMOVE"
12975   [(const_int 0)]
12976   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12977
12978 (define_split
12979   [(set (match_operand:DI 0 "register_operand" "")
12980         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12981                      (match_operand:QI 2 "nonmemory_operand" "")))
12982    (clobber (reg:CC FLAGS_REG))]
12983   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12984                      ? epilogue_completed : reload_completed)"
12985   [(const_int 0)]
12986   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12987
12988 (define_expand "lshrsi3"
12989   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12990         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12991                      (match_operand:QI 2 "nonmemory_operand" "")))]
12992   ""
12993   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12994
12995 (define_insn "*lshrsi3_1_one_bit"
12996   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12997         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12998                      (match_operand:QI 2 "const1_operand" "")))
12999    (clobber (reg:CC FLAGS_REG))]
13000   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13001    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13002   "shr{l}\t%0"
13003   [(set_attr "type" "ishift")
13004    (set (attr "length")
13005      (if_then_else (match_operand:SI 0 "register_operand" "")
13006         (const_string "2")
13007         (const_string "*")))])
13008
13009 (define_insn "*lshrsi3_1_one_bit_zext"
13010   [(set (match_operand:DI 0 "register_operand" "=r")
13011         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13012                      (match_operand:QI 2 "const1_operand" "")))
13013    (clobber (reg:CC FLAGS_REG))]
13014   "TARGET_64BIT
13015    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13016    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017   "shr{l}\t%k0"
13018   [(set_attr "type" "ishift")
13019    (set_attr "length" "2")])
13020
13021 (define_insn "*lshrsi3_1"
13022   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13023         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13024                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13025    (clobber (reg:CC FLAGS_REG))]
13026   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027   "@
13028    shr{l}\t{%2, %0|%0, %2}
13029    shr{l}\t{%b2, %0|%0, %b2}"
13030   [(set_attr "type" "ishift")
13031    (set_attr "mode" "SI")])
13032
13033 (define_insn "*lshrsi3_1_zext"
13034   [(set (match_operand:DI 0 "register_operand" "=r,r")
13035         (zero_extend:DI
13036           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13037                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13038    (clobber (reg:CC FLAGS_REG))]
13039   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13040   "@
13041    shr{l}\t{%2, %k0|%k0, %2}
13042    shr{l}\t{%b2, %k0|%k0, %b2}"
13043   [(set_attr "type" "ishift")
13044    (set_attr "mode" "SI")])
13045
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags.  We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrsi3_one_bit_cmp"
13050   [(set (reg FLAGS_REG)
13051         (compare
13052           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13053                        (match_operand:QI 2 "const1_operand" ""))
13054           (const_int 0)))
13055    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13056         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13057   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13058    && ix86_match_ccmode (insn, CCGOCmode)
13059    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060   "shr{l}\t%0"
13061   [(set_attr "type" "ishift")
13062    (set (attr "length")
13063      (if_then_else (match_operand:SI 0 "register_operand" "")
13064         (const_string "2")
13065         (const_string "*")))])
13066
13067 (define_insn "*lshrsi3_one_bit_cconly"
13068   [(set (reg FLAGS_REG)
13069         (compare
13070           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13071                        (match_operand:QI 2 "const1_operand" ""))
13072           (const_int 0)))
13073    (clobber (match_scratch:SI 0 "=r"))]
13074   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13075    && ix86_match_ccmode (insn, CCGOCmode)
13076    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13077   "shr{l}\t%0"
13078   [(set_attr "type" "ishift")
13079    (set_attr "length" "2")])
13080
13081 (define_insn "*lshrsi3_cmp_one_bit_zext"
13082   [(set (reg FLAGS_REG)
13083         (compare
13084           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13085                        (match_operand:QI 2 "const1_operand" ""))
13086           (const_int 0)))
13087    (set (match_operand:DI 0 "register_operand" "=r")
13088         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13089   "TARGET_64BIT
13090    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091    && ix86_match_ccmode (insn, CCGOCmode)
13092    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13093   "shr{l}\t%k0"
13094   [(set_attr "type" "ishift")
13095    (set_attr "length" "2")])
13096
13097 ;; This pattern can't accept a variable shift count, since shifts by
13098 ;; zero don't affect the flags.  We assume that shifts by constant
13099 ;; zero are optimized away.
13100 (define_insn "*lshrsi3_cmp"
13101   [(set (reg FLAGS_REG)
13102         (compare
13103           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13105           (const_int 0)))
13106    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13107         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13108   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13109    && ix86_match_ccmode (insn, CCGOCmode)
13110    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13111   "shr{l}\t{%2, %0|%0, %2}"
13112   [(set_attr "type" "ishift")
13113    (set_attr "mode" "SI")])
13114
13115 (define_insn "*lshrsi3_cconly"
13116   [(set (reg FLAGS_REG)
13117       (compare
13118         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13119                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120         (const_int 0)))
13121    (clobber (match_scratch:SI 0 "=r"))]
13122   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13123    && ix86_match_ccmode (insn, CCGOCmode)
13124    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13125   "shr{l}\t{%2, %0|%0, %2}"
13126   [(set_attr "type" "ishift")
13127    (set_attr "mode" "SI")])
13128
13129 (define_insn "*lshrsi3_cmp_zext"
13130   [(set (reg FLAGS_REG)
13131         (compare
13132           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13133                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13134           (const_int 0)))
13135    (set (match_operand:DI 0 "register_operand" "=r")
13136         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13137   "TARGET_64BIT
13138    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13139    && ix86_match_ccmode (insn, CCGOCmode)
13140    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13141   "shr{l}\t{%2, %k0|%k0, %2}"
13142   [(set_attr "type" "ishift")
13143    (set_attr "mode" "SI")])
13144
13145 (define_expand "lshrhi3"
13146   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13147         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13148                      (match_operand:QI 2 "nonmemory_operand" "")))]
13149   "TARGET_HIMODE_MATH"
13150   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13151
13152 (define_insn "*lshrhi3_1_one_bit"
13153   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13154         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13155                      (match_operand:QI 2 "const1_operand" "")))
13156    (clobber (reg:CC FLAGS_REG))]
13157   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13158    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13159   "shr{w}\t%0"
13160   [(set_attr "type" "ishift")
13161    (set (attr "length")
13162      (if_then_else (match_operand 0 "register_operand" "")
13163         (const_string "2")
13164         (const_string "*")))])
13165
13166 (define_insn "*lshrhi3_1"
13167   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13168         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13169                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13170    (clobber (reg:CC FLAGS_REG))]
13171   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13172   "@
13173    shr{w}\t{%2, %0|%0, %2}
13174    shr{w}\t{%b2, %0|%0, %b2}"
13175   [(set_attr "type" "ishift")
13176    (set_attr "mode" "HI")])
13177
13178 ;; This pattern can't accept a variable shift count, since shifts by
13179 ;; zero don't affect the flags.  We assume that shifts by constant
13180 ;; zero are optimized away.
13181 (define_insn "*lshrhi3_one_bit_cmp"
13182   [(set (reg FLAGS_REG)
13183         (compare
13184           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13185                        (match_operand:QI 2 "const1_operand" ""))
13186           (const_int 0)))
13187    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13188         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13189   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13190    && ix86_match_ccmode (insn, CCGOCmode)
13191    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13192   "shr{w}\t%0"
13193   [(set_attr "type" "ishift")
13194    (set (attr "length")
13195      (if_then_else (match_operand:SI 0 "register_operand" "")
13196         (const_string "2")
13197         (const_string "*")))])
13198
13199 (define_insn "*lshrhi3_one_bit_cconly"
13200   [(set (reg FLAGS_REG)
13201         (compare
13202           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13203                        (match_operand:QI 2 "const1_operand" ""))
13204           (const_int 0)))
13205    (clobber (match_scratch:HI 0 "=r"))]
13206   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13207    && ix86_match_ccmode (insn, CCGOCmode)
13208    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13209   "shr{w}\t%0"
13210   [(set_attr "type" "ishift")
13211    (set_attr "length" "2")])
13212
13213 ;; This pattern can't accept a variable shift count, since shifts by
13214 ;; zero don't affect the flags.  We assume that shifts by constant
13215 ;; zero are optimized away.
13216 (define_insn "*lshrhi3_cmp"
13217   [(set (reg FLAGS_REG)
13218         (compare
13219           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13220                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13221           (const_int 0)))
13222    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13223         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13224   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13225    && ix86_match_ccmode (insn, CCGOCmode)
13226    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13227   "shr{w}\t{%2, %0|%0, %2}"
13228   [(set_attr "type" "ishift")
13229    (set_attr "mode" "HI")])
13230
13231 (define_insn "*lshrhi3_cconly"
13232   [(set (reg FLAGS_REG)
13233         (compare
13234           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13236           (const_int 0)))
13237    (clobber (match_scratch:HI 0 "=r"))]
13238   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13239    && ix86_match_ccmode (insn, CCGOCmode)
13240    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13241   "shr{w}\t{%2, %0|%0, %2}"
13242   [(set_attr "type" "ishift")
13243    (set_attr "mode" "HI")])
13244
13245 (define_expand "lshrqi3"
13246   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13247         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13248                      (match_operand:QI 2 "nonmemory_operand" "")))]
13249   "TARGET_QIMODE_MATH"
13250   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13251
13252 (define_insn "*lshrqi3_1_one_bit"
13253   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13254         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13255                      (match_operand:QI 2 "const1_operand" "")))
13256    (clobber (reg:CC FLAGS_REG))]
13257   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13258    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13259   "shr{b}\t%0"
13260   [(set_attr "type" "ishift")
13261    (set (attr "length")
13262      (if_then_else (match_operand 0 "register_operand" "")
13263         (const_string "2")
13264         (const_string "*")))])
13265
13266 (define_insn "*lshrqi3_1_one_bit_slp"
13267   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13268         (lshiftrt:QI (match_dup 0)
13269                      (match_operand:QI 1 "const1_operand" "")))
13270    (clobber (reg:CC FLAGS_REG))]
13271   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13272    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13273   "shr{b}\t%0"
13274   [(set_attr "type" "ishift1")
13275    (set (attr "length")
13276      (if_then_else (match_operand 0 "register_operand" "")
13277         (const_string "2")
13278         (const_string "*")))])
13279
13280 (define_insn "*lshrqi3_1"
13281   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13282         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13283                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13284    (clobber (reg:CC FLAGS_REG))]
13285   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13286   "@
13287    shr{b}\t{%2, %0|%0, %2}
13288    shr{b}\t{%b2, %0|%0, %b2}"
13289   [(set_attr "type" "ishift")
13290    (set_attr "mode" "QI")])
13291
13292 (define_insn "*lshrqi3_1_slp"
13293   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13294         (lshiftrt:QI (match_dup 0)
13295                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13296    (clobber (reg:CC FLAGS_REG))]
13297   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13298    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299   "@
13300    shr{b}\t{%1, %0|%0, %1}
13301    shr{b}\t{%b1, %0|%0, %b1}"
13302   [(set_attr "type" "ishift1")
13303    (set_attr "mode" "QI")])
13304
13305 ;; This pattern can't accept a variable shift count, since shifts by
13306 ;; zero don't affect the flags.  We assume that shifts by constant
13307 ;; zero are optimized away.
13308 (define_insn "*lshrqi2_one_bit_cmp"
13309   [(set (reg FLAGS_REG)
13310         (compare
13311           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13312                        (match_operand:QI 2 "const1_operand" ""))
13313           (const_int 0)))
13314    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13315         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13316   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13317    && ix86_match_ccmode (insn, CCGOCmode)
13318    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13319   "shr{b}\t%0"
13320   [(set_attr "type" "ishift")
13321    (set (attr "length")
13322      (if_then_else (match_operand:SI 0 "register_operand" "")
13323         (const_string "2")
13324         (const_string "*")))])
13325
13326 (define_insn "*lshrqi2_one_bit_cconly"
13327   [(set (reg FLAGS_REG)
13328         (compare
13329           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330                        (match_operand:QI 2 "const1_operand" ""))
13331           (const_int 0)))
13332    (clobber (match_scratch:QI 0 "=q"))]
13333   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13334    && ix86_match_ccmode (insn, CCGOCmode)
13335    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336   "shr{b}\t%0"
13337   [(set_attr "type" "ishift")
13338    (set_attr "length" "2")])
13339
13340 ;; This pattern can't accept a variable shift count, since shifts by
13341 ;; zero don't affect the flags.  We assume that shifts by constant
13342 ;; zero are optimized away.
13343 (define_insn "*lshrqi2_cmp"
13344   [(set (reg FLAGS_REG)
13345         (compare
13346           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13347                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13348           (const_int 0)))
13349    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13350         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13351   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13352    && ix86_match_ccmode (insn, CCGOCmode)
13353    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13354   "shr{b}\t{%2, %0|%0, %2}"
13355   [(set_attr "type" "ishift")
13356    (set_attr "mode" "QI")])
13357
13358 (define_insn "*lshrqi2_cconly"
13359   [(set (reg FLAGS_REG)
13360         (compare
13361           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13362                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13363           (const_int 0)))
13364    (clobber (match_scratch:QI 0 "=q"))]
13365   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13366    && ix86_match_ccmode (insn, CCGOCmode)
13367    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13368   "shr{b}\t{%2, %0|%0, %2}"
13369   [(set_attr "type" "ishift")
13370    (set_attr "mode" "QI")])
13371 \f
13372 ;; Rotate instructions
13373
13374 (define_expand "rotldi3"
13375   [(set (match_operand:DI 0 "shiftdi_operand" "")
13376         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13377                    (match_operand:QI 2 "nonmemory_operand" "")))]
13378  ""
13379 {
13380   if (TARGET_64BIT)
13381     {
13382       ix86_expand_binary_operator (ROTATE, DImode, operands);
13383       DONE;
13384     }
13385   if (!const_1_to_31_operand (operands[2], VOIDmode))
13386     FAIL;
13387   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13388   DONE;
13389 })
13390
13391 ;; Implement rotation using two double-precision shift instructions
13392 ;; and a scratch register.
13393 (define_insn_and_split "ix86_rotldi3"
13394  [(set (match_operand:DI 0 "register_operand" "=r")
13395        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13396                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13397   (clobber (reg:CC FLAGS_REG))
13398   (clobber (match_scratch:SI 3 "=&r"))]
13399  "!TARGET_64BIT"
13400  ""
13401  "&& reload_completed"
13402  [(set (match_dup 3) (match_dup 4))
13403   (parallel
13404    [(set (match_dup 4)
13405          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13406                  (lshiftrt:SI (match_dup 5)
13407                               (minus:QI (const_int 32) (match_dup 2)))))
13408     (clobber (reg:CC FLAGS_REG))])
13409   (parallel
13410    [(set (match_dup 5)
13411          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13412                  (lshiftrt:SI (match_dup 3)
13413                               (minus:QI (const_int 32) (match_dup 2)))))
13414     (clobber (reg:CC FLAGS_REG))])]
13415  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13416
13417 (define_insn "*rotlsi3_1_one_bit_rex64"
13418   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13419         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13420                    (match_operand:QI 2 "const1_operand" "")))
13421    (clobber (reg:CC FLAGS_REG))]
13422   "TARGET_64BIT
13423    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13424    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13425   "rol{q}\t%0"
13426   [(set_attr "type" "rotate")
13427    (set (attr "length")
13428      (if_then_else (match_operand:DI 0 "register_operand" "")
13429         (const_string "2")
13430         (const_string "*")))])
13431
13432 (define_insn "*rotldi3_1_rex64"
13433   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13434         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13435                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13436    (clobber (reg:CC FLAGS_REG))]
13437   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13438   "@
13439    rol{q}\t{%2, %0|%0, %2}
13440    rol{q}\t{%b2, %0|%0, %b2}"
13441   [(set_attr "type" "rotate")
13442    (set_attr "mode" "DI")])
13443
13444 (define_expand "rotlsi3"
13445   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13446         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13447                    (match_operand:QI 2 "nonmemory_operand" "")))]
13448   ""
13449   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13450
13451 (define_insn "*rotlsi3_1_one_bit"
13452   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13453         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13454                    (match_operand:QI 2 "const1_operand" "")))
13455    (clobber (reg:CC FLAGS_REG))]
13456   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13457    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13458   "rol{l}\t%0"
13459   [(set_attr "type" "rotate")
13460    (set (attr "length")
13461      (if_then_else (match_operand:SI 0 "register_operand" "")
13462         (const_string "2")
13463         (const_string "*")))])
13464
13465 (define_insn "*rotlsi3_1_one_bit_zext"
13466   [(set (match_operand:DI 0 "register_operand" "=r")
13467         (zero_extend:DI
13468           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13469                      (match_operand:QI 2 "const1_operand" ""))))
13470    (clobber (reg:CC FLAGS_REG))]
13471   "TARGET_64BIT
13472    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13473    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13474   "rol{l}\t%k0"
13475   [(set_attr "type" "rotate")
13476    (set_attr "length" "2")])
13477
13478 (define_insn "*rotlsi3_1"
13479   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13480         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13481                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13482    (clobber (reg:CC FLAGS_REG))]
13483   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13484   "@
13485    rol{l}\t{%2, %0|%0, %2}
13486    rol{l}\t{%b2, %0|%0, %b2}"
13487   [(set_attr "type" "rotate")
13488    (set_attr "mode" "SI")])
13489
13490 (define_insn "*rotlsi3_1_zext"
13491   [(set (match_operand:DI 0 "register_operand" "=r,r")
13492         (zero_extend:DI
13493           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13494                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13495    (clobber (reg:CC FLAGS_REG))]
13496   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13497   "@
13498    rol{l}\t{%2, %k0|%k0, %2}
13499    rol{l}\t{%b2, %k0|%k0, %b2}"
13500   [(set_attr "type" "rotate")
13501    (set_attr "mode" "SI")])
13502
13503 (define_expand "rotlhi3"
13504   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13505         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13506                    (match_operand:QI 2 "nonmemory_operand" "")))]
13507   "TARGET_HIMODE_MATH"
13508   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13509
13510 (define_insn "*rotlhi3_1_one_bit"
13511   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13512         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13513                    (match_operand:QI 2 "const1_operand" "")))
13514    (clobber (reg:CC FLAGS_REG))]
13515   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13516    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13517   "rol{w}\t%0"
13518   [(set_attr "type" "rotate")
13519    (set (attr "length")
13520      (if_then_else (match_operand 0 "register_operand" "")
13521         (const_string "2")
13522         (const_string "*")))])
13523
13524 (define_insn "*rotlhi3_1"
13525   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13526         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13527                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13528    (clobber (reg:CC FLAGS_REG))]
13529   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13530   "@
13531    rol{w}\t{%2, %0|%0, %2}
13532    rol{w}\t{%b2, %0|%0, %b2}"
13533   [(set_attr "type" "rotate")
13534    (set_attr "mode" "HI")])
13535
13536 (define_split
13537  [(set (match_operand:HI 0 "register_operand" "")
13538        (rotate:HI (match_dup 0) (const_int 8)))
13539   (clobber (reg:CC FLAGS_REG))]
13540  "reload_completed"
13541  [(parallel [(set (strict_low_part (match_dup 0))
13542                   (bswap:HI (match_dup 0)))
13543              (clobber (reg:CC FLAGS_REG))])]
13544  "")
13545
13546 (define_expand "rotlqi3"
13547   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13548         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13549                    (match_operand:QI 2 "nonmemory_operand" "")))]
13550   "TARGET_QIMODE_MATH"
13551   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13552
13553 (define_insn "*rotlqi3_1_one_bit_slp"
13554   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13555         (rotate:QI (match_dup 0)
13556                    (match_operand:QI 1 "const1_operand" "")))
13557    (clobber (reg:CC FLAGS_REG))]
13558   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13559    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13560   "rol{b}\t%0"
13561   [(set_attr "type" "rotate1")
13562    (set (attr "length")
13563      (if_then_else (match_operand 0 "register_operand" "")
13564         (const_string "2")
13565         (const_string "*")))])
13566
13567 (define_insn "*rotlqi3_1_one_bit"
13568   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13569         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13570                    (match_operand:QI 2 "const1_operand" "")))
13571    (clobber (reg:CC FLAGS_REG))]
13572   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13573    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13574   "rol{b}\t%0"
13575   [(set_attr "type" "rotate")
13576    (set (attr "length")
13577      (if_then_else (match_operand 0 "register_operand" "")
13578         (const_string "2")
13579         (const_string "*")))])
13580
13581 (define_insn "*rotlqi3_1_slp"
13582   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13583         (rotate:QI (match_dup 0)
13584                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13585    (clobber (reg:CC FLAGS_REG))]
13586   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13587    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13588   "@
13589    rol{b}\t{%1, %0|%0, %1}
13590    rol{b}\t{%b1, %0|%0, %b1}"
13591   [(set_attr "type" "rotate1")
13592    (set_attr "mode" "QI")])
13593
13594 (define_insn "*rotlqi3_1"
13595   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13596         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13597                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13598    (clobber (reg:CC FLAGS_REG))]
13599   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13600   "@
13601    rol{b}\t{%2, %0|%0, %2}
13602    rol{b}\t{%b2, %0|%0, %b2}"
13603   [(set_attr "type" "rotate")
13604    (set_attr "mode" "QI")])
13605
13606 (define_expand "rotrdi3"
13607   [(set (match_operand:DI 0 "shiftdi_operand" "")
13608         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13609                    (match_operand:QI 2 "nonmemory_operand" "")))]
13610  ""
13611 {
13612   if (TARGET_64BIT)
13613     {
13614       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13615       DONE;
13616     }
13617   if (!const_1_to_31_operand (operands[2], VOIDmode))
13618     FAIL;
13619   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13620   DONE;
13621 })
13622
13623 ;; Implement rotation using two double-precision shift instructions
13624 ;; and a scratch register.
13625 (define_insn_and_split "ix86_rotrdi3"
13626  [(set (match_operand:DI 0 "register_operand" "=r")
13627        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13628                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13629   (clobber (reg:CC FLAGS_REG))
13630   (clobber (match_scratch:SI 3 "=&r"))]
13631  "!TARGET_64BIT"
13632  ""
13633  "&& reload_completed"
13634  [(set (match_dup 3) (match_dup 4))
13635   (parallel
13636    [(set (match_dup 4)
13637          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13638                  (ashift:SI (match_dup 5)
13639                             (minus:QI (const_int 32) (match_dup 2)))))
13640     (clobber (reg:CC FLAGS_REG))])
13641   (parallel
13642    [(set (match_dup 5)
13643          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13644                  (ashift:SI (match_dup 3)
13645                             (minus:QI (const_int 32) (match_dup 2)))))
13646     (clobber (reg:CC FLAGS_REG))])]
13647  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13648
13649 (define_insn "*rotrdi3_1_one_bit_rex64"
13650   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13651         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13652                      (match_operand:QI 2 "const1_operand" "")))
13653    (clobber (reg:CC FLAGS_REG))]
13654   "TARGET_64BIT
13655    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13656    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13657   "ror{q}\t%0"
13658   [(set_attr "type" "rotate")
13659    (set (attr "length")
13660      (if_then_else (match_operand:DI 0 "register_operand" "")
13661         (const_string "2")
13662         (const_string "*")))])
13663
13664 (define_insn "*rotrdi3_1_rex64"
13665   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13666         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13667                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13668    (clobber (reg:CC FLAGS_REG))]
13669   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13670   "@
13671    ror{q}\t{%2, %0|%0, %2}
13672    ror{q}\t{%b2, %0|%0, %b2}"
13673   [(set_attr "type" "rotate")
13674    (set_attr "mode" "DI")])
13675
13676 (define_expand "rotrsi3"
13677   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13678         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13679                      (match_operand:QI 2 "nonmemory_operand" "")))]
13680   ""
13681   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13682
13683 (define_insn "*rotrsi3_1_one_bit"
13684   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13685         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13686                      (match_operand:QI 2 "const1_operand" "")))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13689    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13690   "ror{l}\t%0"
13691   [(set_attr "type" "rotate")
13692    (set (attr "length")
13693      (if_then_else (match_operand:SI 0 "register_operand" "")
13694         (const_string "2")
13695         (const_string "*")))])
13696
13697 (define_insn "*rotrsi3_1_one_bit_zext"
13698   [(set (match_operand:DI 0 "register_operand" "=r")
13699         (zero_extend:DI
13700           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13701                        (match_operand:QI 2 "const1_operand" ""))))
13702    (clobber (reg:CC FLAGS_REG))]
13703   "TARGET_64BIT
13704    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13705    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13706   "ror{l}\t%k0"
13707   [(set_attr "type" "rotate")
13708    (set (attr "length")
13709      (if_then_else (match_operand:SI 0 "register_operand" "")
13710         (const_string "2")
13711         (const_string "*")))])
13712
13713 (define_insn "*rotrsi3_1"
13714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13715         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13716                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13717    (clobber (reg:CC FLAGS_REG))]
13718   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13719   "@
13720    ror{l}\t{%2, %0|%0, %2}
13721    ror{l}\t{%b2, %0|%0, %b2}"
13722   [(set_attr "type" "rotate")
13723    (set_attr "mode" "SI")])
13724
13725 (define_insn "*rotrsi3_1_zext"
13726   [(set (match_operand:DI 0 "register_operand" "=r,r")
13727         (zero_extend:DI
13728           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13729                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13730    (clobber (reg:CC FLAGS_REG))]
13731   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13732   "@
13733    ror{l}\t{%2, %k0|%k0, %2}
13734    ror{l}\t{%b2, %k0|%k0, %b2}"
13735   [(set_attr "type" "rotate")
13736    (set_attr "mode" "SI")])
13737
13738 (define_expand "rotrhi3"
13739   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13740         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13741                      (match_operand:QI 2 "nonmemory_operand" "")))]
13742   "TARGET_HIMODE_MATH"
13743   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13744
13745 (define_insn "*rotrhi3_one_bit"
13746   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13747         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13748                      (match_operand:QI 2 "const1_operand" "")))
13749    (clobber (reg:CC FLAGS_REG))]
13750   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13751    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13752   "ror{w}\t%0"
13753   [(set_attr "type" "rotate")
13754    (set (attr "length")
13755      (if_then_else (match_operand 0 "register_operand" "")
13756         (const_string "2")
13757         (const_string "*")))])
13758
13759 (define_insn "*rotrhi3_1"
13760   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13761         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13762                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13763    (clobber (reg:CC FLAGS_REG))]
13764   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13765   "@
13766    ror{w}\t{%2, %0|%0, %2}
13767    ror{w}\t{%b2, %0|%0, %b2}"
13768   [(set_attr "type" "rotate")
13769    (set_attr "mode" "HI")])
13770
13771 (define_split
13772  [(set (match_operand:HI 0 "register_operand" "")
13773        (rotatert:HI (match_dup 0) (const_int 8)))
13774   (clobber (reg:CC FLAGS_REG))]
13775  "reload_completed"
13776  [(parallel [(set (strict_low_part (match_dup 0))
13777                   (bswap:HI (match_dup 0)))
13778              (clobber (reg:CC FLAGS_REG))])]
13779  "")
13780
13781 (define_expand "rotrqi3"
13782   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13783         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13784                      (match_operand:QI 2 "nonmemory_operand" "")))]
13785   "TARGET_QIMODE_MATH"
13786   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13787
13788 (define_insn "*rotrqi3_1_one_bit"
13789   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13790         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13791                      (match_operand:QI 2 "const1_operand" "")))
13792    (clobber (reg:CC FLAGS_REG))]
13793   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13794    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13795   "ror{b}\t%0"
13796   [(set_attr "type" "rotate")
13797    (set (attr "length")
13798      (if_then_else (match_operand 0 "register_operand" "")
13799         (const_string "2")
13800         (const_string "*")))])
13801
13802 (define_insn "*rotrqi3_1_one_bit_slp"
13803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13804         (rotatert:QI (match_dup 0)
13805                      (match_operand:QI 1 "const1_operand" "")))
13806    (clobber (reg:CC FLAGS_REG))]
13807   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13808    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13809   "ror{b}\t%0"
13810   [(set_attr "type" "rotate1")
13811    (set (attr "length")
13812      (if_then_else (match_operand 0 "register_operand" "")
13813         (const_string "2")
13814         (const_string "*")))])
13815
13816 (define_insn "*rotrqi3_1"
13817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13818         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13819                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13820    (clobber (reg:CC FLAGS_REG))]
13821   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13822   "@
13823    ror{b}\t{%2, %0|%0, %2}
13824    ror{b}\t{%b2, %0|%0, %b2}"
13825   [(set_attr "type" "rotate")
13826    (set_attr "mode" "QI")])
13827
13828 (define_insn "*rotrqi3_1_slp"
13829   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13830         (rotatert:QI (match_dup 0)
13831                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13832    (clobber (reg:CC FLAGS_REG))]
13833   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13834    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13835   "@
13836    ror{b}\t{%1, %0|%0, %1}
13837    ror{b}\t{%b1, %0|%0, %b1}"
13838   [(set_attr "type" "rotate1")
13839    (set_attr "mode" "QI")])
13840 \f
13841 ;; Bit set / bit test instructions
13842
13843 (define_expand "extv"
13844   [(set (match_operand:SI 0 "register_operand" "")
13845         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13846                          (match_operand:SI 2 "const8_operand" "")
13847                          (match_operand:SI 3 "const8_operand" "")))]
13848   ""
13849 {
13850   /* Handle extractions from %ah et al.  */
13851   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13852     FAIL;
13853
13854   /* From mips.md: extract_bit_field doesn't verify that our source
13855      matches the predicate, so check it again here.  */
13856   if (! ext_register_operand (operands[1], VOIDmode))
13857     FAIL;
13858 })
13859
13860 (define_expand "extzv"
13861   [(set (match_operand:SI 0 "register_operand" "")
13862         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13863                          (match_operand:SI 2 "const8_operand" "")
13864                          (match_operand:SI 3 "const8_operand" "")))]
13865   ""
13866 {
13867   /* Handle extractions from %ah et al.  */
13868   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13869     FAIL;
13870
13871   /* From mips.md: extract_bit_field doesn't verify that our source
13872      matches the predicate, so check it again here.  */
13873   if (! ext_register_operand (operands[1], VOIDmode))
13874     FAIL;
13875 })
13876
13877 (define_expand "insv"
13878   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13879                       (match_operand 1 "const8_operand" "")
13880                       (match_operand 2 "const8_operand" ""))
13881         (match_operand 3 "register_operand" ""))]
13882   ""
13883 {
13884   /* Handle insertions to %ah et al.  */
13885   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13886     FAIL;
13887
13888   /* From mips.md: insert_bit_field doesn't verify that our source
13889      matches the predicate, so check it again here.  */
13890   if (! ext_register_operand (operands[0], VOIDmode))
13891     FAIL;
13892
13893   if (TARGET_64BIT)
13894     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13895   else
13896     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13897
13898   DONE;
13899 })
13900
13901 ;; %%% bts, btr, btc, bt.
13902 ;; In general these instructions are *slow* when applied to memory,
13903 ;; since they enforce atomic operation.  When applied to registers,
13904 ;; it depends on the cpu implementation.  They're never faster than
13905 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13906 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13907 ;; within the instruction itself, so operating on bits in the high
13908 ;; 32-bits of a register becomes easier.
13909 ;;
13910 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13911 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13912 ;; negdf respectively, so they can never be disabled entirely.
13913
13914 (define_insn "*btsq"
13915   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13916                          (const_int 1)
13917                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13918         (const_int 1))
13919    (clobber (reg:CC FLAGS_REG))]
13920   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13921   "bts{q}\t{%1, %0|%0, %1}"
13922   [(set_attr "type" "alu1")])
13923
13924 (define_insn "*btrq"
13925   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13926                          (const_int 1)
13927                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13928         (const_int 0))
13929    (clobber (reg:CC FLAGS_REG))]
13930   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13931   "btr{q}\t{%1, %0|%0, %1}"
13932   [(set_attr "type" "alu1")])
13933
13934 (define_insn "*btcq"
13935   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13936                          (const_int 1)
13937                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13938         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13939    (clobber (reg:CC FLAGS_REG))]
13940   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13941   "btc{q}\t{%1, %0|%0, %1}"
13942   [(set_attr "type" "alu1")])
13943
13944 ;; Allow Nocona to avoid these instructions if a register is available.
13945
13946 (define_peephole2
13947   [(match_scratch:DI 2 "r")
13948    (parallel [(set (zero_extract:DI
13949                      (match_operand:DI 0 "register_operand" "")
13950                      (const_int 1)
13951                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13952                    (const_int 1))
13953               (clobber (reg:CC FLAGS_REG))])]
13954   "TARGET_64BIT && !TARGET_USE_BT"
13955   [(const_int 0)]
13956 {
13957   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13958   rtx op1;
13959
13960   if (HOST_BITS_PER_WIDE_INT >= 64)
13961     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13962   else if (i < HOST_BITS_PER_WIDE_INT)
13963     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13964   else
13965     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13966
13967   op1 = immed_double_const (lo, hi, DImode);
13968   if (i >= 31)
13969     {
13970       emit_move_insn (operands[2], op1);
13971       op1 = operands[2];
13972     }
13973
13974   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13975   DONE;
13976 })
13977
13978 (define_peephole2
13979   [(match_scratch:DI 2 "r")
13980    (parallel [(set (zero_extract:DI
13981                      (match_operand:DI 0 "register_operand" "")
13982                      (const_int 1)
13983                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13984                    (const_int 0))
13985               (clobber (reg:CC FLAGS_REG))])]
13986   "TARGET_64BIT && !TARGET_USE_BT"
13987   [(const_int 0)]
13988 {
13989   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13990   rtx op1;
13991
13992   if (HOST_BITS_PER_WIDE_INT >= 64)
13993     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13994   else if (i < HOST_BITS_PER_WIDE_INT)
13995     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13996   else
13997     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13998
13999   op1 = immed_double_const (~lo, ~hi, DImode);
14000   if (i >= 32)
14001     {
14002       emit_move_insn (operands[2], op1);
14003       op1 = operands[2];
14004     }
14005
14006   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14007   DONE;
14008 })
14009
14010 (define_peephole2
14011   [(match_scratch:DI 2 "r")
14012    (parallel [(set (zero_extract:DI
14013                      (match_operand:DI 0 "register_operand" "")
14014                      (const_int 1)
14015                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14016               (not:DI (zero_extract:DI
14017                         (match_dup 0) (const_int 1) (match_dup 1))))
14018               (clobber (reg:CC FLAGS_REG))])]
14019   "TARGET_64BIT && !TARGET_USE_BT"
14020   [(const_int 0)]
14021 {
14022   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14023   rtx op1;
14024
14025   if (HOST_BITS_PER_WIDE_INT >= 64)
14026     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14027   else if (i < HOST_BITS_PER_WIDE_INT)
14028     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14029   else
14030     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14031
14032   op1 = immed_double_const (lo, hi, DImode);
14033   if (i >= 31)
14034     {
14035       emit_move_insn (operands[2], op1);
14036       op1 = operands[2];
14037     }
14038
14039   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14040   DONE;
14041 })
14042
14043 (define_insn "*btdi_rex64"
14044   [(set (reg:CCC FLAGS_REG)
14045         (compare:CCC
14046           (zero_extract:DI
14047             (match_operand:DI 0 "register_operand" "r")
14048             (const_int 1)
14049             (match_operand:DI 1 "nonmemory_operand" "rN"))
14050           (const_int 0)))]
14051   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14052   "bt{q}\t{%1, %0|%0, %1}"
14053   [(set_attr "type" "alu1")])
14054
14055 (define_insn "*btsi"
14056   [(set (reg:CCC FLAGS_REG)
14057         (compare:CCC
14058           (zero_extract:SI
14059             (match_operand:SI 0 "register_operand" "r")
14060             (const_int 1)
14061             (match_operand:SI 1 "nonmemory_operand" "rN"))
14062           (const_int 0)))]
14063   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14064   "bt{l}\t{%1, %0|%0, %1}"
14065   [(set_attr "type" "alu1")])
14066 \f
14067 ;; Store-flag instructions.
14068
14069 ;; For all sCOND expanders, also expand the compare or test insn that
14070 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14071
14072 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14073 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14074 ;; way, which can later delete the movzx if only QImode is needed.
14075
14076 (define_expand "s<code>"
14077   [(set (match_operand:QI 0 "register_operand" "")
14078         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14079   ""
14080   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14081
14082 (define_expand "s<code>"
14083   [(set (match_operand:QI 0 "register_operand" "")
14084         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14085   "TARGET_80387 || TARGET_SSE"
14086   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14087
14088 (define_insn "*setcc_1"
14089   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14090         (match_operator:QI 1 "ix86_comparison_operator"
14091           [(reg FLAGS_REG) (const_int 0)]))]
14092   ""
14093   "set%C1\t%0"
14094   [(set_attr "type" "setcc")
14095    (set_attr "mode" "QI")])
14096
14097 (define_insn "*setcc_2"
14098   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14099         (match_operator:QI 1 "ix86_comparison_operator"
14100           [(reg FLAGS_REG) (const_int 0)]))]
14101   ""
14102   "set%C1\t%0"
14103   [(set_attr "type" "setcc")
14104    (set_attr "mode" "QI")])
14105
14106 ;; In general it is not safe to assume too much about CCmode registers,
14107 ;; so simplify-rtx stops when it sees a second one.  Under certain
14108 ;; conditions this is safe on x86, so help combine not create
14109 ;;
14110 ;;      seta    %al
14111 ;;      testb   %al, %al
14112 ;;      sete    %al
14113
14114 (define_split
14115   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14116         (ne:QI (match_operator 1 "ix86_comparison_operator"
14117                  [(reg FLAGS_REG) (const_int 0)])
14118             (const_int 0)))]
14119   ""
14120   [(set (match_dup 0) (match_dup 1))]
14121 {
14122   PUT_MODE (operands[1], QImode);
14123 })
14124
14125 (define_split
14126   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14127         (ne:QI (match_operator 1 "ix86_comparison_operator"
14128                  [(reg FLAGS_REG) (const_int 0)])
14129             (const_int 0)))]
14130   ""
14131   [(set (match_dup 0) (match_dup 1))]
14132 {
14133   PUT_MODE (operands[1], QImode);
14134 })
14135
14136 (define_split
14137   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14138         (eq:QI (match_operator 1 "ix86_comparison_operator"
14139                  [(reg FLAGS_REG) (const_int 0)])
14140             (const_int 0)))]
14141   ""
14142   [(set (match_dup 0) (match_dup 1))]
14143 {
14144   rtx new_op1 = copy_rtx (operands[1]);
14145   operands[1] = new_op1;
14146   PUT_MODE (new_op1, QImode);
14147   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14148                                              GET_MODE (XEXP (new_op1, 0))));
14149
14150   /* Make sure that (a) the CCmode we have for the flags is strong
14151      enough for the reversed compare or (b) we have a valid FP compare.  */
14152   if (! ix86_comparison_operator (new_op1, VOIDmode))
14153     FAIL;
14154 })
14155
14156 (define_split
14157   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14158         (eq:QI (match_operator 1 "ix86_comparison_operator"
14159                  [(reg FLAGS_REG) (const_int 0)])
14160             (const_int 0)))]
14161   ""
14162   [(set (match_dup 0) (match_dup 1))]
14163 {
14164   rtx new_op1 = copy_rtx (operands[1]);
14165   operands[1] = new_op1;
14166   PUT_MODE (new_op1, QImode);
14167   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14168                                              GET_MODE (XEXP (new_op1, 0))));
14169
14170   /* Make sure that (a) the CCmode we have for the flags is strong
14171      enough for the reversed compare or (b) we have a valid FP compare.  */
14172   if (! ix86_comparison_operator (new_op1, VOIDmode))
14173     FAIL;
14174 })
14175
14176 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14177 ;; subsequent logical operations are used to imitate conditional moves.
14178 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14179 ;; it directly.
14180
14181 (define_insn "*avx_setcc<mode>"
14182   [(set (match_operand:MODEF 0 "register_operand" "=x")
14183         (match_operator:MODEF 1 "avx_comparison_float_operator"
14184           [(match_operand:MODEF 2 "register_operand" "x")
14185            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14186   "TARGET_AVX"
14187   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14188   [(set_attr "type" "ssecmp")
14189    (set_attr "prefix" "vex")
14190    (set_attr "mode" "<MODE>")])
14191
14192 (define_insn "*sse_setcc<mode>"
14193   [(set (match_operand:MODEF 0 "register_operand" "=x")
14194         (match_operator:MODEF 1 "sse_comparison_operator"
14195           [(match_operand:MODEF 2 "register_operand" "0")
14196            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14197   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14198   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14199   [(set_attr "type" "ssecmp")
14200    (set_attr "mode" "<MODE>")])
14201
14202 (define_insn "*sse5_setcc<mode>"
14203   [(set (match_operand:MODEF 0 "register_operand" "=x")
14204         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14205           [(match_operand:MODEF 2 "register_operand" "x")
14206            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14207   "TARGET_SSE5"
14208   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14209   [(set_attr "type" "sse4arg")
14210    (set_attr "mode" "<MODE>")])
14211
14212 \f
14213 ;; Basic conditional jump instructions.
14214 ;; We ignore the overflow flag for signed branch instructions.
14215
14216 ;; For all bCOND expanders, also expand the compare or test insn that
14217 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14218
14219 (define_expand "b<code>"
14220   [(set (pc)
14221         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14222                                    (const_int 0))
14223                       (label_ref (match_operand 0 ""))
14224                       (pc)))]
14225   ""
14226   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14227
14228 (define_expand "b<code>"
14229   [(set (pc)
14230         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14231                                   (const_int 0))
14232                       (label_ref (match_operand 0 ""))
14233                       (pc)))]
14234   "TARGET_80387 || TARGET_SSE_MATH"
14235   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14236
14237 (define_insn "*jcc_1"
14238   [(set (pc)
14239         (if_then_else (match_operator 1 "ix86_comparison_operator"
14240                                       [(reg FLAGS_REG) (const_int 0)])
14241                       (label_ref (match_operand 0 "" ""))
14242                       (pc)))]
14243   ""
14244   "%+j%C1\t%l0"
14245   [(set_attr "type" "ibr")
14246    (set_attr "modrm" "0")
14247    (set (attr "length")
14248            (if_then_else (and (ge (minus (match_dup 0) (pc))
14249                                   (const_int -126))
14250                               (lt (minus (match_dup 0) (pc))
14251                                   (const_int 128)))
14252              (const_int 2)
14253              (const_int 6)))])
14254
14255 (define_insn "*jcc_2"
14256   [(set (pc)
14257         (if_then_else (match_operator 1 "ix86_comparison_operator"
14258                                       [(reg FLAGS_REG) (const_int 0)])
14259                       (pc)
14260                       (label_ref (match_operand 0 "" ""))))]
14261   ""
14262   "%+j%c1\t%l0"
14263   [(set_attr "type" "ibr")
14264    (set_attr "modrm" "0")
14265    (set (attr "length")
14266            (if_then_else (and (ge (minus (match_dup 0) (pc))
14267                                   (const_int -126))
14268                               (lt (minus (match_dup 0) (pc))
14269                                   (const_int 128)))
14270              (const_int 2)
14271              (const_int 6)))])
14272
14273 ;; In general it is not safe to assume too much about CCmode registers,
14274 ;; so simplify-rtx stops when it sees a second one.  Under certain
14275 ;; conditions this is safe on x86, so help combine not create
14276 ;;
14277 ;;      seta    %al
14278 ;;      testb   %al, %al
14279 ;;      je      Lfoo
14280
14281 (define_split
14282   [(set (pc)
14283         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14284                                       [(reg FLAGS_REG) (const_int 0)])
14285                           (const_int 0))
14286                       (label_ref (match_operand 1 "" ""))
14287                       (pc)))]
14288   ""
14289   [(set (pc)
14290         (if_then_else (match_dup 0)
14291                       (label_ref (match_dup 1))
14292                       (pc)))]
14293 {
14294   PUT_MODE (operands[0], VOIDmode);
14295 })
14296
14297 (define_split
14298   [(set (pc)
14299         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14300                                       [(reg FLAGS_REG) (const_int 0)])
14301                           (const_int 0))
14302                       (label_ref (match_operand 1 "" ""))
14303                       (pc)))]
14304   ""
14305   [(set (pc)
14306         (if_then_else (match_dup 0)
14307                       (label_ref (match_dup 1))
14308                       (pc)))]
14309 {
14310   rtx new_op0 = copy_rtx (operands[0]);
14311   operands[0] = new_op0;
14312   PUT_MODE (new_op0, VOIDmode);
14313   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14314                                              GET_MODE (XEXP (new_op0, 0))));
14315
14316   /* Make sure that (a) the CCmode we have for the flags is strong
14317      enough for the reversed compare or (b) we have a valid FP compare.  */
14318   if (! ix86_comparison_operator (new_op0, VOIDmode))
14319     FAIL;
14320 })
14321
14322 ;; zero_extend in SImode is correct, since this is what combine pass
14323 ;; generates from shift insn with QImode operand.  Actually, the mode of
14324 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14325 ;; appropriate modulo of the bit offset value.
14326
14327 (define_insn_and_split "*jcc_btdi_rex64"
14328   [(set (pc)
14329         (if_then_else (match_operator 0 "bt_comparison_operator"
14330                         [(zero_extract:DI
14331                            (match_operand:DI 1 "register_operand" "r")
14332                            (const_int 1)
14333                            (zero_extend:SI
14334                              (match_operand:QI 2 "register_operand" "r")))
14335                          (const_int 0)])
14336                       (label_ref (match_operand 3 "" ""))
14337                       (pc)))
14338    (clobber (reg:CC FLAGS_REG))]
14339   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14340   "#"
14341   "&& 1"
14342   [(set (reg:CCC FLAGS_REG)
14343         (compare:CCC
14344           (zero_extract:DI
14345             (match_dup 1)
14346             (const_int 1)
14347             (match_dup 2))
14348           (const_int 0)))
14349    (set (pc)
14350         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14351                       (label_ref (match_dup 3))
14352                       (pc)))]
14353 {
14354   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14355
14356   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14357 })
14358
14359 ;; avoid useless masking of bit offset operand
14360 (define_insn_and_split "*jcc_btdi_mask_rex64"
14361   [(set (pc)
14362         (if_then_else (match_operator 0 "bt_comparison_operator"
14363                         [(zero_extract:DI
14364                            (match_operand:DI 1 "register_operand" "r")
14365                            (const_int 1)
14366                            (and:SI
14367                              (match_operand:SI 2 "register_operand" "r")
14368                              (match_operand:SI 3 "const_int_operand" "n")))])
14369                       (label_ref (match_operand 4 "" ""))
14370                       (pc)))
14371    (clobber (reg:CC FLAGS_REG))]
14372   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14373    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14374   "#"
14375   "&& 1"
14376   [(set (reg:CCC FLAGS_REG)
14377         (compare:CCC
14378           (zero_extract:DI
14379             (match_dup 1)
14380             (const_int 1)
14381             (match_dup 2))
14382           (const_int 0)))
14383    (set (pc)
14384         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14385                       (label_ref (match_dup 4))
14386                       (pc)))]
14387 {
14388   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14389
14390   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14391 })
14392
14393 (define_insn_and_split "*jcc_btsi"
14394   [(set (pc)
14395         (if_then_else (match_operator 0 "bt_comparison_operator"
14396                         [(zero_extract:SI
14397                            (match_operand:SI 1 "register_operand" "r")
14398                            (const_int 1)
14399                            (zero_extend:SI
14400                              (match_operand:QI 2 "register_operand" "r")))
14401                          (const_int 0)])
14402                       (label_ref (match_operand 3 "" ""))
14403                       (pc)))
14404    (clobber (reg:CC FLAGS_REG))]
14405   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14406   "#"
14407   "&& 1"
14408   [(set (reg:CCC FLAGS_REG)
14409         (compare:CCC
14410           (zero_extract:SI
14411             (match_dup 1)
14412             (const_int 1)
14413             (match_dup 2))
14414           (const_int 0)))
14415    (set (pc)
14416         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14417                       (label_ref (match_dup 3))
14418                       (pc)))]
14419 {
14420   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14421
14422   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14423 })
14424
14425 ;; avoid useless masking of bit offset operand
14426 (define_insn_and_split "*jcc_btsi_mask"
14427   [(set (pc)
14428         (if_then_else (match_operator 0 "bt_comparison_operator"
14429                         [(zero_extract:SI
14430                            (match_operand:SI 1 "register_operand" "r")
14431                            (const_int 1)
14432                            (and:SI
14433                              (match_operand:SI 2 "register_operand" "r")
14434                              (match_operand:SI 3 "const_int_operand" "n")))])
14435                       (label_ref (match_operand 4 "" ""))
14436                       (pc)))
14437    (clobber (reg:CC FLAGS_REG))]
14438   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14439    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14440   "#"
14441   "&& 1"
14442   [(set (reg:CCC FLAGS_REG)
14443         (compare:CCC
14444           (zero_extract:SI
14445             (match_dup 1)
14446             (const_int 1)
14447             (match_dup 2))
14448           (const_int 0)))
14449    (set (pc)
14450         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14451                       (label_ref (match_dup 4))
14452                       (pc)))]
14453   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14454
14455 (define_insn_and_split "*jcc_btsi_1"
14456   [(set (pc)
14457         (if_then_else (match_operator 0 "bt_comparison_operator"
14458                         [(and:SI
14459                            (lshiftrt:SI
14460                              (match_operand:SI 1 "register_operand" "r")
14461                              (match_operand:QI 2 "register_operand" "r"))
14462                            (const_int 1))
14463                          (const_int 0)])
14464                       (label_ref (match_operand 3 "" ""))
14465                       (pc)))
14466    (clobber (reg:CC FLAGS_REG))]
14467   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14468   "#"
14469   "&& 1"
14470   [(set (reg:CCC FLAGS_REG)
14471         (compare:CCC
14472           (zero_extract:SI
14473             (match_dup 1)
14474             (const_int 1)
14475             (match_dup 2))
14476           (const_int 0)))
14477    (set (pc)
14478         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14479                       (label_ref (match_dup 3))
14480                       (pc)))]
14481 {
14482   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14483
14484   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14485 })
14486
14487 ;; avoid useless masking of bit offset operand
14488 (define_insn_and_split "*jcc_btsi_mask_1"
14489   [(set (pc)
14490         (if_then_else
14491           (match_operator 0 "bt_comparison_operator"
14492             [(and:SI
14493                (lshiftrt:SI
14494                  (match_operand:SI 1 "register_operand" "r")
14495                  (subreg:QI
14496                    (and:SI
14497                      (match_operand:SI 2 "register_operand" "r")
14498                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14499                (const_int 1))
14500              (const_int 0)])
14501           (label_ref (match_operand 4 "" ""))
14502           (pc)))
14503    (clobber (reg:CC FLAGS_REG))]
14504   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14505    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14506   "#"
14507   "&& 1"
14508   [(set (reg:CCC FLAGS_REG)
14509         (compare:CCC
14510           (zero_extract:SI
14511             (match_dup 1)
14512             (const_int 1)
14513             (match_dup 2))
14514           (const_int 0)))
14515    (set (pc)
14516         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14517                       (label_ref (match_dup 4))
14518                       (pc)))]
14519   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14520
14521 ;; Define combination compare-and-branch fp compare instructions to use
14522 ;; during early optimization.  Splitting the operation apart early makes
14523 ;; for bad code when we want to reverse the operation.
14524
14525 (define_insn "*fp_jcc_1_mixed"
14526   [(set (pc)
14527         (if_then_else (match_operator 0 "comparison_operator"
14528                         [(match_operand 1 "register_operand" "f,x")
14529                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14530           (label_ref (match_operand 3 "" ""))
14531           (pc)))
14532    (clobber (reg:CCFP FPSR_REG))
14533    (clobber (reg:CCFP FLAGS_REG))]
14534   "TARGET_MIX_SSE_I387
14535    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14536    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14537    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14538   "#")
14539
14540 (define_insn "*fp_jcc_1_sse"
14541   [(set (pc)
14542         (if_then_else (match_operator 0 "comparison_operator"
14543                         [(match_operand 1 "register_operand" "x")
14544                          (match_operand 2 "nonimmediate_operand" "xm")])
14545           (label_ref (match_operand 3 "" ""))
14546           (pc)))
14547    (clobber (reg:CCFP FPSR_REG))
14548    (clobber (reg:CCFP FLAGS_REG))]
14549   "TARGET_SSE_MATH
14550    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14551    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14552    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14553   "#")
14554
14555 (define_insn "*fp_jcc_1_387"
14556   [(set (pc)
14557         (if_then_else (match_operator 0 "comparison_operator"
14558                         [(match_operand 1 "register_operand" "f")
14559                          (match_operand 2 "register_operand" "f")])
14560           (label_ref (match_operand 3 "" ""))
14561           (pc)))
14562    (clobber (reg:CCFP FPSR_REG))
14563    (clobber (reg:CCFP FLAGS_REG))]
14564   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14565    && TARGET_CMOVE
14566    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14567    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14568   "#")
14569
14570 (define_insn "*fp_jcc_2_mixed"
14571   [(set (pc)
14572         (if_then_else (match_operator 0 "comparison_operator"
14573                         [(match_operand 1 "register_operand" "f,x")
14574                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14575           (pc)
14576           (label_ref (match_operand 3 "" ""))))
14577    (clobber (reg:CCFP FPSR_REG))
14578    (clobber (reg:CCFP FLAGS_REG))]
14579   "TARGET_MIX_SSE_I387
14580    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14581    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14582    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14583   "#")
14584
14585 (define_insn "*fp_jcc_2_sse"
14586   [(set (pc)
14587         (if_then_else (match_operator 0 "comparison_operator"
14588                         [(match_operand 1 "register_operand" "x")
14589                          (match_operand 2 "nonimmediate_operand" "xm")])
14590           (pc)
14591           (label_ref (match_operand 3 "" ""))))
14592    (clobber (reg:CCFP FPSR_REG))
14593    (clobber (reg:CCFP FLAGS_REG))]
14594   "TARGET_SSE_MATH
14595    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14596    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14597    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14598   "#")
14599
14600 (define_insn "*fp_jcc_2_387"
14601   [(set (pc)
14602         (if_then_else (match_operator 0 "comparison_operator"
14603                         [(match_operand 1 "register_operand" "f")
14604                          (match_operand 2 "register_operand" "f")])
14605           (pc)
14606           (label_ref (match_operand 3 "" ""))))
14607    (clobber (reg:CCFP FPSR_REG))
14608    (clobber (reg:CCFP FLAGS_REG))]
14609   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14610    && TARGET_CMOVE
14611    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14612    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14613   "#")
14614
14615 (define_insn "*fp_jcc_3_387"
14616   [(set (pc)
14617         (if_then_else (match_operator 0 "comparison_operator"
14618                         [(match_operand 1 "register_operand" "f")
14619                          (match_operand 2 "nonimmediate_operand" "fm")])
14620           (label_ref (match_operand 3 "" ""))
14621           (pc)))
14622    (clobber (reg:CCFP FPSR_REG))
14623    (clobber (reg:CCFP FLAGS_REG))
14624    (clobber (match_scratch:HI 4 "=a"))]
14625   "TARGET_80387
14626    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14627    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14628    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14629    && SELECT_CC_MODE (GET_CODE (operands[0]),
14630                       operands[1], operands[2]) == CCFPmode
14631    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14632   "#")
14633
14634 (define_insn "*fp_jcc_4_387"
14635   [(set (pc)
14636         (if_then_else (match_operator 0 "comparison_operator"
14637                         [(match_operand 1 "register_operand" "f")
14638                          (match_operand 2 "nonimmediate_operand" "fm")])
14639           (pc)
14640           (label_ref (match_operand 3 "" ""))))
14641    (clobber (reg:CCFP FPSR_REG))
14642    (clobber (reg:CCFP FLAGS_REG))
14643    (clobber (match_scratch:HI 4 "=a"))]
14644   "TARGET_80387
14645    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14646    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14647    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14648    && SELECT_CC_MODE (GET_CODE (operands[0]),
14649                       operands[1], operands[2]) == CCFPmode
14650    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14651   "#")
14652
14653 (define_insn "*fp_jcc_5_387"
14654   [(set (pc)
14655         (if_then_else (match_operator 0 "comparison_operator"
14656                         [(match_operand 1 "register_operand" "f")
14657                          (match_operand 2 "register_operand" "f")])
14658           (label_ref (match_operand 3 "" ""))
14659           (pc)))
14660    (clobber (reg:CCFP FPSR_REG))
14661    (clobber (reg:CCFP FLAGS_REG))
14662    (clobber (match_scratch:HI 4 "=a"))]
14663   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14664    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14665    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14666   "#")
14667
14668 (define_insn "*fp_jcc_6_387"
14669   [(set (pc)
14670         (if_then_else (match_operator 0 "comparison_operator"
14671                         [(match_operand 1 "register_operand" "f")
14672                          (match_operand 2 "register_operand" "f")])
14673           (pc)
14674           (label_ref (match_operand 3 "" ""))))
14675    (clobber (reg:CCFP FPSR_REG))
14676    (clobber (reg:CCFP FLAGS_REG))
14677    (clobber (match_scratch:HI 4 "=a"))]
14678   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14679    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14681   "#")
14682
14683 (define_insn "*fp_jcc_7_387"
14684   [(set (pc)
14685         (if_then_else (match_operator 0 "comparison_operator"
14686                         [(match_operand 1 "register_operand" "f")
14687                          (match_operand 2 "const0_operand" "")])
14688           (label_ref (match_operand 3 "" ""))
14689           (pc)))
14690    (clobber (reg:CCFP FPSR_REG))
14691    (clobber (reg:CCFP FLAGS_REG))
14692    (clobber (match_scratch:HI 4 "=a"))]
14693   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14694    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14695    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14696    && SELECT_CC_MODE (GET_CODE (operands[0]),
14697                       operands[1], operands[2]) == CCFPmode
14698    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14699   "#")
14700
14701 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14702 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14703 ;; with a precedence over other operators and is always put in the first
14704 ;; place. Swap condition and operands to match ficom instruction.
14705
14706 (define_insn "*fp_jcc_8<mode>_387"
14707   [(set (pc)
14708         (if_then_else (match_operator 0 "comparison_operator"
14709                         [(match_operator 1 "float_operator"
14710                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14711                            (match_operand 3 "register_operand" "f,f")])
14712           (label_ref (match_operand 4 "" ""))
14713           (pc)))
14714    (clobber (reg:CCFP FPSR_REG))
14715    (clobber (reg:CCFP FLAGS_REG))
14716    (clobber (match_scratch:HI 5 "=a,a"))]
14717   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14718    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14719    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14720    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14721    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14722    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14723   "#")
14724
14725 (define_split
14726   [(set (pc)
14727         (if_then_else (match_operator 0 "comparison_operator"
14728                         [(match_operand 1 "register_operand" "")
14729                          (match_operand 2 "nonimmediate_operand" "")])
14730           (match_operand 3 "" "")
14731           (match_operand 4 "" "")))
14732    (clobber (reg:CCFP FPSR_REG))
14733    (clobber (reg:CCFP FLAGS_REG))]
14734   "reload_completed"
14735   [(const_int 0)]
14736 {
14737   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14738                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14739   DONE;
14740 })
14741
14742 (define_split
14743   [(set (pc)
14744         (if_then_else (match_operator 0 "comparison_operator"
14745                         [(match_operand 1 "register_operand" "")
14746                          (match_operand 2 "general_operand" "")])
14747           (match_operand 3 "" "")
14748           (match_operand 4 "" "")))
14749    (clobber (reg:CCFP FPSR_REG))
14750    (clobber (reg:CCFP FLAGS_REG))
14751    (clobber (match_scratch:HI 5 "=a"))]
14752   "reload_completed"
14753   [(const_int 0)]
14754 {
14755   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14756                         operands[3], operands[4], operands[5], NULL_RTX);
14757   DONE;
14758 })
14759
14760 (define_split
14761   [(set (pc)
14762         (if_then_else (match_operator 0 "comparison_operator"
14763                         [(match_operator 1 "float_operator"
14764                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14765                            (match_operand 3 "register_operand" "")])
14766           (match_operand 4 "" "")
14767           (match_operand 5 "" "")))
14768    (clobber (reg:CCFP FPSR_REG))
14769    (clobber (reg:CCFP FLAGS_REG))
14770    (clobber (match_scratch:HI 6 "=a"))]
14771   "reload_completed"
14772   [(const_int 0)]
14773 {
14774   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14775   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14776                         operands[3], operands[7],
14777                         operands[4], operands[5], operands[6], NULL_RTX);
14778   DONE;
14779 })
14780
14781 ;; %%% Kill this when reload knows how to do it.
14782 (define_split
14783   [(set (pc)
14784         (if_then_else (match_operator 0 "comparison_operator"
14785                         [(match_operator 1 "float_operator"
14786                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14787                            (match_operand 3 "register_operand" "")])
14788           (match_operand 4 "" "")
14789           (match_operand 5 "" "")))
14790    (clobber (reg:CCFP FPSR_REG))
14791    (clobber (reg:CCFP FLAGS_REG))
14792    (clobber (match_scratch:HI 6 "=a"))]
14793   "reload_completed"
14794   [(const_int 0)]
14795 {
14796   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14797   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14798   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14799                         operands[3], operands[7],
14800                         operands[4], operands[5], operands[6], operands[2]);
14801   DONE;
14802 })
14803 \f
14804 ;; Unconditional and other jump instructions
14805
14806 (define_insn "jump"
14807   [(set (pc)
14808         (label_ref (match_operand 0 "" "")))]
14809   ""
14810   "jmp\t%l0"
14811   [(set_attr "type" "ibr")
14812    (set (attr "length")
14813            (if_then_else (and (ge (minus (match_dup 0) (pc))
14814                                   (const_int -126))
14815                               (lt (minus (match_dup 0) (pc))
14816                                   (const_int 128)))
14817              (const_int 2)
14818              (const_int 5)))
14819    (set_attr "modrm" "0")])
14820
14821 (define_expand "indirect_jump"
14822   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14823   ""
14824   "")
14825
14826 (define_insn "*indirect_jump"
14827   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14828   ""
14829   "jmp\t%A0"
14830   [(set_attr "type" "ibr")
14831    (set_attr "length_immediate" "0")])
14832
14833 (define_expand "tablejump"
14834   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14835               (use (label_ref (match_operand 1 "" "")))])]
14836   ""
14837 {
14838   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14839      relative.  Convert the relative address to an absolute address.  */
14840   if (flag_pic)
14841     {
14842       rtx op0, op1;
14843       enum rtx_code code;
14844
14845       /* We can't use @GOTOFF for text labels on VxWorks;
14846          see gotoff_operand.  */
14847       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14848         {
14849           code = PLUS;
14850           op0 = operands[0];
14851           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14852         }
14853       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14854         {
14855           code = PLUS;
14856           op0 = operands[0];
14857           op1 = pic_offset_table_rtx;
14858         }
14859       else
14860         {
14861           code = MINUS;
14862           op0 = pic_offset_table_rtx;
14863           op1 = operands[0];
14864         }
14865
14866       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14867                                          OPTAB_DIRECT);
14868     }
14869 })
14870
14871 (define_insn "*tablejump_1"
14872   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14873    (use (label_ref (match_operand 1 "" "")))]
14874   ""
14875   "jmp\t%A0"
14876   [(set_attr "type" "ibr")
14877    (set_attr "length_immediate" "0")])
14878 \f
14879 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14880
14881 (define_peephole2
14882   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14883    (set (match_operand:QI 1 "register_operand" "")
14884         (match_operator:QI 2 "ix86_comparison_operator"
14885           [(reg FLAGS_REG) (const_int 0)]))
14886    (set (match_operand 3 "q_regs_operand" "")
14887         (zero_extend (match_dup 1)))]
14888   "(peep2_reg_dead_p (3, operands[1])
14889     || operands_match_p (operands[1], operands[3]))
14890    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14891   [(set (match_dup 4) (match_dup 0))
14892    (set (strict_low_part (match_dup 5))
14893         (match_dup 2))]
14894 {
14895   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14896   operands[5] = gen_lowpart (QImode, operands[3]);
14897   ix86_expand_clear (operands[3]);
14898 })
14899
14900 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14901
14902 (define_peephole2
14903   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14904    (set (match_operand:QI 1 "register_operand" "")
14905         (match_operator:QI 2 "ix86_comparison_operator"
14906           [(reg FLAGS_REG) (const_int 0)]))
14907    (parallel [(set (match_operand 3 "q_regs_operand" "")
14908                    (zero_extend (match_dup 1)))
14909               (clobber (reg:CC FLAGS_REG))])]
14910   "(peep2_reg_dead_p (3, operands[1])
14911     || operands_match_p (operands[1], operands[3]))
14912    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14913   [(set (match_dup 4) (match_dup 0))
14914    (set (strict_low_part (match_dup 5))
14915         (match_dup 2))]
14916 {
14917   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14918   operands[5] = gen_lowpart (QImode, operands[3]);
14919   ix86_expand_clear (operands[3]);
14920 })
14921 \f
14922 ;; Call instructions.
14923
14924 ;; The predicates normally associated with named expanders are not properly
14925 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14926 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14927
14928 ;; Call subroutine returning no value.
14929
14930 (define_expand "call_pop"
14931   [(parallel [(call (match_operand:QI 0 "" "")
14932                     (match_operand:SI 1 "" ""))
14933               (set (reg:SI SP_REG)
14934                    (plus:SI (reg:SI SP_REG)
14935                             (match_operand:SI 3 "" "")))])]
14936   "!TARGET_64BIT"
14937 {
14938   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14939   DONE;
14940 })
14941
14942 (define_insn "*call_pop_0"
14943   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14944          (match_operand:SI 1 "" ""))
14945    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14946                             (match_operand:SI 2 "immediate_operand" "")))]
14947   "!TARGET_64BIT"
14948 {
14949   if (SIBLING_CALL_P (insn))
14950     return "jmp\t%P0";
14951   else
14952     return "call\t%P0";
14953 }
14954   [(set_attr "type" "call")])
14955
14956 (define_insn "*call_pop_1"
14957   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14958          (match_operand:SI 1 "" ""))
14959    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14960                             (match_operand:SI 2 "immediate_operand" "i")))]
14961   "!TARGET_64BIT"
14962 {
14963   if (constant_call_address_operand (operands[0], Pmode))
14964     {
14965       if (SIBLING_CALL_P (insn))
14966         return "jmp\t%P0";
14967       else
14968         return "call\t%P0";
14969     }
14970   if (SIBLING_CALL_P (insn))
14971     return "jmp\t%A0";
14972   else
14973     return "call\t%A0";
14974 }
14975   [(set_attr "type" "call")])
14976
14977 (define_expand "call"
14978   [(call (match_operand:QI 0 "" "")
14979          (match_operand 1 "" ""))
14980    (use (match_operand 2 "" ""))]
14981   ""
14982 {
14983   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14984   DONE;
14985 })
14986
14987 (define_expand "sibcall"
14988   [(call (match_operand:QI 0 "" "")
14989          (match_operand 1 "" ""))
14990    (use (match_operand 2 "" ""))]
14991   ""
14992 {
14993   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14994   DONE;
14995 })
14996
14997 (define_insn "*call_0"
14998   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14999          (match_operand 1 "" ""))]
15000   ""
15001 {
15002   if (SIBLING_CALL_P (insn))
15003     return "jmp\t%P0";
15004   else
15005     return "call\t%P0";
15006 }
15007   [(set_attr "type" "call")])
15008
15009 (define_insn "*call_1"
15010   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15011          (match_operand 1 "" ""))]
15012   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15013 {
15014   if (constant_call_address_operand (operands[0], Pmode))
15015     return "call\t%P0";
15016   return "call\t%A0";
15017 }
15018   [(set_attr "type" "call")])
15019
15020 (define_insn "*sibcall_1"
15021   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15022          (match_operand 1 "" ""))]
15023   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15024 {
15025   if (constant_call_address_operand (operands[0], Pmode))
15026     return "jmp\t%P0";
15027   return "jmp\t%A0";
15028 }
15029   [(set_attr "type" "call")])
15030
15031 (define_insn "*call_1_rex64"
15032   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15033          (match_operand 1 "" ""))]
15034   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15035    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15036 {
15037   if (constant_call_address_operand (operands[0], Pmode))
15038     return "call\t%P0";
15039   return "call\t%A0";
15040 }
15041   [(set_attr "type" "call")])
15042
15043 (define_insn "*call_1_rex64_ms_sysv"
15044   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15045          (match_operand 1 "" ""))
15046    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15047    (clobber (reg:TI 27))
15048    (clobber (reg:TI 28))
15049    (clobber (reg:TI 45))
15050    (clobber (reg:TI 46))
15051    (clobber (reg:TI 47))
15052    (clobber (reg:TI 48))
15053    (clobber (reg:TI 49))
15054    (clobber (reg:TI 50))
15055    (clobber (reg:TI 51))
15056    (clobber (reg:TI 52))
15057    (clobber (reg:DI SI_REG))
15058    (clobber (reg:DI DI_REG))]
15059   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15060 {
15061   if (constant_call_address_operand (operands[0], Pmode))
15062     return "call\t%P0";
15063   return "call\t%A0";
15064 }
15065   [(set_attr "type" "call")])
15066
15067 (define_insn "*call_1_rex64_large"
15068   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15069          (match_operand 1 "" ""))]
15070   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15071   "call\t%A0"
15072   [(set_attr "type" "call")])
15073
15074 (define_insn "*sibcall_1_rex64"
15075   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15076          (match_operand 1 "" ""))]
15077   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15078   "jmp\t%P0"
15079   [(set_attr "type" "call")])
15080
15081 (define_insn "*sibcall_1_rex64_v"
15082   [(call (mem:QI (reg:DI R11_REG))
15083          (match_operand 0 "" ""))]
15084   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15085   "jmp\t{*%%}r11"
15086   [(set_attr "type" "call")])
15087
15088
15089 ;; Call subroutine, returning value in operand 0
15090
15091 (define_expand "call_value_pop"
15092   [(parallel [(set (match_operand 0 "" "")
15093                    (call (match_operand:QI 1 "" "")
15094                          (match_operand:SI 2 "" "")))
15095               (set (reg:SI SP_REG)
15096                    (plus:SI (reg:SI SP_REG)
15097                             (match_operand:SI 4 "" "")))])]
15098   "!TARGET_64BIT"
15099 {
15100   ix86_expand_call (operands[0], operands[1], operands[2],
15101                     operands[3], operands[4], 0);
15102   DONE;
15103 })
15104
15105 (define_expand "call_value"
15106   [(set (match_operand 0 "" "")
15107         (call (match_operand:QI 1 "" "")
15108               (match_operand:SI 2 "" "")))
15109    (use (match_operand:SI 3 "" ""))]
15110   ;; Operand 2 not used on the i386.
15111   ""
15112 {
15113   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15114   DONE;
15115 })
15116
15117 (define_expand "sibcall_value"
15118   [(set (match_operand 0 "" "")
15119         (call (match_operand:QI 1 "" "")
15120               (match_operand:SI 2 "" "")))
15121    (use (match_operand:SI 3 "" ""))]
15122   ;; Operand 2 not used on the i386.
15123   ""
15124 {
15125   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15126   DONE;
15127 })
15128
15129 ;; Call subroutine returning any type.
15130
15131 (define_expand "untyped_call"
15132   [(parallel [(call (match_operand 0 "" "")
15133                     (const_int 0))
15134               (match_operand 1 "" "")
15135               (match_operand 2 "" "")])]
15136   ""
15137 {
15138   int i;
15139
15140   /* In order to give reg-stack an easier job in validating two
15141      coprocessor registers as containing a possible return value,
15142      simply pretend the untyped call returns a complex long double
15143      value.  */
15144
15145   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15146                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15147                     operands[0], const0_rtx,
15148                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15149                                                       : X64_SSE_REGPARM_MAX)
15150                              - 1),
15151                     NULL, 0);
15152
15153   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15154     {
15155       rtx set = XVECEXP (operands[2], 0, i);
15156       emit_move_insn (SET_DEST (set), SET_SRC (set));
15157     }
15158
15159   /* The optimizer does not know that the call sets the function value
15160      registers we stored in the result block.  We avoid problems by
15161      claiming that all hard registers are used and clobbered at this
15162      point.  */
15163   emit_insn (gen_blockage ());
15164
15165   DONE;
15166 })
15167 \f
15168 ;; Prologue and epilogue instructions
15169
15170 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15171 ;; all of memory.  This blocks insns from being moved across this point.
15172
15173 (define_insn "blockage"
15174   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15175   ""
15176   ""
15177   [(set_attr "length" "0")])
15178
15179 ;; Do not schedule instructions accessing memory across this point.
15180
15181 (define_expand "memory_blockage"
15182   [(set (match_dup 0)
15183         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15184   ""
15185 {
15186   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15187   MEM_VOLATILE_P (operands[0]) = 1;
15188 })
15189
15190 (define_insn "*memory_blockage"
15191   [(set (match_operand:BLK 0 "" "")
15192         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15193   ""
15194   ""
15195   [(set_attr "length" "0")])
15196
15197 ;; As USE insns aren't meaningful after reload, this is used instead
15198 ;; to prevent deleting instructions setting registers for PIC code
15199 (define_insn "prologue_use"
15200   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15201   ""
15202   ""
15203   [(set_attr "length" "0")])
15204
15205 ;; Insn emitted into the body of a function to return from a function.
15206 ;; This is only done if the function's epilogue is known to be simple.
15207 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15208
15209 (define_expand "return"
15210   [(return)]
15211   "ix86_can_use_return_insn_p ()"
15212 {
15213   if (crtl->args.pops_args)
15214     {
15215       rtx popc = GEN_INT (crtl->args.pops_args);
15216       emit_jump_insn (gen_return_pop_internal (popc));
15217       DONE;
15218     }
15219 })
15220
15221 (define_insn "return_internal"
15222   [(return)]
15223   "reload_completed"
15224   "ret"
15225   [(set_attr "length" "1")
15226    (set_attr "length_immediate" "0")
15227    (set_attr "modrm" "0")])
15228
15229 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15230 ;; instruction Athlon and K8 have.
15231
15232 (define_insn "return_internal_long"
15233   [(return)
15234    (unspec [(const_int 0)] UNSPEC_REP)]
15235   "reload_completed"
15236   "rep\;ret"
15237   [(set_attr "length" "1")
15238    (set_attr "length_immediate" "0")
15239    (set_attr "prefix_rep" "1")
15240    (set_attr "modrm" "0")])
15241
15242 (define_insn "return_pop_internal"
15243   [(return)
15244    (use (match_operand:SI 0 "const_int_operand" ""))]
15245   "reload_completed"
15246   "ret\t%0"
15247   [(set_attr "length" "3")
15248    (set_attr "length_immediate" "2")
15249    (set_attr "modrm" "0")])
15250
15251 (define_insn "return_indirect_internal"
15252   [(return)
15253    (use (match_operand:SI 0 "register_operand" "r"))]
15254   "reload_completed"
15255   "jmp\t%A0"
15256   [(set_attr "type" "ibr")
15257    (set_attr "length_immediate" "0")])
15258
15259 (define_insn "nop"
15260   [(const_int 0)]
15261   ""
15262   "nop"
15263   [(set_attr "length" "1")
15264    (set_attr "length_immediate" "0")
15265    (set_attr "modrm" "0")])
15266
15267 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15268 ;; branch prediction penalty for the third jump in a 16-byte
15269 ;; block on K8.
15270
15271 (define_insn "align"
15272   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15273   ""
15274 {
15275 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15276   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15277 #else
15278   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15279      The align insn is used to avoid 3 jump instructions in the row to improve
15280      branch prediction and the benefits hardly outweigh the cost of extra 8
15281      nops on the average inserted by full alignment pseudo operation.  */
15282 #endif
15283   return "";
15284 }
15285   [(set_attr "length" "16")])
15286
15287 (define_expand "prologue"
15288   [(const_int 0)]
15289   ""
15290   "ix86_expand_prologue (); DONE;")
15291
15292 (define_insn "set_got"
15293   [(set (match_operand:SI 0 "register_operand" "=r")
15294         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15295    (clobber (reg:CC FLAGS_REG))]
15296   "!TARGET_64BIT"
15297   { return output_set_got (operands[0], NULL_RTX); }
15298   [(set_attr "type" "multi")
15299    (set_attr "length" "12")])
15300
15301 (define_insn "set_got_labelled"
15302   [(set (match_operand:SI 0 "register_operand" "=r")
15303         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15304          UNSPEC_SET_GOT))
15305    (clobber (reg:CC FLAGS_REG))]
15306   "!TARGET_64BIT"
15307   { return output_set_got (operands[0], operands[1]); }
15308   [(set_attr "type" "multi")
15309    (set_attr "length" "12")])
15310
15311 (define_insn "set_got_rex64"
15312   [(set (match_operand:DI 0 "register_operand" "=r")
15313         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15314   "TARGET_64BIT"
15315   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15316   [(set_attr "type" "lea")
15317    (set_attr "length" "6")])
15318
15319 (define_insn "set_rip_rex64"
15320   [(set (match_operand:DI 0 "register_operand" "=r")
15321         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15322   "TARGET_64BIT"
15323   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15324   [(set_attr "type" "lea")
15325    (set_attr "length" "6")])
15326
15327 (define_insn "set_got_offset_rex64"
15328   [(set (match_operand:DI 0 "register_operand" "=r")
15329         (unspec:DI
15330           [(label_ref (match_operand 1 "" ""))]
15331           UNSPEC_SET_GOT_OFFSET))]
15332   "TARGET_64BIT"
15333   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15334   [(set_attr "type" "imov")
15335    (set_attr "length" "11")])
15336
15337 (define_expand "epilogue"
15338   [(const_int 0)]
15339   ""
15340   "ix86_expand_epilogue (1); DONE;")
15341
15342 (define_expand "sibcall_epilogue"
15343   [(const_int 0)]
15344   ""
15345   "ix86_expand_epilogue (0); DONE;")
15346
15347 (define_expand "eh_return"
15348   [(use (match_operand 0 "register_operand" ""))]
15349   ""
15350 {
15351   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15352
15353   /* Tricky bit: we write the address of the handler to which we will
15354      be returning into someone else's stack frame, one word below the
15355      stack address we wish to restore.  */
15356   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15357   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15358   tmp = gen_rtx_MEM (Pmode, tmp);
15359   emit_move_insn (tmp, ra);
15360
15361   if (Pmode == SImode)
15362     emit_jump_insn (gen_eh_return_si (sa));
15363   else
15364     emit_jump_insn (gen_eh_return_di (sa));
15365   emit_barrier ();
15366   DONE;
15367 })
15368
15369 (define_insn_and_split "eh_return_<mode>"
15370   [(set (pc)
15371         (unspec [(match_operand:P 0 "register_operand" "c")]
15372                  UNSPEC_EH_RETURN))]
15373   ""
15374   "#"
15375   "reload_completed"
15376   [(const_int 0)]
15377   "ix86_expand_epilogue (2); DONE;")
15378
15379 (define_insn "leave"
15380   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15381    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15382    (clobber (mem:BLK (scratch)))]
15383   "!TARGET_64BIT"
15384   "leave"
15385   [(set_attr "type" "leave")])
15386
15387 (define_insn "leave_rex64"
15388   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15389    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15390    (clobber (mem:BLK (scratch)))]
15391   "TARGET_64BIT"
15392   "leave"
15393   [(set_attr "type" "leave")])
15394 \f
15395 (define_expand "ffssi2"
15396   [(parallel
15397      [(set (match_operand:SI 0 "register_operand" "")
15398            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15399       (clobber (match_scratch:SI 2 ""))
15400       (clobber (reg:CC FLAGS_REG))])]
15401   ""
15402 {
15403   if (TARGET_CMOVE)
15404     {
15405       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15406       DONE;
15407     }
15408 })
15409
15410 (define_expand "ffs_cmove"
15411   [(set (match_dup 2) (const_int -1))
15412    (parallel [(set (reg:CCZ FLAGS_REG)
15413                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15414                                 (const_int 0)))
15415               (set (match_operand:SI 0 "register_operand" "")
15416                    (ctz:SI (match_dup 1)))])
15417    (set (match_dup 0) (if_then_else:SI
15418                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15419                         (match_dup 2)
15420                         (match_dup 0)))
15421    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15422               (clobber (reg:CC FLAGS_REG))])]
15423   "TARGET_CMOVE"
15424   "operands[2] = gen_reg_rtx (SImode);")
15425
15426 (define_insn_and_split "*ffs_no_cmove"
15427   [(set (match_operand:SI 0 "register_operand" "=r")
15428         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15429    (clobber (match_scratch:SI 2 "=&q"))
15430    (clobber (reg:CC FLAGS_REG))]
15431   "!TARGET_CMOVE"
15432   "#"
15433   "&& reload_completed"
15434   [(parallel [(set (reg:CCZ FLAGS_REG)
15435                    (compare:CCZ (match_dup 1) (const_int 0)))
15436               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15437    (set (strict_low_part (match_dup 3))
15438         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15439    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15440               (clobber (reg:CC FLAGS_REG))])
15441    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15442               (clobber (reg:CC FLAGS_REG))])
15443    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15444               (clobber (reg:CC FLAGS_REG))])]
15445 {
15446   operands[3] = gen_lowpart (QImode, operands[2]);
15447   ix86_expand_clear (operands[2]);
15448 })
15449
15450 (define_insn "*ffssi_1"
15451   [(set (reg:CCZ FLAGS_REG)
15452         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15453                      (const_int 0)))
15454    (set (match_operand:SI 0 "register_operand" "=r")
15455         (ctz:SI (match_dup 1)))]
15456   ""
15457   "bsf{l}\t{%1, %0|%0, %1}"
15458   [(set_attr "prefix_0f" "1")])
15459
15460 (define_expand "ffsdi2"
15461   [(set (match_dup 2) (const_int -1))
15462    (parallel [(set (reg:CCZ FLAGS_REG)
15463                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15464                                 (const_int 0)))
15465               (set (match_operand:DI 0 "register_operand" "")
15466                    (ctz:DI (match_dup 1)))])
15467    (set (match_dup 0) (if_then_else:DI
15468                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15469                         (match_dup 2)
15470                         (match_dup 0)))
15471    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15472               (clobber (reg:CC FLAGS_REG))])]
15473   "TARGET_64BIT"
15474   "operands[2] = gen_reg_rtx (DImode);")
15475
15476 (define_insn "*ffsdi_1"
15477   [(set (reg:CCZ FLAGS_REG)
15478         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15479                      (const_int 0)))
15480    (set (match_operand:DI 0 "register_operand" "=r")
15481         (ctz:DI (match_dup 1)))]
15482   "TARGET_64BIT"
15483   "bsf{q}\t{%1, %0|%0, %1}"
15484   [(set_attr "prefix_0f" "1")])
15485
15486 (define_insn "ctzsi2"
15487   [(set (match_operand:SI 0 "register_operand" "=r")
15488         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15489    (clobber (reg:CC FLAGS_REG))]
15490   ""
15491   "bsf{l}\t{%1, %0|%0, %1}"
15492   [(set_attr "prefix_0f" "1")])
15493
15494 (define_insn "ctzdi2"
15495   [(set (match_operand:DI 0 "register_operand" "=r")
15496         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15497    (clobber (reg:CC FLAGS_REG))]
15498   "TARGET_64BIT"
15499   "bsf{q}\t{%1, %0|%0, %1}"
15500   [(set_attr "prefix_0f" "1")])
15501
15502 (define_expand "clzsi2"
15503   [(parallel
15504      [(set (match_operand:SI 0 "register_operand" "")
15505            (minus:SI (const_int 31)
15506                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15507       (clobber (reg:CC FLAGS_REG))])
15508    (parallel
15509      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15510       (clobber (reg:CC FLAGS_REG))])]
15511   ""
15512 {
15513   if (TARGET_ABM)
15514     {
15515       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15516       DONE;
15517     }
15518 })
15519
15520 (define_insn "clzsi2_abm"
15521   [(set (match_operand:SI 0 "register_operand" "=r")
15522         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15523    (clobber (reg:CC FLAGS_REG))]
15524   "TARGET_ABM"
15525   "lzcnt{l}\t{%1, %0|%0, %1}"
15526   [(set_attr "prefix_rep" "1")
15527    (set_attr "type" "bitmanip")
15528    (set_attr "mode" "SI")])
15529
15530 (define_insn "*bsr"
15531   [(set (match_operand:SI 0 "register_operand" "=r")
15532         (minus:SI (const_int 31)
15533                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15534    (clobber (reg:CC FLAGS_REG))]
15535   ""
15536   "bsr{l}\t{%1, %0|%0, %1}"
15537   [(set_attr "prefix_0f" "1")
15538    (set_attr "mode" "SI")])
15539
15540 (define_insn "popcount<mode>2"
15541   [(set (match_operand:SWI248 0 "register_operand" "=r")
15542         (popcount:SWI248
15543           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15544    (clobber (reg:CC FLAGS_REG))]
15545   "TARGET_POPCNT"
15546 {
15547 #if TARGET_MACHO
15548   return "popcnt\t{%1, %0|%0, %1}";
15549 #else
15550   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15551 #endif
15552 }
15553   [(set_attr "prefix_rep" "1")
15554    (set_attr "type" "bitmanip")
15555    (set_attr "mode" "<MODE>")])
15556
15557 (define_insn "*popcount<mode>2_cmp"
15558   [(set (reg FLAGS_REG)
15559         (compare
15560           (popcount:SWI248
15561             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15562           (const_int 0)))
15563    (set (match_operand:SWI248 0 "register_operand" "=r")
15564         (popcount:SWI248 (match_dup 1)))]
15565   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15566 {
15567 #if TARGET_MACHO
15568   return "popcnt\t{%1, %0|%0, %1}";
15569 #else
15570   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15571 #endif
15572 }
15573   [(set_attr "prefix_rep" "1")
15574    (set_attr "type" "bitmanip")
15575    (set_attr "mode" "<MODE>")])
15576
15577 (define_insn "*popcountsi2_cmp_zext"
15578   [(set (reg FLAGS_REG)
15579         (compare
15580           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15581           (const_int 0)))
15582    (set (match_operand:DI 0 "register_operand" "=r")
15583         (zero_extend:DI(popcount:SI (match_dup 1))))]
15584   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15585 {
15586 #if TARGET_MACHO
15587   return "popcnt\t{%1, %0|%0, %1}";
15588 #else
15589   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15590 #endif
15591 }
15592   [(set_attr "prefix_rep" "1")
15593    (set_attr "type" "bitmanip")
15594    (set_attr "mode" "SI")])
15595
15596 (define_expand "bswapsi2"
15597   [(set (match_operand:SI 0 "register_operand" "")
15598         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15599   ""
15600 {
15601   if (!TARGET_BSWAP)
15602     {
15603       rtx x = operands[0];
15604
15605       emit_move_insn (x, operands[1]);
15606       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15607       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15608       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15609       DONE;
15610     }
15611 })
15612
15613 (define_insn "*bswapsi_1"
15614   [(set (match_operand:SI 0 "register_operand" "=r")
15615         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15616   "TARGET_BSWAP"
15617   "bswap\t%0"
15618   [(set_attr "prefix_0f" "1")
15619    (set_attr "length" "2")])
15620
15621 (define_insn "*bswaphi_lowpart_1"
15622   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15623         (bswap:HI (match_dup 0)))
15624    (clobber (reg:CC FLAGS_REG))]
15625   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15626   "@
15627     xchg{b}\t{%h0, %b0|%b0, %h0}
15628     rol{w}\t{$8, %0|%0, 8}"
15629   [(set_attr "length" "2,4")
15630    (set_attr "mode" "QI,HI")])
15631
15632 (define_insn "bswaphi_lowpart"
15633   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15634         (bswap:HI (match_dup 0)))
15635    (clobber (reg:CC FLAGS_REG))]
15636   ""
15637   "rol{w}\t{$8, %0|%0, 8}"
15638   [(set_attr "length" "4")
15639    (set_attr "mode" "HI")])
15640
15641 (define_insn "bswapdi2"
15642   [(set (match_operand:DI 0 "register_operand" "=r")
15643         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15644   "TARGET_64BIT"
15645   "bswap\t%0"
15646   [(set_attr "prefix_0f" "1")
15647    (set_attr "length" "3")])
15648
15649 (define_expand "clzdi2"
15650   [(parallel
15651      [(set (match_operand:DI 0 "register_operand" "")
15652            (minus:DI (const_int 63)
15653                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15654       (clobber (reg:CC FLAGS_REG))])
15655    (parallel
15656      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15657       (clobber (reg:CC FLAGS_REG))])]
15658   "TARGET_64BIT"
15659 {
15660   if (TARGET_ABM)
15661     {
15662       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15663       DONE;
15664     }
15665 })
15666
15667 (define_insn "clzdi2_abm"
15668   [(set (match_operand:DI 0 "register_operand" "=r")
15669         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15670    (clobber (reg:CC FLAGS_REG))]
15671   "TARGET_64BIT && TARGET_ABM"
15672   "lzcnt{q}\t{%1, %0|%0, %1}"
15673   [(set_attr "prefix_rep" "1")
15674    (set_attr "type" "bitmanip")
15675    (set_attr "mode" "DI")])
15676
15677 (define_insn "*bsr_rex64"
15678   [(set (match_operand:DI 0 "register_operand" "=r")
15679         (minus:DI (const_int 63)
15680                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15681    (clobber (reg:CC FLAGS_REG))]
15682   "TARGET_64BIT"
15683   "bsr{q}\t{%1, %0|%0, %1}"
15684   [(set_attr "prefix_0f" "1")
15685    (set_attr "mode" "DI")])
15686
15687 (define_expand "clzhi2"
15688   [(parallel
15689      [(set (match_operand:HI 0 "register_operand" "")
15690            (minus:HI (const_int 15)
15691                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15692       (clobber (reg:CC FLAGS_REG))])
15693    (parallel
15694      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15695       (clobber (reg:CC FLAGS_REG))])]
15696   ""
15697 {
15698   if (TARGET_ABM)
15699     {
15700       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15701       DONE;
15702     }
15703 })
15704
15705 (define_insn "clzhi2_abm"
15706   [(set (match_operand:HI 0 "register_operand" "=r")
15707         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15708    (clobber (reg:CC FLAGS_REG))]
15709   "TARGET_ABM"
15710   "lzcnt{w}\t{%1, %0|%0, %1}"
15711   [(set_attr "prefix_rep" "1")
15712    (set_attr "type" "bitmanip")
15713    (set_attr "mode" "HI")])
15714
15715 (define_insn "*bsrhi"
15716   [(set (match_operand:HI 0 "register_operand" "=r")
15717         (minus:HI (const_int 15)
15718                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15719    (clobber (reg:CC FLAGS_REG))]
15720   ""
15721   "bsr{w}\t{%1, %0|%0, %1}"
15722   [(set_attr "prefix_0f" "1")
15723    (set_attr "mode" "HI")])
15724
15725 (define_expand "paritydi2"
15726   [(set (match_operand:DI 0 "register_operand" "")
15727         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15728   "! TARGET_POPCNT"
15729 {
15730   rtx scratch = gen_reg_rtx (QImode);
15731   rtx cond;
15732
15733   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15734                                 NULL_RTX, operands[1]));
15735
15736   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15737                          gen_rtx_REG (CCmode, FLAGS_REG),
15738                          const0_rtx);
15739   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15740
15741   if (TARGET_64BIT)
15742     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15743   else
15744     {
15745       rtx tmp = gen_reg_rtx (SImode);
15746
15747       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15748       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15749     }
15750   DONE;
15751 })
15752
15753 (define_insn_and_split "paritydi2_cmp"
15754   [(set (reg:CC FLAGS_REG)
15755         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15756    (clobber (match_scratch:DI 0 "=r"))
15757    (clobber (match_scratch:SI 1 "=&r"))
15758    (clobber (match_scratch:HI 2 "=Q"))]
15759   "! TARGET_POPCNT"
15760   "#"
15761   "&& reload_completed"
15762   [(parallel
15763      [(set (match_dup 1)
15764            (xor:SI (match_dup 1) (match_dup 4)))
15765       (clobber (reg:CC FLAGS_REG))])
15766    (parallel
15767      [(set (reg:CC FLAGS_REG)
15768            (parity:CC (match_dup 1)))
15769       (clobber (match_dup 1))
15770       (clobber (match_dup 2))])]
15771 {
15772   operands[4] = gen_lowpart (SImode, operands[3]);
15773
15774   if (TARGET_64BIT)
15775     {
15776       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15777       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15778     }
15779   else
15780     operands[1] = gen_highpart (SImode, operands[3]);
15781 })
15782
15783 (define_expand "paritysi2"
15784   [(set (match_operand:SI 0 "register_operand" "")
15785         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15786   "! TARGET_POPCNT"
15787 {
15788   rtx scratch = gen_reg_rtx (QImode);
15789   rtx cond;
15790
15791   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15792
15793   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15794                          gen_rtx_REG (CCmode, FLAGS_REG),
15795                          const0_rtx);
15796   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15797
15798   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15799   DONE;
15800 })
15801
15802 (define_insn_and_split "paritysi2_cmp"
15803   [(set (reg:CC FLAGS_REG)
15804         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15805    (clobber (match_scratch:SI 0 "=r"))
15806    (clobber (match_scratch:HI 1 "=&Q"))]
15807   "! TARGET_POPCNT"
15808   "#"
15809   "&& reload_completed"
15810   [(parallel
15811      [(set (match_dup 1)
15812            (xor:HI (match_dup 1) (match_dup 3)))
15813       (clobber (reg:CC FLAGS_REG))])
15814    (parallel
15815      [(set (reg:CC FLAGS_REG)
15816            (parity:CC (match_dup 1)))
15817       (clobber (match_dup 1))])]
15818 {
15819   operands[3] = gen_lowpart (HImode, operands[2]);
15820
15821   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15822   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15823 })
15824
15825 (define_insn "*parityhi2_cmp"
15826   [(set (reg:CC FLAGS_REG)
15827         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15828    (clobber (match_scratch:HI 0 "=Q"))]
15829   "! TARGET_POPCNT"
15830   "xor{b}\t{%h0, %b0|%b0, %h0}"
15831   [(set_attr "length" "2")
15832    (set_attr "mode" "HI")])
15833
15834 (define_insn "*parityqi2_cmp"
15835   [(set (reg:CC FLAGS_REG)
15836         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15837   "! TARGET_POPCNT"
15838   "test{b}\t%0, %0"
15839   [(set_attr "length" "2")
15840    (set_attr "mode" "QI")])
15841 \f
15842 ;; Thread-local storage patterns for ELF.
15843 ;;
15844 ;; Note that these code sequences must appear exactly as shown
15845 ;; in order to allow linker relaxation.
15846
15847 (define_insn "*tls_global_dynamic_32_gnu"
15848   [(set (match_operand:SI 0 "register_operand" "=a")
15849         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15850                     (match_operand:SI 2 "tls_symbolic_operand" "")
15851                     (match_operand:SI 3 "call_insn_operand" "")]
15852                     UNSPEC_TLS_GD))
15853    (clobber (match_scratch:SI 4 "=d"))
15854    (clobber (match_scratch:SI 5 "=c"))
15855    (clobber (reg:CC FLAGS_REG))]
15856   "!TARGET_64BIT && TARGET_GNU_TLS"
15857   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15858   [(set_attr "type" "multi")
15859    (set_attr "length" "12")])
15860
15861 (define_insn "*tls_global_dynamic_32_sun"
15862   [(set (match_operand:SI 0 "register_operand" "=a")
15863         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15864                     (match_operand:SI 2 "tls_symbolic_operand" "")
15865                     (match_operand:SI 3 "call_insn_operand" "")]
15866                     UNSPEC_TLS_GD))
15867    (clobber (match_scratch:SI 4 "=d"))
15868    (clobber (match_scratch:SI 5 "=c"))
15869    (clobber (reg:CC FLAGS_REG))]
15870   "!TARGET_64BIT && TARGET_SUN_TLS"
15871   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15872         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15873   [(set_attr "type" "multi")
15874    (set_attr "length" "14")])
15875
15876 (define_expand "tls_global_dynamic_32"
15877   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15878                    (unspec:SI
15879                     [(match_dup 2)
15880                      (match_operand:SI 1 "tls_symbolic_operand" "")
15881                      (match_dup 3)]
15882                     UNSPEC_TLS_GD))
15883               (clobber (match_scratch:SI 4 ""))
15884               (clobber (match_scratch:SI 5 ""))
15885               (clobber (reg:CC FLAGS_REG))])]
15886   ""
15887 {
15888   if (flag_pic)
15889     operands[2] = pic_offset_table_rtx;
15890   else
15891     {
15892       operands[2] = gen_reg_rtx (Pmode);
15893       emit_insn (gen_set_got (operands[2]));
15894     }
15895   if (TARGET_GNU2_TLS)
15896     {
15897        emit_insn (gen_tls_dynamic_gnu2_32
15898                   (operands[0], operands[1], operands[2]));
15899        DONE;
15900     }
15901   operands[3] = ix86_tls_get_addr ();
15902 })
15903
15904 (define_insn "*tls_global_dynamic_64"
15905   [(set (match_operand:DI 0 "register_operand" "=a")
15906         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15907                  (match_operand:DI 3 "" "")))
15908    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15909               UNSPEC_TLS_GD)]
15910   "TARGET_64BIT"
15911   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15912   [(set_attr "type" "multi")
15913    (set_attr "length" "16")])
15914
15915 (define_expand "tls_global_dynamic_64"
15916   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15917                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15918               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15919                          UNSPEC_TLS_GD)])]
15920   ""
15921 {
15922   if (TARGET_GNU2_TLS)
15923     {
15924        emit_insn (gen_tls_dynamic_gnu2_64
15925                   (operands[0], operands[1]));
15926        DONE;
15927     }
15928   operands[2] = ix86_tls_get_addr ();
15929 })
15930
15931 (define_insn "*tls_local_dynamic_base_32_gnu"
15932   [(set (match_operand:SI 0 "register_operand" "=a")
15933         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15934                     (match_operand:SI 2 "call_insn_operand" "")]
15935                    UNSPEC_TLS_LD_BASE))
15936    (clobber (match_scratch:SI 3 "=d"))
15937    (clobber (match_scratch:SI 4 "=c"))
15938    (clobber (reg:CC FLAGS_REG))]
15939   "!TARGET_64BIT && TARGET_GNU_TLS"
15940   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15941   [(set_attr "type" "multi")
15942    (set_attr "length" "11")])
15943
15944 (define_insn "*tls_local_dynamic_base_32_sun"
15945   [(set (match_operand:SI 0 "register_operand" "=a")
15946         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15947                     (match_operand:SI 2 "call_insn_operand" "")]
15948                    UNSPEC_TLS_LD_BASE))
15949    (clobber (match_scratch:SI 3 "=d"))
15950    (clobber (match_scratch:SI 4 "=c"))
15951    (clobber (reg:CC FLAGS_REG))]
15952   "!TARGET_64BIT && TARGET_SUN_TLS"
15953   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15954         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15955   [(set_attr "type" "multi")
15956    (set_attr "length" "13")])
15957
15958 (define_expand "tls_local_dynamic_base_32"
15959   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15960                    (unspec:SI [(match_dup 1) (match_dup 2)]
15961                               UNSPEC_TLS_LD_BASE))
15962               (clobber (match_scratch:SI 3 ""))
15963               (clobber (match_scratch:SI 4 ""))
15964               (clobber (reg:CC FLAGS_REG))])]
15965   ""
15966 {
15967   if (flag_pic)
15968     operands[1] = pic_offset_table_rtx;
15969   else
15970     {
15971       operands[1] = gen_reg_rtx (Pmode);
15972       emit_insn (gen_set_got (operands[1]));
15973     }
15974   if (TARGET_GNU2_TLS)
15975     {
15976        emit_insn (gen_tls_dynamic_gnu2_32
15977                   (operands[0], ix86_tls_module_base (), operands[1]));
15978        DONE;
15979     }
15980   operands[2] = ix86_tls_get_addr ();
15981 })
15982
15983 (define_insn "*tls_local_dynamic_base_64"
15984   [(set (match_operand:DI 0 "register_operand" "=a")
15985         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15986                  (match_operand:DI 2 "" "")))
15987    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15988   "TARGET_64BIT"
15989   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15990   [(set_attr "type" "multi")
15991    (set_attr "length" "12")])
15992
15993 (define_expand "tls_local_dynamic_base_64"
15994   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15995                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15996               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15997   ""
15998 {
15999   if (TARGET_GNU2_TLS)
16000     {
16001        emit_insn (gen_tls_dynamic_gnu2_64
16002                   (operands[0], ix86_tls_module_base ()));
16003        DONE;
16004     }
16005   operands[1] = ix86_tls_get_addr ();
16006 })
16007
16008 ;; Local dynamic of a single variable is a lose.  Show combine how
16009 ;; to convert that back to global dynamic.
16010
16011 (define_insn_and_split "*tls_local_dynamic_32_once"
16012   [(set (match_operand:SI 0 "register_operand" "=a")
16013         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16014                              (match_operand:SI 2 "call_insn_operand" "")]
16015                             UNSPEC_TLS_LD_BASE)
16016                  (const:SI (unspec:SI
16017                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16018                             UNSPEC_DTPOFF))))
16019    (clobber (match_scratch:SI 4 "=d"))
16020    (clobber (match_scratch:SI 5 "=c"))
16021    (clobber (reg:CC FLAGS_REG))]
16022   ""
16023   "#"
16024   ""
16025   [(parallel [(set (match_dup 0)
16026                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16027                               UNSPEC_TLS_GD))
16028               (clobber (match_dup 4))
16029               (clobber (match_dup 5))
16030               (clobber (reg:CC FLAGS_REG))])]
16031   "")
16032
16033 ;; Load and add the thread base pointer from %gs:0.
16034
16035 (define_insn "*load_tp_si"
16036   [(set (match_operand:SI 0 "register_operand" "=r")
16037         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16038   "!TARGET_64BIT"
16039   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16040   [(set_attr "type" "imov")
16041    (set_attr "modrm" "0")
16042    (set_attr "length" "7")
16043    (set_attr "memory" "load")
16044    (set_attr "imm_disp" "false")])
16045
16046 (define_insn "*add_tp_si"
16047   [(set (match_operand:SI 0 "register_operand" "=r")
16048         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16049                  (match_operand:SI 1 "register_operand" "0")))
16050    (clobber (reg:CC FLAGS_REG))]
16051   "!TARGET_64BIT"
16052   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16053   [(set_attr "type" "alu")
16054    (set_attr "modrm" "0")
16055    (set_attr "length" "7")
16056    (set_attr "memory" "load")
16057    (set_attr "imm_disp" "false")])
16058
16059 (define_insn "*load_tp_di"
16060   [(set (match_operand:DI 0 "register_operand" "=r")
16061         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16062   "TARGET_64BIT"
16063   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16064   [(set_attr "type" "imov")
16065    (set_attr "modrm" "0")
16066    (set_attr "length" "7")
16067    (set_attr "memory" "load")
16068    (set_attr "imm_disp" "false")])
16069
16070 (define_insn "*add_tp_di"
16071   [(set (match_operand:DI 0 "register_operand" "=r")
16072         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16073                  (match_operand:DI 1 "register_operand" "0")))
16074    (clobber (reg:CC FLAGS_REG))]
16075   "TARGET_64BIT"
16076   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16077   [(set_attr "type" "alu")
16078    (set_attr "modrm" "0")
16079    (set_attr "length" "7")
16080    (set_attr "memory" "load")
16081    (set_attr "imm_disp" "false")])
16082
16083 ;; GNU2 TLS patterns can be split.
16084
16085 (define_expand "tls_dynamic_gnu2_32"
16086   [(set (match_dup 3)
16087         (plus:SI (match_operand:SI 2 "register_operand" "")
16088                  (const:SI
16089                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16090                              UNSPEC_TLSDESC))))
16091    (parallel
16092     [(set (match_operand:SI 0 "register_operand" "")
16093           (unspec:SI [(match_dup 1) (match_dup 3)
16094                       (match_dup 2) (reg:SI SP_REG)]
16095                       UNSPEC_TLSDESC))
16096      (clobber (reg:CC FLAGS_REG))])]
16097   "!TARGET_64BIT && TARGET_GNU2_TLS"
16098 {
16099   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16100   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16101 })
16102
16103 (define_insn "*tls_dynamic_lea_32"
16104   [(set (match_operand:SI 0 "register_operand" "=r")
16105         (plus:SI (match_operand:SI 1 "register_operand" "b")
16106                  (const:SI
16107                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16108                               UNSPEC_TLSDESC))))]
16109   "!TARGET_64BIT && TARGET_GNU2_TLS"
16110   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16111   [(set_attr "type" "lea")
16112    (set_attr "mode" "SI")
16113    (set_attr "length" "6")
16114    (set_attr "length_address" "4")])
16115
16116 (define_insn "*tls_dynamic_call_32"
16117   [(set (match_operand:SI 0 "register_operand" "=a")
16118         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16119                     (match_operand:SI 2 "register_operand" "0")
16120                     ;; we have to make sure %ebx still points to the GOT
16121                     (match_operand:SI 3 "register_operand" "b")
16122                     (reg:SI SP_REG)]
16123                    UNSPEC_TLSDESC))
16124    (clobber (reg:CC FLAGS_REG))]
16125   "!TARGET_64BIT && TARGET_GNU2_TLS"
16126   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16127   [(set_attr "type" "call")
16128    (set_attr "length" "2")
16129    (set_attr "length_address" "0")])
16130
16131 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16132   [(set (match_operand:SI 0 "register_operand" "=&a")
16133         (plus:SI
16134          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16135                      (match_operand:SI 4 "" "")
16136                      (match_operand:SI 2 "register_operand" "b")
16137                      (reg:SI SP_REG)]
16138                     UNSPEC_TLSDESC)
16139          (const:SI (unspec:SI
16140                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16141                     UNSPEC_DTPOFF))))
16142    (clobber (reg:CC FLAGS_REG))]
16143   "!TARGET_64BIT && TARGET_GNU2_TLS"
16144   "#"
16145   ""
16146   [(set (match_dup 0) (match_dup 5))]
16147 {
16148   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16149   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16150 })
16151
16152 (define_expand "tls_dynamic_gnu2_64"
16153   [(set (match_dup 2)
16154         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16155                    UNSPEC_TLSDESC))
16156    (parallel
16157     [(set (match_operand:DI 0 "register_operand" "")
16158           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16159                      UNSPEC_TLSDESC))
16160      (clobber (reg:CC FLAGS_REG))])]
16161   "TARGET_64BIT && TARGET_GNU2_TLS"
16162 {
16163   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16164   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16165 })
16166
16167 (define_insn "*tls_dynamic_lea_64"
16168   [(set (match_operand:DI 0 "register_operand" "=r")
16169         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16170                    UNSPEC_TLSDESC))]
16171   "TARGET_64BIT && TARGET_GNU2_TLS"
16172   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16173   [(set_attr "type" "lea")
16174    (set_attr "mode" "DI")
16175    (set_attr "length" "7")
16176    (set_attr "length_address" "4")])
16177
16178 (define_insn "*tls_dynamic_call_64"
16179   [(set (match_operand:DI 0 "register_operand" "=a")
16180         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16181                     (match_operand:DI 2 "register_operand" "0")
16182                     (reg:DI SP_REG)]
16183                    UNSPEC_TLSDESC))
16184    (clobber (reg:CC FLAGS_REG))]
16185   "TARGET_64BIT && TARGET_GNU2_TLS"
16186   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16187   [(set_attr "type" "call")
16188    (set_attr "length" "2")
16189    (set_attr "length_address" "0")])
16190
16191 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16192   [(set (match_operand:DI 0 "register_operand" "=&a")
16193         (plus:DI
16194          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16195                      (match_operand:DI 3 "" "")
16196                      (reg:DI SP_REG)]
16197                     UNSPEC_TLSDESC)
16198          (const:DI (unspec:DI
16199                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16200                     UNSPEC_DTPOFF))))
16201    (clobber (reg:CC FLAGS_REG))]
16202   "TARGET_64BIT && TARGET_GNU2_TLS"
16203   "#"
16204   ""
16205   [(set (match_dup 0) (match_dup 4))]
16206 {
16207   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16208   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16209 })
16210
16211 ;;
16212 \f
16213 ;; These patterns match the binary 387 instructions for addM3, subM3,
16214 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16215 ;; SFmode.  The first is the normal insn, the second the same insn but
16216 ;; with one operand a conversion, and the third the same insn but with
16217 ;; the other operand a conversion.  The conversion may be SFmode or
16218 ;; SImode if the target mode DFmode, but only SImode if the target mode
16219 ;; is SFmode.
16220
16221 ;; Gcc is slightly more smart about handling normal two address instructions
16222 ;; so use special patterns for add and mull.
16223
16224 (define_insn "*fop_<mode>_comm_mixed_avx"
16225   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16226         (match_operator:MODEF 3 "binary_fp_operator"
16227           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16228            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16229   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16230    && COMMUTATIVE_ARITH_P (operands[3])
16231    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16232   "* return output_387_binary_op (insn, operands);"
16233   [(set (attr "type")
16234         (if_then_else (eq_attr "alternative" "1")
16235            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16236               (const_string "ssemul")
16237               (const_string "sseadd"))
16238            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16239               (const_string "fmul")
16240               (const_string "fop"))))
16241    (set_attr "prefix" "orig,maybe_vex")
16242    (set_attr "mode" "<MODE>")])
16243
16244 (define_insn "*fop_<mode>_comm_mixed"
16245   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16246         (match_operator:MODEF 3 "binary_fp_operator"
16247           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16248            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16249   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16250    && COMMUTATIVE_ARITH_P (operands[3])
16251    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16252   "* return output_387_binary_op (insn, operands);"
16253   [(set (attr "type")
16254         (if_then_else (eq_attr "alternative" "1")
16255            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16256               (const_string "ssemul")
16257               (const_string "sseadd"))
16258            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16259               (const_string "fmul")
16260               (const_string "fop"))))
16261    (set_attr "mode" "<MODE>")])
16262
16263 (define_insn "*fop_<mode>_comm_avx"
16264   [(set (match_operand:MODEF 0 "register_operand" "=x")
16265         (match_operator:MODEF 3 "binary_fp_operator"
16266           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16267            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16268   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
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 "ssemul")
16275            (const_string "sseadd")))
16276    (set_attr "prefix" "vex")
16277    (set_attr "mode" "<MODE>")])
16278
16279 (define_insn "*fop_<mode>_comm_sse"
16280   [(set (match_operand:MODEF 0 "register_operand" "=x")
16281         (match_operator:MODEF 3 "binary_fp_operator"
16282           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16283            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16284   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16285    && COMMUTATIVE_ARITH_P (operands[3])
16286    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16287   "* return output_387_binary_op (insn, operands);"
16288   [(set (attr "type")
16289         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16290            (const_string "ssemul")
16291            (const_string "sseadd")))
16292    (set_attr "mode" "<MODE>")])
16293
16294 (define_insn "*fop_<mode>_comm_i387"
16295   [(set (match_operand:MODEF 0 "register_operand" "=f")
16296         (match_operator:MODEF 3 "binary_fp_operator"
16297           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16298            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16299   "TARGET_80387
16300    && COMMUTATIVE_ARITH_P (operands[3])
16301    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16302   "* return output_387_binary_op (insn, operands);"
16303   [(set (attr "type")
16304         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16305            (const_string "fmul")
16306            (const_string "fop")))
16307    (set_attr "mode" "<MODE>")])
16308
16309 (define_insn "*fop_<mode>_1_mixed_avx"
16310   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16311         (match_operator:MODEF 3 "binary_fp_operator"
16312           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16313            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16314   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16315    && !COMMUTATIVE_ARITH_P (operands[3])
16316    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16317   "* return output_387_binary_op (insn, operands);"
16318   [(set (attr "type")
16319         (cond [(and (eq_attr "alternative" "2")
16320                     (match_operand:MODEF 3 "mult_operator" ""))
16321                  (const_string "ssemul")
16322                (and (eq_attr "alternative" "2")
16323                     (match_operand:MODEF 3 "div_operator" ""))
16324                  (const_string "ssediv")
16325                (eq_attr "alternative" "2")
16326                  (const_string "sseadd")
16327                (match_operand:MODEF 3 "mult_operator" "")
16328                  (const_string "fmul")
16329                (match_operand:MODEF 3 "div_operator" "")
16330                  (const_string "fdiv")
16331               ]
16332               (const_string "fop")))
16333    (set_attr "prefix" "orig,orig,maybe_vex")
16334    (set_attr "mode" "<MODE>")])
16335
16336 (define_insn "*fop_<mode>_1_mixed"
16337   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16338         (match_operator:MODEF 3 "binary_fp_operator"
16339           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16340            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16341   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16342    && !COMMUTATIVE_ARITH_P (operands[3])
16343    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16344   "* return output_387_binary_op (insn, operands);"
16345   [(set (attr "type")
16346         (cond [(and (eq_attr "alternative" "2")
16347                     (match_operand:MODEF 3 "mult_operator" ""))
16348                  (const_string "ssemul")
16349                (and (eq_attr "alternative" "2")
16350                     (match_operand:MODEF 3 "div_operator" ""))
16351                  (const_string "ssediv")
16352                (eq_attr "alternative" "2")
16353                  (const_string "sseadd")
16354                (match_operand:MODEF 3 "mult_operator" "")
16355                  (const_string "fmul")
16356                (match_operand:MODEF 3 "div_operator" "")
16357                  (const_string "fdiv")
16358               ]
16359               (const_string "fop")))
16360    (set_attr "mode" "<MODE>")])
16361
16362 (define_insn "*rcpsf2_sse"
16363   [(set (match_operand:SF 0 "register_operand" "=x")
16364         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16365                    UNSPEC_RCP))]
16366   "TARGET_SSE_MATH"
16367   "%vrcpss\t{%1, %d0|%d0, %1}"
16368   [(set_attr "type" "sse")
16369    (set_attr "prefix" "maybe_vex")
16370    (set_attr "mode" "SF")])
16371
16372 (define_insn "*fop_<mode>_1_avx"
16373   [(set (match_operand:MODEF 0 "register_operand" "=x")
16374         (match_operator:MODEF 3 "binary_fp_operator"
16375           [(match_operand:MODEF 1 "register_operand" "x")
16376            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16377   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378    && !COMMUTATIVE_ARITH_P (operands[3])"
16379   "* return output_387_binary_op (insn, operands);"
16380   [(set (attr "type")
16381         (cond [(match_operand:MODEF 3 "mult_operator" "")
16382                  (const_string "ssemul")
16383                (match_operand:MODEF 3 "div_operator" "")
16384                  (const_string "ssediv")
16385               ]
16386               (const_string "sseadd")))
16387    (set_attr "prefix" "vex")
16388    (set_attr "mode" "<MODE>")])
16389
16390 (define_insn "*fop_<mode>_1_sse"
16391   [(set (match_operand:MODEF 0 "register_operand" "=x")
16392         (match_operator:MODEF 3 "binary_fp_operator"
16393           [(match_operand:MODEF 1 "register_operand" "0")
16394            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16395   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16396    && !COMMUTATIVE_ARITH_P (operands[3])"
16397   "* return output_387_binary_op (insn, operands);"
16398   [(set (attr "type")
16399         (cond [(match_operand:MODEF 3 "mult_operator" "")
16400                  (const_string "ssemul")
16401                (match_operand:MODEF 3 "div_operator" "")
16402                  (const_string "ssediv")
16403               ]
16404               (const_string "sseadd")))
16405    (set_attr "mode" "<MODE>")])
16406
16407 ;; This pattern is not fully shadowed by the pattern above.
16408 (define_insn "*fop_<mode>_1_i387"
16409   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16410         (match_operator:MODEF 3 "binary_fp_operator"
16411           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16412            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16413   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16414    && !COMMUTATIVE_ARITH_P (operands[3])
16415    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16416   "* return output_387_binary_op (insn, operands);"
16417   [(set (attr "type")
16418         (cond [(match_operand:MODEF 3 "mult_operator" "")
16419                  (const_string "fmul")
16420                (match_operand:MODEF 3 "div_operator" "")
16421                  (const_string "fdiv")
16422               ]
16423               (const_string "fop")))
16424    (set_attr "mode" "<MODE>")])
16425
16426 ;; ??? Add SSE splitters for these!
16427 (define_insn "*fop_<MODEF:mode>_2_i387"
16428   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16429         (match_operator:MODEF 3 "binary_fp_operator"
16430           [(float:MODEF
16431              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16432            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16433   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16434    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16435   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16436   [(set (attr "type")
16437         (cond [(match_operand:MODEF 3 "mult_operator" "")
16438                  (const_string "fmul")
16439                (match_operand:MODEF 3 "div_operator" "")
16440                  (const_string "fdiv")
16441               ]
16442               (const_string "fop")))
16443    (set_attr "fp_int_src" "true")
16444    (set_attr "mode" "<X87MODEI12:MODE>")])
16445
16446 (define_insn "*fop_<MODEF:mode>_3_i387"
16447   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16448         (match_operator:MODEF 3 "binary_fp_operator"
16449           [(match_operand:MODEF 1 "register_operand" "0,0")
16450            (float:MODEF
16451              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16452   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16453    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16454   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16455   [(set (attr "type")
16456         (cond [(match_operand:MODEF 3 "mult_operator" "")
16457                  (const_string "fmul")
16458                (match_operand:MODEF 3 "div_operator" "")
16459                  (const_string "fdiv")
16460               ]
16461               (const_string "fop")))
16462    (set_attr "fp_int_src" "true")
16463    (set_attr "mode" "<MODE>")])
16464
16465 (define_insn "*fop_df_4_i387"
16466   [(set (match_operand:DF 0 "register_operand" "=f,f")
16467         (match_operator:DF 3 "binary_fp_operator"
16468            [(float_extend:DF
16469              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16470             (match_operand:DF 2 "register_operand" "0,f")]))]
16471   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16473   "* return output_387_binary_op (insn, operands);"
16474   [(set (attr "type")
16475         (cond [(match_operand:DF 3 "mult_operator" "")
16476                  (const_string "fmul")
16477                (match_operand:DF 3 "div_operator" "")
16478                  (const_string "fdiv")
16479               ]
16480               (const_string "fop")))
16481    (set_attr "mode" "SF")])
16482
16483 (define_insn "*fop_df_5_i387"
16484   [(set (match_operand:DF 0 "register_operand" "=f,f")
16485         (match_operator:DF 3 "binary_fp_operator"
16486           [(match_operand:DF 1 "register_operand" "0,f")
16487            (float_extend:DF
16488             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16489   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16490   "* return output_387_binary_op (insn, operands);"
16491   [(set (attr "type")
16492         (cond [(match_operand:DF 3 "mult_operator" "")
16493                  (const_string "fmul")
16494                (match_operand:DF 3 "div_operator" "")
16495                  (const_string "fdiv")
16496               ]
16497               (const_string "fop")))
16498    (set_attr "mode" "SF")])
16499
16500 (define_insn "*fop_df_6_i387"
16501   [(set (match_operand:DF 0 "register_operand" "=f,f")
16502         (match_operator:DF 3 "binary_fp_operator"
16503           [(float_extend:DF
16504             (match_operand:SF 1 "register_operand" "0,f"))
16505            (float_extend:DF
16506             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16507   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16508   "* return output_387_binary_op (insn, operands);"
16509   [(set (attr "type")
16510         (cond [(match_operand:DF 3 "mult_operator" "")
16511                  (const_string "fmul")
16512                (match_operand:DF 3 "div_operator" "")
16513                  (const_string "fdiv")
16514               ]
16515               (const_string "fop")))
16516    (set_attr "mode" "SF")])
16517
16518 (define_insn "*fop_xf_comm_i387"
16519   [(set (match_operand:XF 0 "register_operand" "=f")
16520         (match_operator:XF 3 "binary_fp_operator"
16521                         [(match_operand:XF 1 "register_operand" "%0")
16522                          (match_operand:XF 2 "register_operand" "f")]))]
16523   "TARGET_80387
16524    && COMMUTATIVE_ARITH_P (operands[3])"
16525   "* return output_387_binary_op (insn, operands);"
16526   [(set (attr "type")
16527         (if_then_else (match_operand:XF 3 "mult_operator" "")
16528            (const_string "fmul")
16529            (const_string "fop")))
16530    (set_attr "mode" "XF")])
16531
16532 (define_insn "*fop_xf_1_i387"
16533   [(set (match_operand:XF 0 "register_operand" "=f,f")
16534         (match_operator:XF 3 "binary_fp_operator"
16535                         [(match_operand:XF 1 "register_operand" "0,f")
16536                          (match_operand:XF 2 "register_operand" "f,0")]))]
16537   "TARGET_80387
16538    && !COMMUTATIVE_ARITH_P (operands[3])"
16539   "* return output_387_binary_op (insn, operands);"
16540   [(set (attr "type")
16541         (cond [(match_operand:XF 3 "mult_operator" "")
16542                  (const_string "fmul")
16543                (match_operand:XF 3 "div_operator" "")
16544                  (const_string "fdiv")
16545               ]
16546               (const_string "fop")))
16547    (set_attr "mode" "XF")])
16548
16549 (define_insn "*fop_xf_2_i387"
16550   [(set (match_operand:XF 0 "register_operand" "=f,f")
16551         (match_operator:XF 3 "binary_fp_operator"
16552           [(float:XF
16553              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16554            (match_operand:XF 2 "register_operand" "0,0")]))]
16555   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16556   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16557   [(set (attr "type")
16558         (cond [(match_operand:XF 3 "mult_operator" "")
16559                  (const_string "fmul")
16560                (match_operand:XF 3 "div_operator" "")
16561                  (const_string "fdiv")
16562               ]
16563               (const_string "fop")))
16564    (set_attr "fp_int_src" "true")
16565    (set_attr "mode" "<MODE>")])
16566
16567 (define_insn "*fop_xf_3_i387"
16568   [(set (match_operand:XF 0 "register_operand" "=f,f")
16569         (match_operator:XF 3 "binary_fp_operator"
16570           [(match_operand:XF 1 "register_operand" "0,0")
16571            (float:XF
16572              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16573   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16574   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16575   [(set (attr "type")
16576         (cond [(match_operand:XF 3 "mult_operator" "")
16577                  (const_string "fmul")
16578                (match_operand:XF 3 "div_operator" "")
16579                  (const_string "fdiv")
16580               ]
16581               (const_string "fop")))
16582    (set_attr "fp_int_src" "true")
16583    (set_attr "mode" "<MODE>")])
16584
16585 (define_insn "*fop_xf_4_i387"
16586   [(set (match_operand:XF 0 "register_operand" "=f,f")
16587         (match_operator:XF 3 "binary_fp_operator"
16588            [(float_extend:XF
16589               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16590             (match_operand:XF 2 "register_operand" "0,f")]))]
16591   "TARGET_80387"
16592   "* return output_387_binary_op (insn, operands);"
16593   [(set (attr "type")
16594         (cond [(match_operand:XF 3 "mult_operator" "")
16595                  (const_string "fmul")
16596                (match_operand:XF 3 "div_operator" "")
16597                  (const_string "fdiv")
16598               ]
16599               (const_string "fop")))
16600    (set_attr "mode" "<MODE>")])
16601
16602 (define_insn "*fop_xf_5_i387"
16603   [(set (match_operand:XF 0 "register_operand" "=f,f")
16604         (match_operator:XF 3 "binary_fp_operator"
16605           [(match_operand:XF 1 "register_operand" "0,f")
16606            (float_extend:XF
16607              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16608   "TARGET_80387"
16609   "* return output_387_binary_op (insn, operands);"
16610   [(set (attr "type")
16611         (cond [(match_operand:XF 3 "mult_operator" "")
16612                  (const_string "fmul")
16613                (match_operand:XF 3 "div_operator" "")
16614                  (const_string "fdiv")
16615               ]
16616               (const_string "fop")))
16617    (set_attr "mode" "<MODE>")])
16618
16619 (define_insn "*fop_xf_6_i387"
16620   [(set (match_operand:XF 0 "register_operand" "=f,f")
16621         (match_operator:XF 3 "binary_fp_operator"
16622           [(float_extend:XF
16623              (match_operand:MODEF 1 "register_operand" "0,f"))
16624            (float_extend:XF
16625              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16626   "TARGET_80387"
16627   "* return output_387_binary_op (insn, operands);"
16628   [(set (attr "type")
16629         (cond [(match_operand:XF 3 "mult_operator" "")
16630                  (const_string "fmul")
16631                (match_operand:XF 3 "div_operator" "")
16632                  (const_string "fdiv")
16633               ]
16634               (const_string "fop")))
16635    (set_attr "mode" "<MODE>")])
16636
16637 (define_split
16638   [(set (match_operand 0 "register_operand" "")
16639         (match_operator 3 "binary_fp_operator"
16640            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16641             (match_operand 2 "register_operand" "")]))]
16642   "reload_completed
16643    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16644   [(const_int 0)]
16645 {
16646   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16647   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16648   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16649                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16650                                           GET_MODE (operands[3]),
16651                                           operands[4],
16652                                           operands[2])));
16653   ix86_free_from_memory (GET_MODE (operands[1]));
16654   DONE;
16655 })
16656
16657 (define_split
16658   [(set (match_operand 0 "register_operand" "")
16659         (match_operator 3 "binary_fp_operator"
16660            [(match_operand 1 "register_operand" "")
16661             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16662   "reload_completed
16663    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16664   [(const_int 0)]
16665 {
16666   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16667   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16668   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16669                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16670                                           GET_MODE (operands[3]),
16671                                           operands[1],
16672                                           operands[4])));
16673   ix86_free_from_memory (GET_MODE (operands[2]));
16674   DONE;
16675 })
16676 \f
16677 ;; FPU special functions.
16678
16679 ;; This pattern implements a no-op XFmode truncation for
16680 ;; all fancy i386 XFmode math functions.
16681
16682 (define_insn "truncxf<mode>2_i387_noop_unspec"
16683   [(set (match_operand:MODEF 0 "register_operand" "=f")
16684         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16685         UNSPEC_TRUNC_NOOP))]
16686   "TARGET_USE_FANCY_MATH_387"
16687   "* return output_387_reg_move (insn, operands);"
16688   [(set_attr "type" "fmov")
16689    (set_attr "mode" "<MODE>")])
16690
16691 (define_insn "sqrtxf2"
16692   [(set (match_operand:XF 0 "register_operand" "=f")
16693         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16694   "TARGET_USE_FANCY_MATH_387"
16695   "fsqrt"
16696   [(set_attr "type" "fpspc")
16697    (set_attr "mode" "XF")
16698    (set_attr "athlon_decode" "direct")
16699    (set_attr "amdfam10_decode" "direct")])
16700
16701 (define_insn "sqrt_extend<mode>xf2_i387"
16702   [(set (match_operand:XF 0 "register_operand" "=f")
16703         (sqrt:XF
16704           (float_extend:XF
16705             (match_operand:MODEF 1 "register_operand" "0"))))]
16706   "TARGET_USE_FANCY_MATH_387"
16707   "fsqrt"
16708   [(set_attr "type" "fpspc")
16709    (set_attr "mode" "XF")
16710    (set_attr "athlon_decode" "direct")
16711    (set_attr "amdfam10_decode" "direct")])
16712
16713 (define_insn "*rsqrtsf2_sse"
16714   [(set (match_operand:SF 0 "register_operand" "=x")
16715         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16716                    UNSPEC_RSQRT))]
16717   "TARGET_SSE_MATH"
16718   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16719   [(set_attr "type" "sse")
16720    (set_attr "prefix" "maybe_vex")
16721    (set_attr "mode" "SF")])
16722
16723 (define_expand "rsqrtsf2"
16724   [(set (match_operand:SF 0 "register_operand" "")
16725         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16726                    UNSPEC_RSQRT))]
16727   "TARGET_SSE_MATH"
16728 {
16729   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16730   DONE;
16731 })
16732
16733 (define_insn "*sqrt<mode>2_sse"
16734   [(set (match_operand:MODEF 0 "register_operand" "=x")
16735         (sqrt:MODEF
16736           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16737   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16738   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16739   [(set_attr "type" "sse")
16740    (set_attr "prefix" "maybe_vex")
16741    (set_attr "mode" "<MODE>")
16742    (set_attr "athlon_decode" "*")
16743    (set_attr "amdfam10_decode" "*")])
16744
16745 (define_expand "sqrt<mode>2"
16746   [(set (match_operand:MODEF 0 "register_operand" "")
16747         (sqrt:MODEF
16748           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16749   "TARGET_USE_FANCY_MATH_387
16750    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16751 {
16752   if (<MODE>mode == SFmode
16753       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16754       && flag_finite_math_only && !flag_trapping_math
16755       && flag_unsafe_math_optimizations)
16756     {
16757       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16758       DONE;
16759     }
16760
16761   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16762     {
16763       rtx op0 = gen_reg_rtx (XFmode);
16764       rtx op1 = force_reg (<MODE>mode, operands[1]);
16765
16766       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16767       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16768       DONE;
16769    }
16770 })
16771
16772 (define_insn "fpremxf4_i387"
16773   [(set (match_operand:XF 0 "register_operand" "=f")
16774         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16775                     (match_operand:XF 3 "register_operand" "1")]
16776                    UNSPEC_FPREM_F))
16777    (set (match_operand:XF 1 "register_operand" "=u")
16778         (unspec:XF [(match_dup 2) (match_dup 3)]
16779                    UNSPEC_FPREM_U))
16780    (set (reg:CCFP FPSR_REG)
16781         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16782                      UNSPEC_C2_FLAG))]
16783   "TARGET_USE_FANCY_MATH_387"
16784   "fprem"
16785   [(set_attr "type" "fpspc")
16786    (set_attr "mode" "XF")])
16787
16788 (define_expand "fmodxf3"
16789   [(use (match_operand:XF 0 "register_operand" ""))
16790    (use (match_operand:XF 1 "general_operand" ""))
16791    (use (match_operand:XF 2 "general_operand" ""))]
16792   "TARGET_USE_FANCY_MATH_387"
16793 {
16794   rtx label = gen_label_rtx ();
16795
16796   rtx op1 = gen_reg_rtx (XFmode);
16797   rtx op2 = gen_reg_rtx (XFmode);
16798
16799   emit_move_insn (op2, operands[2]);
16800   emit_move_insn (op1, operands[1]);
16801
16802   emit_label (label);
16803   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16804   ix86_emit_fp_unordered_jump (label);
16805   LABEL_NUSES (label) = 1;
16806
16807   emit_move_insn (operands[0], op1);
16808   DONE;
16809 })
16810
16811 (define_expand "fmod<mode>3"
16812   [(use (match_operand:MODEF 0 "register_operand" ""))
16813    (use (match_operand:MODEF 1 "general_operand" ""))
16814    (use (match_operand:MODEF 2 "general_operand" ""))]
16815   "TARGET_USE_FANCY_MATH_387"
16816 {
16817   rtx label = gen_label_rtx ();
16818
16819   rtx op1 = gen_reg_rtx (XFmode);
16820   rtx op2 = gen_reg_rtx (XFmode);
16821
16822   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16823   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16824
16825   emit_label (label);
16826   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16827   ix86_emit_fp_unordered_jump (label);
16828   LABEL_NUSES (label) = 1;
16829
16830   /* Truncate the result properly for strict SSE math.  */
16831   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16832       && !TARGET_MIX_SSE_I387)
16833     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16834   else
16835     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16836
16837   DONE;
16838 })
16839
16840 (define_insn "fprem1xf4_i387"
16841   [(set (match_operand:XF 0 "register_operand" "=f")
16842         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16843                     (match_operand:XF 3 "register_operand" "1")]
16844                    UNSPEC_FPREM1_F))
16845    (set (match_operand:XF 1 "register_operand" "=u")
16846         (unspec:XF [(match_dup 2) (match_dup 3)]
16847                    UNSPEC_FPREM1_U))
16848    (set (reg:CCFP FPSR_REG)
16849         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16850                      UNSPEC_C2_FLAG))]
16851   "TARGET_USE_FANCY_MATH_387"
16852   "fprem1"
16853   [(set_attr "type" "fpspc")
16854    (set_attr "mode" "XF")])
16855
16856 (define_expand "remainderxf3"
16857   [(use (match_operand:XF 0 "register_operand" ""))
16858    (use (match_operand:XF 1 "general_operand" ""))
16859    (use (match_operand:XF 2 "general_operand" ""))]
16860   "TARGET_USE_FANCY_MATH_387"
16861 {
16862   rtx label = gen_label_rtx ();
16863
16864   rtx op1 = gen_reg_rtx (XFmode);
16865   rtx op2 = gen_reg_rtx (XFmode);
16866
16867   emit_move_insn (op2, operands[2]);
16868   emit_move_insn (op1, operands[1]);
16869
16870   emit_label (label);
16871   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16872   ix86_emit_fp_unordered_jump (label);
16873   LABEL_NUSES (label) = 1;
16874
16875   emit_move_insn (operands[0], op1);
16876   DONE;
16877 })
16878
16879 (define_expand "remainder<mode>3"
16880   [(use (match_operand:MODEF 0 "register_operand" ""))
16881    (use (match_operand:MODEF 1 "general_operand" ""))
16882    (use (match_operand:MODEF 2 "general_operand" ""))]
16883   "TARGET_USE_FANCY_MATH_387"
16884 {
16885   rtx label = gen_label_rtx ();
16886
16887   rtx op1 = gen_reg_rtx (XFmode);
16888   rtx op2 = gen_reg_rtx (XFmode);
16889
16890   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16891   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16892
16893   emit_label (label);
16894
16895   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16896   ix86_emit_fp_unordered_jump (label);
16897   LABEL_NUSES (label) = 1;
16898
16899   /* Truncate the result properly for strict SSE math.  */
16900   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16901       && !TARGET_MIX_SSE_I387)
16902     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16903   else
16904     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16905
16906   DONE;
16907 })
16908
16909 (define_insn "*sinxf2_i387"
16910   [(set (match_operand:XF 0 "register_operand" "=f")
16911         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16912   "TARGET_USE_FANCY_MATH_387
16913    && flag_unsafe_math_optimizations"
16914   "fsin"
16915   [(set_attr "type" "fpspc")
16916    (set_attr "mode" "XF")])
16917
16918 (define_insn "*sin_extend<mode>xf2_i387"
16919   [(set (match_operand:XF 0 "register_operand" "=f")
16920         (unspec:XF [(float_extend:XF
16921                       (match_operand:MODEF 1 "register_operand" "0"))]
16922                    UNSPEC_SIN))]
16923   "TARGET_USE_FANCY_MATH_387
16924    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925        || TARGET_MIX_SSE_I387)
16926    && flag_unsafe_math_optimizations"
16927   "fsin"
16928   [(set_attr "type" "fpspc")
16929    (set_attr "mode" "XF")])
16930
16931 (define_insn "*cosxf2_i387"
16932   [(set (match_operand:XF 0 "register_operand" "=f")
16933         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16934   "TARGET_USE_FANCY_MATH_387
16935    && flag_unsafe_math_optimizations"
16936   "fcos"
16937   [(set_attr "type" "fpspc")
16938    (set_attr "mode" "XF")])
16939
16940 (define_insn "*cos_extend<mode>xf2_i387"
16941   [(set (match_operand:XF 0 "register_operand" "=f")
16942         (unspec:XF [(float_extend:XF
16943                       (match_operand:MODEF 1 "register_operand" "0"))]
16944                    UNSPEC_COS))]
16945   "TARGET_USE_FANCY_MATH_387
16946    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16947        || TARGET_MIX_SSE_I387)
16948    && flag_unsafe_math_optimizations"
16949   "fcos"
16950   [(set_attr "type" "fpspc")
16951    (set_attr "mode" "XF")])
16952
16953 ;; When sincos pattern is defined, sin and cos builtin functions will be
16954 ;; expanded to sincos pattern with one of its outputs left unused.
16955 ;; CSE pass will figure out if two sincos patterns can be combined,
16956 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16957 ;; depending on the unused output.
16958
16959 (define_insn "sincosxf3"
16960   [(set (match_operand:XF 0 "register_operand" "=f")
16961         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16962                    UNSPEC_SINCOS_COS))
16963    (set (match_operand:XF 1 "register_operand" "=u")
16964         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16965   "TARGET_USE_FANCY_MATH_387
16966    && flag_unsafe_math_optimizations"
16967   "fsincos"
16968   [(set_attr "type" "fpspc")
16969    (set_attr "mode" "XF")])
16970
16971 (define_split
16972   [(set (match_operand:XF 0 "register_operand" "")
16973         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16974                    UNSPEC_SINCOS_COS))
16975    (set (match_operand:XF 1 "register_operand" "")
16976         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16977   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16978    && !(reload_completed || reload_in_progress)"
16979   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16980   "")
16981
16982 (define_split
16983   [(set (match_operand:XF 0 "register_operand" "")
16984         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16985                    UNSPEC_SINCOS_COS))
16986    (set (match_operand:XF 1 "register_operand" "")
16987         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16988   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16989    && !(reload_completed || reload_in_progress)"
16990   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16991   "")
16992
16993 (define_insn "sincos_extend<mode>xf3_i387"
16994   [(set (match_operand:XF 0 "register_operand" "=f")
16995         (unspec:XF [(float_extend:XF
16996                       (match_operand:MODEF 2 "register_operand" "0"))]
16997                    UNSPEC_SINCOS_COS))
16998    (set (match_operand:XF 1 "register_operand" "=u")
16999         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17000   "TARGET_USE_FANCY_MATH_387
17001    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17002        || TARGET_MIX_SSE_I387)
17003    && flag_unsafe_math_optimizations"
17004   "fsincos"
17005   [(set_attr "type" "fpspc")
17006    (set_attr "mode" "XF")])
17007
17008 (define_split
17009   [(set (match_operand:XF 0 "register_operand" "")
17010         (unspec:XF [(float_extend:XF
17011                       (match_operand:MODEF 2 "register_operand" ""))]
17012                    UNSPEC_SINCOS_COS))
17013    (set (match_operand:XF 1 "register_operand" "")
17014         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17015   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17016    && !(reload_completed || reload_in_progress)"
17017   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17018   "")
17019
17020 (define_split
17021   [(set (match_operand:XF 0 "register_operand" "")
17022         (unspec:XF [(float_extend:XF
17023                       (match_operand:MODEF 2 "register_operand" ""))]
17024                    UNSPEC_SINCOS_COS))
17025    (set (match_operand:XF 1 "register_operand" "")
17026         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17027   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17028    && !(reload_completed || reload_in_progress)"
17029   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17030   "")
17031
17032 (define_expand "sincos<mode>3"
17033   [(use (match_operand:MODEF 0 "register_operand" ""))
17034    (use (match_operand:MODEF 1 "register_operand" ""))
17035    (use (match_operand:MODEF 2 "register_operand" ""))]
17036   "TARGET_USE_FANCY_MATH_387
17037    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17038        || TARGET_MIX_SSE_I387)
17039    && flag_unsafe_math_optimizations"
17040 {
17041   rtx op0 = gen_reg_rtx (XFmode);
17042   rtx op1 = gen_reg_rtx (XFmode);
17043
17044   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17045   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17046   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17047   DONE;
17048 })
17049
17050 (define_insn "fptanxf4_i387"
17051   [(set (match_operand:XF 0 "register_operand" "=f")
17052         (match_operand:XF 3 "const_double_operand" "F"))
17053    (set (match_operand:XF 1 "register_operand" "=u")
17054         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17055                    UNSPEC_TAN))]
17056   "TARGET_USE_FANCY_MATH_387
17057    && flag_unsafe_math_optimizations
17058    && standard_80387_constant_p (operands[3]) == 2"
17059   "fptan"
17060   [(set_attr "type" "fpspc")
17061    (set_attr "mode" "XF")])
17062
17063 (define_insn "fptan_extend<mode>xf4_i387"
17064   [(set (match_operand:MODEF 0 "register_operand" "=f")
17065         (match_operand:MODEF 3 "const_double_operand" "F"))
17066    (set (match_operand:XF 1 "register_operand" "=u")
17067         (unspec:XF [(float_extend:XF
17068                       (match_operand:MODEF 2 "register_operand" "0"))]
17069                    UNSPEC_TAN))]
17070   "TARGET_USE_FANCY_MATH_387
17071    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17072        || TARGET_MIX_SSE_I387)
17073    && flag_unsafe_math_optimizations
17074    && standard_80387_constant_p (operands[3]) == 2"
17075   "fptan"
17076   [(set_attr "type" "fpspc")
17077    (set_attr "mode" "XF")])
17078
17079 (define_expand "tanxf2"
17080   [(use (match_operand:XF 0 "register_operand" ""))
17081    (use (match_operand:XF 1 "register_operand" ""))]
17082   "TARGET_USE_FANCY_MATH_387
17083    && flag_unsafe_math_optimizations"
17084 {
17085   rtx one = gen_reg_rtx (XFmode);
17086   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17087
17088   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17089   DONE;
17090 })
17091
17092 (define_expand "tan<mode>2"
17093   [(use (match_operand:MODEF 0 "register_operand" ""))
17094    (use (match_operand:MODEF 1 "register_operand" ""))]
17095   "TARGET_USE_FANCY_MATH_387
17096    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17097        || TARGET_MIX_SSE_I387)
17098    && flag_unsafe_math_optimizations"
17099 {
17100   rtx op0 = gen_reg_rtx (XFmode);
17101
17102   rtx one = gen_reg_rtx (<MODE>mode);
17103   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17104
17105   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17106                                              operands[1], op2));
17107   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17108   DONE;
17109 })
17110
17111 (define_insn "*fpatanxf3_i387"
17112   [(set (match_operand:XF 0 "register_operand" "=f")
17113         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17114                     (match_operand:XF 2 "register_operand" "u")]
17115                    UNSPEC_FPATAN))
17116    (clobber (match_scratch:XF 3 "=2"))]
17117   "TARGET_USE_FANCY_MATH_387
17118    && flag_unsafe_math_optimizations"
17119   "fpatan"
17120   [(set_attr "type" "fpspc")
17121    (set_attr "mode" "XF")])
17122
17123 (define_insn "fpatan_extend<mode>xf3_i387"
17124   [(set (match_operand:XF 0 "register_operand" "=f")
17125         (unspec:XF [(float_extend:XF
17126                       (match_operand:MODEF 1 "register_operand" "0"))
17127                     (float_extend:XF
17128                       (match_operand:MODEF 2 "register_operand" "u"))]
17129                    UNSPEC_FPATAN))
17130    (clobber (match_scratch:XF 3 "=2"))]
17131   "TARGET_USE_FANCY_MATH_387
17132    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17133        || TARGET_MIX_SSE_I387)
17134    && flag_unsafe_math_optimizations"
17135   "fpatan"
17136   [(set_attr "type" "fpspc")
17137    (set_attr "mode" "XF")])
17138
17139 (define_expand "atan2xf3"
17140   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17141                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17142                                (match_operand:XF 1 "register_operand" "")]
17143                               UNSPEC_FPATAN))
17144               (clobber (match_scratch:XF 3 ""))])]
17145   "TARGET_USE_FANCY_MATH_387
17146    && flag_unsafe_math_optimizations"
17147   "")
17148
17149 (define_expand "atan2<mode>3"
17150   [(use (match_operand:MODEF 0 "register_operand" ""))
17151    (use (match_operand:MODEF 1 "register_operand" ""))
17152    (use (match_operand:MODEF 2 "register_operand" ""))]
17153   "TARGET_USE_FANCY_MATH_387
17154    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17155        || TARGET_MIX_SSE_I387)
17156    && flag_unsafe_math_optimizations"
17157 {
17158   rtx op0 = gen_reg_rtx (XFmode);
17159
17160   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17161   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17162   DONE;
17163 })
17164
17165 (define_expand "atanxf2"
17166   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17167                    (unspec:XF [(match_dup 2)
17168                                (match_operand:XF 1 "register_operand" "")]
17169                               UNSPEC_FPATAN))
17170               (clobber (match_scratch:XF 3 ""))])]
17171   "TARGET_USE_FANCY_MATH_387
17172    && flag_unsafe_math_optimizations"
17173 {
17174   operands[2] = gen_reg_rtx (XFmode);
17175   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17176 })
17177
17178 (define_expand "atan<mode>2"
17179   [(use (match_operand:MODEF 0 "register_operand" ""))
17180    (use (match_operand:MODEF 1 "register_operand" ""))]
17181   "TARGET_USE_FANCY_MATH_387
17182    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17183        || TARGET_MIX_SSE_I387)
17184    && flag_unsafe_math_optimizations"
17185 {
17186   rtx op0 = gen_reg_rtx (XFmode);
17187
17188   rtx op2 = gen_reg_rtx (<MODE>mode);
17189   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17190
17191   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17192   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17193   DONE;
17194 })
17195
17196 (define_expand "asinxf2"
17197   [(set (match_dup 2)
17198         (mult:XF (match_operand:XF 1 "register_operand" "")
17199                  (match_dup 1)))
17200    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17201    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17202    (parallel [(set (match_operand:XF 0 "register_operand" "")
17203                    (unspec:XF [(match_dup 5) (match_dup 1)]
17204                               UNSPEC_FPATAN))
17205               (clobber (match_scratch:XF 6 ""))])]
17206   "TARGET_USE_FANCY_MATH_387
17207    && flag_unsafe_math_optimizations"
17208 {
17209   int i;
17210
17211   if (optimize_insn_for_size_p ())
17212     FAIL;
17213
17214   for (i = 2; i < 6; i++)
17215     operands[i] = gen_reg_rtx (XFmode);
17216
17217   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17218 })
17219
17220 (define_expand "asin<mode>2"
17221   [(use (match_operand:MODEF 0 "register_operand" ""))
17222    (use (match_operand:MODEF 1 "general_operand" ""))]
17223  "TARGET_USE_FANCY_MATH_387
17224    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17225        || TARGET_MIX_SSE_I387)
17226    && flag_unsafe_math_optimizations"
17227 {
17228   rtx op0 = gen_reg_rtx (XFmode);
17229   rtx op1 = gen_reg_rtx (XFmode);
17230
17231   if (optimize_insn_for_size_p ())
17232     FAIL;
17233
17234   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17235   emit_insn (gen_asinxf2 (op0, op1));
17236   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17237   DONE;
17238 })
17239
17240 (define_expand "acosxf2"
17241   [(set (match_dup 2)
17242         (mult:XF (match_operand:XF 1 "register_operand" "")
17243                  (match_dup 1)))
17244    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17245    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17246    (parallel [(set (match_operand:XF 0 "register_operand" "")
17247                    (unspec:XF [(match_dup 1) (match_dup 5)]
17248                               UNSPEC_FPATAN))
17249               (clobber (match_scratch:XF 6 ""))])]
17250   "TARGET_USE_FANCY_MATH_387
17251    && flag_unsafe_math_optimizations"
17252 {
17253   int i;
17254
17255   if (optimize_insn_for_size_p ())
17256     FAIL;
17257
17258   for (i = 2; i < 6; i++)
17259     operands[i] = gen_reg_rtx (XFmode);
17260
17261   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17262 })
17263
17264 (define_expand "acos<mode>2"
17265   [(use (match_operand:MODEF 0 "register_operand" ""))
17266    (use (match_operand:MODEF 1 "general_operand" ""))]
17267  "TARGET_USE_FANCY_MATH_387
17268    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17269        || TARGET_MIX_SSE_I387)
17270    && flag_unsafe_math_optimizations"
17271 {
17272   rtx op0 = gen_reg_rtx (XFmode);
17273   rtx op1 = gen_reg_rtx (XFmode);
17274
17275   if (optimize_insn_for_size_p ())
17276     FAIL;
17277
17278   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17279   emit_insn (gen_acosxf2 (op0, op1));
17280   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17281   DONE;
17282 })
17283
17284 (define_insn "fyl2xxf3_i387"
17285   [(set (match_operand:XF 0 "register_operand" "=f")
17286         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17287                     (match_operand:XF 2 "register_operand" "u")]
17288                    UNSPEC_FYL2X))
17289    (clobber (match_scratch:XF 3 "=2"))]
17290   "TARGET_USE_FANCY_MATH_387
17291    && flag_unsafe_math_optimizations"
17292   "fyl2x"
17293   [(set_attr "type" "fpspc")
17294    (set_attr "mode" "XF")])
17295
17296 (define_insn "fyl2x_extend<mode>xf3_i387"
17297   [(set (match_operand:XF 0 "register_operand" "=f")
17298         (unspec:XF [(float_extend:XF
17299                       (match_operand:MODEF 1 "register_operand" "0"))
17300                     (match_operand:XF 2 "register_operand" "u")]
17301                    UNSPEC_FYL2X))
17302    (clobber (match_scratch:XF 3 "=2"))]
17303   "TARGET_USE_FANCY_MATH_387
17304    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17305        || TARGET_MIX_SSE_I387)
17306    && flag_unsafe_math_optimizations"
17307   "fyl2x"
17308   [(set_attr "type" "fpspc")
17309    (set_attr "mode" "XF")])
17310
17311 (define_expand "logxf2"
17312   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17313                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17314                                (match_dup 2)] UNSPEC_FYL2X))
17315               (clobber (match_scratch:XF 3 ""))])]
17316   "TARGET_USE_FANCY_MATH_387
17317    && flag_unsafe_math_optimizations"
17318 {
17319   operands[2] = gen_reg_rtx (XFmode);
17320   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17321 })
17322
17323 (define_expand "log<mode>2"
17324   [(use (match_operand:MODEF 0 "register_operand" ""))
17325    (use (match_operand:MODEF 1 "register_operand" ""))]
17326   "TARGET_USE_FANCY_MATH_387
17327    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17328        || TARGET_MIX_SSE_I387)
17329    && flag_unsafe_math_optimizations"
17330 {
17331   rtx op0 = gen_reg_rtx (XFmode);
17332
17333   rtx op2 = gen_reg_rtx (XFmode);
17334   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17335
17336   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17337   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17338   DONE;
17339 })
17340
17341 (define_expand "log10xf2"
17342   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17343                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17344                                (match_dup 2)] UNSPEC_FYL2X))
17345               (clobber (match_scratch:XF 3 ""))])]
17346   "TARGET_USE_FANCY_MATH_387
17347    && flag_unsafe_math_optimizations"
17348 {
17349   operands[2] = gen_reg_rtx (XFmode);
17350   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17351 })
17352
17353 (define_expand "log10<mode>2"
17354   [(use (match_operand:MODEF 0 "register_operand" ""))
17355    (use (match_operand:MODEF 1 "register_operand" ""))]
17356   "TARGET_USE_FANCY_MATH_387
17357    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17358        || TARGET_MIX_SSE_I387)
17359    && flag_unsafe_math_optimizations"
17360 {
17361   rtx op0 = gen_reg_rtx (XFmode);
17362
17363   rtx op2 = gen_reg_rtx (XFmode);
17364   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17365
17366   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17367   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17368   DONE;
17369 })
17370
17371 (define_expand "log2xf2"
17372   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17373                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17374                                (match_dup 2)] UNSPEC_FYL2X))
17375               (clobber (match_scratch:XF 3 ""))])]
17376   "TARGET_USE_FANCY_MATH_387
17377    && flag_unsafe_math_optimizations"
17378 {
17379   operands[2] = gen_reg_rtx (XFmode);
17380   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17381 })
17382
17383 (define_expand "log2<mode>2"
17384   [(use (match_operand:MODEF 0 "register_operand" ""))
17385    (use (match_operand:MODEF 1 "register_operand" ""))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17388        || TARGET_MIX_SSE_I387)
17389    && flag_unsafe_math_optimizations"
17390 {
17391   rtx op0 = gen_reg_rtx (XFmode);
17392
17393   rtx op2 = gen_reg_rtx (XFmode);
17394   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17395
17396   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17397   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17398   DONE;
17399 })
17400
17401 (define_insn "fyl2xp1xf3_i387"
17402   [(set (match_operand:XF 0 "register_operand" "=f")
17403         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17404                     (match_operand:XF 2 "register_operand" "u")]
17405                    UNSPEC_FYL2XP1))
17406    (clobber (match_scratch:XF 3 "=2"))]
17407   "TARGET_USE_FANCY_MATH_387
17408    && flag_unsafe_math_optimizations"
17409   "fyl2xp1"
17410   [(set_attr "type" "fpspc")
17411    (set_attr "mode" "XF")])
17412
17413 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17414   [(set (match_operand:XF 0 "register_operand" "=f")
17415         (unspec:XF [(float_extend:XF
17416                       (match_operand:MODEF 1 "register_operand" "0"))
17417                     (match_operand:XF 2 "register_operand" "u")]
17418                    UNSPEC_FYL2XP1))
17419    (clobber (match_scratch:XF 3 "=2"))]
17420   "TARGET_USE_FANCY_MATH_387
17421    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17422        || TARGET_MIX_SSE_I387)
17423    && flag_unsafe_math_optimizations"
17424   "fyl2xp1"
17425   [(set_attr "type" "fpspc")
17426    (set_attr "mode" "XF")])
17427
17428 (define_expand "log1pxf2"
17429   [(use (match_operand:XF 0 "register_operand" ""))
17430    (use (match_operand:XF 1 "register_operand" ""))]
17431   "TARGET_USE_FANCY_MATH_387
17432    && flag_unsafe_math_optimizations"
17433 {
17434   if (optimize_insn_for_size_p ())
17435     FAIL;
17436
17437   ix86_emit_i387_log1p (operands[0], operands[1]);
17438   DONE;
17439 })
17440
17441 (define_expand "log1p<mode>2"
17442   [(use (match_operand:MODEF 0 "register_operand" ""))
17443    (use (match_operand:MODEF 1 "register_operand" ""))]
17444   "TARGET_USE_FANCY_MATH_387
17445    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17446        || TARGET_MIX_SSE_I387)
17447    && flag_unsafe_math_optimizations"
17448 {
17449   rtx op0;
17450
17451   if (optimize_insn_for_size_p ())
17452     FAIL;
17453
17454   op0 = gen_reg_rtx (XFmode);
17455
17456   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17457
17458   ix86_emit_i387_log1p (op0, operands[1]);
17459   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17460   DONE;
17461 })
17462
17463 (define_insn "fxtractxf3_i387"
17464   [(set (match_operand:XF 0 "register_operand" "=f")
17465         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17466                    UNSPEC_XTRACT_FRACT))
17467    (set (match_operand:XF 1 "register_operand" "=u")
17468         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17469   "TARGET_USE_FANCY_MATH_387
17470    && flag_unsafe_math_optimizations"
17471   "fxtract"
17472   [(set_attr "type" "fpspc")
17473    (set_attr "mode" "XF")])
17474
17475 (define_insn "fxtract_extend<mode>xf3_i387"
17476   [(set (match_operand:XF 0 "register_operand" "=f")
17477         (unspec:XF [(float_extend:XF
17478                       (match_operand:MODEF 2 "register_operand" "0"))]
17479                    UNSPEC_XTRACT_FRACT))
17480    (set (match_operand:XF 1 "register_operand" "=u")
17481         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17482   "TARGET_USE_FANCY_MATH_387
17483    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17484        || TARGET_MIX_SSE_I387)
17485    && flag_unsafe_math_optimizations"
17486   "fxtract"
17487   [(set_attr "type" "fpspc")
17488    (set_attr "mode" "XF")])
17489
17490 (define_expand "logbxf2"
17491   [(parallel [(set (match_dup 2)
17492                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17493                               UNSPEC_XTRACT_FRACT))
17494               (set (match_operand:XF 0 "register_operand" "")
17495                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17496   "TARGET_USE_FANCY_MATH_387
17497    && flag_unsafe_math_optimizations"
17498 {
17499   operands[2] = gen_reg_rtx (XFmode);
17500 })
17501
17502 (define_expand "logb<mode>2"
17503   [(use (match_operand:MODEF 0 "register_operand" ""))
17504    (use (match_operand:MODEF 1 "register_operand" ""))]
17505   "TARGET_USE_FANCY_MATH_387
17506    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17507        || TARGET_MIX_SSE_I387)
17508    && flag_unsafe_math_optimizations"
17509 {
17510   rtx op0 = gen_reg_rtx (XFmode);
17511   rtx op1 = gen_reg_rtx (XFmode);
17512
17513   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17514   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17515   DONE;
17516 })
17517
17518 (define_expand "ilogbxf2"
17519   [(use (match_operand:SI 0 "register_operand" ""))
17520    (use (match_operand:XF 1 "register_operand" ""))]
17521   "TARGET_USE_FANCY_MATH_387
17522    && flag_unsafe_math_optimizations"
17523 {
17524   rtx op0, op1;
17525
17526   if (optimize_insn_for_size_p ())
17527     FAIL;
17528
17529   op0 = gen_reg_rtx (XFmode);
17530   op1 = gen_reg_rtx (XFmode);
17531
17532   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17533   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17534   DONE;
17535 })
17536
17537 (define_expand "ilogb<mode>2"
17538   [(use (match_operand:SI 0 "register_operand" ""))
17539    (use (match_operand:MODEF 1 "register_operand" ""))]
17540   "TARGET_USE_FANCY_MATH_387
17541    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17542        || TARGET_MIX_SSE_I387)
17543    && flag_unsafe_math_optimizations"
17544 {
17545   rtx op0, op1;
17546
17547   if (optimize_insn_for_size_p ())
17548     FAIL;
17549
17550   op0 = gen_reg_rtx (XFmode);
17551   op1 = gen_reg_rtx (XFmode);
17552
17553   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17554   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17555   DONE;
17556 })
17557
17558 (define_insn "*f2xm1xf2_i387"
17559   [(set (match_operand:XF 0 "register_operand" "=f")
17560         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17561                    UNSPEC_F2XM1))]
17562   "TARGET_USE_FANCY_MATH_387
17563    && flag_unsafe_math_optimizations"
17564   "f2xm1"
17565   [(set_attr "type" "fpspc")
17566    (set_attr "mode" "XF")])
17567
17568 (define_insn "*fscalexf4_i387"
17569   [(set (match_operand:XF 0 "register_operand" "=f")
17570         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17571                     (match_operand:XF 3 "register_operand" "1")]
17572                    UNSPEC_FSCALE_FRACT))
17573    (set (match_operand:XF 1 "register_operand" "=u")
17574         (unspec:XF [(match_dup 2) (match_dup 3)]
17575                    UNSPEC_FSCALE_EXP))]
17576   "TARGET_USE_FANCY_MATH_387
17577    && flag_unsafe_math_optimizations"
17578   "fscale"
17579   [(set_attr "type" "fpspc")
17580    (set_attr "mode" "XF")])
17581
17582 (define_expand "expNcorexf3"
17583   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17584                                (match_operand:XF 2 "register_operand" "")))
17585    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17586    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17587    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17588    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17589    (parallel [(set (match_operand:XF 0 "register_operand" "")
17590                    (unspec:XF [(match_dup 8) (match_dup 4)]
17591                               UNSPEC_FSCALE_FRACT))
17592               (set (match_dup 9)
17593                    (unspec:XF [(match_dup 8) (match_dup 4)]
17594                               UNSPEC_FSCALE_EXP))])]
17595   "TARGET_USE_FANCY_MATH_387
17596    && flag_unsafe_math_optimizations"
17597 {
17598   int i;
17599
17600   if (optimize_insn_for_size_p ())
17601     FAIL;
17602
17603   for (i = 3; i < 10; i++)
17604     operands[i] = gen_reg_rtx (XFmode);
17605
17606   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17607 })
17608
17609 (define_expand "expxf2"
17610   [(use (match_operand:XF 0 "register_operand" ""))
17611    (use (match_operand:XF 1 "register_operand" ""))]
17612   "TARGET_USE_FANCY_MATH_387
17613    && flag_unsafe_math_optimizations"
17614 {
17615   rtx op2;
17616
17617   if (optimize_insn_for_size_p ())
17618     FAIL;
17619
17620   op2 = gen_reg_rtx (XFmode);
17621   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17622
17623   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17624   DONE;
17625 })
17626
17627 (define_expand "exp<mode>2"
17628   [(use (match_operand:MODEF 0 "register_operand" ""))
17629    (use (match_operand:MODEF 1 "general_operand" ""))]
17630  "TARGET_USE_FANCY_MATH_387
17631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17632        || TARGET_MIX_SSE_I387)
17633    && flag_unsafe_math_optimizations"
17634 {
17635   rtx op0, op1;
17636
17637   if (optimize_insn_for_size_p ())
17638     FAIL;
17639
17640   op0 = gen_reg_rtx (XFmode);
17641   op1 = gen_reg_rtx (XFmode);
17642
17643   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17644   emit_insn (gen_expxf2 (op0, op1));
17645   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17646   DONE;
17647 })
17648
17649 (define_expand "exp10xf2"
17650   [(use (match_operand:XF 0 "register_operand" ""))
17651    (use (match_operand:XF 1 "register_operand" ""))]
17652   "TARGET_USE_FANCY_MATH_387
17653    && flag_unsafe_math_optimizations"
17654 {
17655   rtx op2;
17656
17657   if (optimize_insn_for_size_p ())
17658     FAIL;
17659
17660   op2 = gen_reg_rtx (XFmode);
17661   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17662
17663   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17664   DONE;
17665 })
17666
17667 (define_expand "exp10<mode>2"
17668   [(use (match_operand:MODEF 0 "register_operand" ""))
17669    (use (match_operand:MODEF 1 "general_operand" ""))]
17670  "TARGET_USE_FANCY_MATH_387
17671    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17672        || TARGET_MIX_SSE_I387)
17673    && flag_unsafe_math_optimizations"
17674 {
17675   rtx op0, op1;
17676
17677   if (optimize_insn_for_size_p ())
17678     FAIL;
17679
17680   op0 = gen_reg_rtx (XFmode);
17681   op1 = gen_reg_rtx (XFmode);
17682
17683   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17684   emit_insn (gen_exp10xf2 (op0, op1));
17685   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17686   DONE;
17687 })
17688
17689 (define_expand "exp2xf2"
17690   [(use (match_operand:XF 0 "register_operand" ""))
17691    (use (match_operand:XF 1 "register_operand" ""))]
17692   "TARGET_USE_FANCY_MATH_387
17693    && flag_unsafe_math_optimizations"
17694 {
17695   rtx op2;
17696
17697   if (optimize_insn_for_size_p ())
17698     FAIL;
17699
17700   op2 = gen_reg_rtx (XFmode);
17701   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17702
17703   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17704   DONE;
17705 })
17706
17707 (define_expand "exp2<mode>2"
17708   [(use (match_operand:MODEF 0 "register_operand" ""))
17709    (use (match_operand:MODEF 1 "general_operand" ""))]
17710  "TARGET_USE_FANCY_MATH_387
17711    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17712        || TARGET_MIX_SSE_I387)
17713    && flag_unsafe_math_optimizations"
17714 {
17715   rtx op0, op1;
17716
17717   if (optimize_insn_for_size_p ())
17718     FAIL;
17719
17720   op0 = gen_reg_rtx (XFmode);
17721   op1 = gen_reg_rtx (XFmode);
17722
17723   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17724   emit_insn (gen_exp2xf2 (op0, op1));
17725   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17726   DONE;
17727 })
17728
17729 (define_expand "expm1xf2"
17730   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17731                                (match_dup 2)))
17732    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17733    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17734    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17735    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17736    (parallel [(set (match_dup 7)
17737                    (unspec:XF [(match_dup 6) (match_dup 4)]
17738                               UNSPEC_FSCALE_FRACT))
17739               (set (match_dup 8)
17740                    (unspec:XF [(match_dup 6) (match_dup 4)]
17741                               UNSPEC_FSCALE_EXP))])
17742    (parallel [(set (match_dup 10)
17743                    (unspec:XF [(match_dup 9) (match_dup 8)]
17744                               UNSPEC_FSCALE_FRACT))
17745               (set (match_dup 11)
17746                    (unspec:XF [(match_dup 9) (match_dup 8)]
17747                               UNSPEC_FSCALE_EXP))])
17748    (set (match_dup 12) (minus:XF (match_dup 10)
17749                                  (float_extend:XF (match_dup 13))))
17750    (set (match_operand:XF 0 "register_operand" "")
17751         (plus:XF (match_dup 12) (match_dup 7)))]
17752   "TARGET_USE_FANCY_MATH_387
17753    && flag_unsafe_math_optimizations"
17754 {
17755   int i;
17756
17757   if (optimize_insn_for_size_p ())
17758     FAIL;
17759
17760   for (i = 2; i < 13; i++)
17761     operands[i] = gen_reg_rtx (XFmode);
17762
17763   operands[13]
17764     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17765
17766   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17767 })
17768
17769 (define_expand "expm1<mode>2"
17770   [(use (match_operand:MODEF 0 "register_operand" ""))
17771    (use (match_operand:MODEF 1 "general_operand" ""))]
17772  "TARGET_USE_FANCY_MATH_387
17773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17774        || TARGET_MIX_SSE_I387)
17775    && flag_unsafe_math_optimizations"
17776 {
17777   rtx op0, op1;
17778
17779   if (optimize_insn_for_size_p ())
17780     FAIL;
17781
17782   op0 = gen_reg_rtx (XFmode);
17783   op1 = gen_reg_rtx (XFmode);
17784
17785   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17786   emit_insn (gen_expm1xf2 (op0, op1));
17787   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17788   DONE;
17789 })
17790
17791 (define_expand "ldexpxf3"
17792   [(set (match_dup 3)
17793         (float:XF (match_operand:SI 2 "register_operand" "")))
17794    (parallel [(set (match_operand:XF 0 " register_operand" "")
17795                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17796                                (match_dup 3)]
17797                               UNSPEC_FSCALE_FRACT))
17798               (set (match_dup 4)
17799                    (unspec:XF [(match_dup 1) (match_dup 3)]
17800                               UNSPEC_FSCALE_EXP))])]
17801   "TARGET_USE_FANCY_MATH_387
17802    && flag_unsafe_math_optimizations"
17803 {
17804   if (optimize_insn_for_size_p ())
17805     FAIL;
17806
17807   operands[3] = gen_reg_rtx (XFmode);
17808   operands[4] = gen_reg_rtx (XFmode);
17809 })
17810
17811 (define_expand "ldexp<mode>3"
17812   [(use (match_operand:MODEF 0 "register_operand" ""))
17813    (use (match_operand:MODEF 1 "general_operand" ""))
17814    (use (match_operand:SI 2 "register_operand" ""))]
17815  "TARGET_USE_FANCY_MATH_387
17816    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17817        || TARGET_MIX_SSE_I387)
17818    && flag_unsafe_math_optimizations"
17819 {
17820   rtx op0, op1;
17821
17822   if (optimize_insn_for_size_p ())
17823     FAIL;
17824
17825   op0 = gen_reg_rtx (XFmode);
17826   op1 = gen_reg_rtx (XFmode);
17827
17828   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17829   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17830   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17831   DONE;
17832 })
17833
17834 (define_expand "scalbxf3"
17835   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17836                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17837                                (match_operand:XF 2 "register_operand" "")]
17838                               UNSPEC_FSCALE_FRACT))
17839               (set (match_dup 3)
17840                    (unspec:XF [(match_dup 1) (match_dup 2)]
17841                               UNSPEC_FSCALE_EXP))])]
17842   "TARGET_USE_FANCY_MATH_387
17843    && flag_unsafe_math_optimizations"
17844 {
17845   if (optimize_insn_for_size_p ())
17846     FAIL;
17847
17848   operands[3] = gen_reg_rtx (XFmode);
17849 })
17850
17851 (define_expand "scalb<mode>3"
17852   [(use (match_operand:MODEF 0 "register_operand" ""))
17853    (use (match_operand:MODEF 1 "general_operand" ""))
17854    (use (match_operand:MODEF 2 "register_operand" ""))]
17855  "TARGET_USE_FANCY_MATH_387
17856    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17857        || TARGET_MIX_SSE_I387)
17858    && flag_unsafe_math_optimizations"
17859 {
17860   rtx op0, op1, op2;
17861
17862   if (optimize_insn_for_size_p ())
17863     FAIL;
17864
17865   op0 = gen_reg_rtx (XFmode);
17866   op1 = gen_reg_rtx (XFmode);
17867   op2 = gen_reg_rtx (XFmode);
17868
17869   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17870   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17871   emit_insn (gen_scalbxf3 (op0, op1, op2));
17872   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17873   DONE;
17874 })
17875 \f
17876
17877 (define_insn "sse4_1_round<mode>2"
17878   [(set (match_operand:MODEF 0 "register_operand" "=x")
17879         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17880                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17881                       UNSPEC_ROUND))]
17882   "TARGET_ROUND"
17883   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17884   [(set_attr "type" "ssecvt")
17885    (set_attr "prefix_extra" "1")
17886    (set_attr "prefix" "maybe_vex")
17887    (set_attr "mode" "<MODE>")])
17888
17889 (define_insn "rintxf2"
17890   [(set (match_operand:XF 0 "register_operand" "=f")
17891         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17892                    UNSPEC_FRNDINT))]
17893   "TARGET_USE_FANCY_MATH_387
17894    && flag_unsafe_math_optimizations"
17895   "frndint"
17896   [(set_attr "type" "fpspc")
17897    (set_attr "mode" "XF")])
17898
17899 (define_expand "rint<mode>2"
17900   [(use (match_operand:MODEF 0 "register_operand" ""))
17901    (use (match_operand:MODEF 1 "register_operand" ""))]
17902   "(TARGET_USE_FANCY_MATH_387
17903     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17904         || TARGET_MIX_SSE_I387)
17905     && flag_unsafe_math_optimizations)
17906    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17907        && !flag_trapping_math)"
17908 {
17909   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17910       && !flag_trapping_math)
17911     {
17912       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17913         FAIL;
17914       if (TARGET_ROUND)
17915         emit_insn (gen_sse4_1_round<mode>2
17916                    (operands[0], operands[1], GEN_INT (0x04)));
17917       else
17918         ix86_expand_rint (operand0, operand1);
17919     }
17920   else
17921     {
17922       rtx op0 = gen_reg_rtx (XFmode);
17923       rtx op1 = gen_reg_rtx (XFmode);
17924
17925       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17926       emit_insn (gen_rintxf2 (op0, op1));
17927
17928       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17929     }
17930   DONE;
17931 })
17932
17933 (define_expand "round<mode>2"
17934   [(match_operand:MODEF 0 "register_operand" "")
17935    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17936   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17937    && !flag_trapping_math && !flag_rounding_math"
17938 {
17939   if (optimize_insn_for_size_p ())
17940     FAIL;
17941   if (TARGET_64BIT || (<MODE>mode != DFmode))
17942     ix86_expand_round (operand0, operand1);
17943   else
17944     ix86_expand_rounddf_32 (operand0, operand1);
17945   DONE;
17946 })
17947
17948 (define_insn_and_split "*fistdi2_1"
17949   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17950         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17951                    UNSPEC_FIST))]
17952   "TARGET_USE_FANCY_MATH_387
17953    && !(reload_completed || reload_in_progress)"
17954   "#"
17955   "&& 1"
17956   [(const_int 0)]
17957 {
17958   if (memory_operand (operands[0], VOIDmode))
17959     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17960   else
17961     {
17962       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17963       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17964                                          operands[2]));
17965     }
17966   DONE;
17967 }
17968   [(set_attr "type" "fpspc")
17969    (set_attr "mode" "DI")])
17970
17971 (define_insn "fistdi2"
17972   [(set (match_operand:DI 0 "memory_operand" "=m")
17973         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17974                    UNSPEC_FIST))
17975    (clobber (match_scratch:XF 2 "=&1f"))]
17976   "TARGET_USE_FANCY_MATH_387"
17977   "* return output_fix_trunc (insn, operands, 0);"
17978   [(set_attr "type" "fpspc")
17979    (set_attr "mode" "DI")])
17980
17981 (define_insn "fistdi2_with_temp"
17982   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17983         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17984                    UNSPEC_FIST))
17985    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17986    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17987   "TARGET_USE_FANCY_MATH_387"
17988   "#"
17989   [(set_attr "type" "fpspc")
17990    (set_attr "mode" "DI")])
17991
17992 (define_split
17993   [(set (match_operand:DI 0 "register_operand" "")
17994         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17995                    UNSPEC_FIST))
17996    (clobber (match_operand:DI 2 "memory_operand" ""))
17997    (clobber (match_scratch 3 ""))]
17998   "reload_completed"
17999   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18000               (clobber (match_dup 3))])
18001    (set (match_dup 0) (match_dup 2))]
18002   "")
18003
18004 (define_split
18005   [(set (match_operand:DI 0 "memory_operand" "")
18006         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18007                    UNSPEC_FIST))
18008    (clobber (match_operand:DI 2 "memory_operand" ""))
18009    (clobber (match_scratch 3 ""))]
18010   "reload_completed"
18011   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18012               (clobber (match_dup 3))])]
18013   "")
18014
18015 (define_insn_and_split "*fist<mode>2_1"
18016   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18017         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18018                            UNSPEC_FIST))]
18019   "TARGET_USE_FANCY_MATH_387
18020    && !(reload_completed || reload_in_progress)"
18021   "#"
18022   "&& 1"
18023   [(const_int 0)]
18024 {
18025   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18026   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18027                                         operands[2]));
18028   DONE;
18029 }
18030   [(set_attr "type" "fpspc")
18031    (set_attr "mode" "<MODE>")])
18032
18033 (define_insn "fist<mode>2"
18034   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18035         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18036                            UNSPEC_FIST))]
18037   "TARGET_USE_FANCY_MATH_387"
18038   "* return output_fix_trunc (insn, operands, 0);"
18039   [(set_attr "type" "fpspc")
18040    (set_attr "mode" "<MODE>")])
18041
18042 (define_insn "fist<mode>2_with_temp"
18043   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18044         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18045                            UNSPEC_FIST))
18046    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18047   "TARGET_USE_FANCY_MATH_387"
18048   "#"
18049   [(set_attr "type" "fpspc")
18050    (set_attr "mode" "<MODE>")])
18051
18052 (define_split
18053   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18054         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18055                            UNSPEC_FIST))
18056    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18057   "reload_completed"
18058   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18059    (set (match_dup 0) (match_dup 2))]
18060   "")
18061
18062 (define_split
18063   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18064         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18065                            UNSPEC_FIST))
18066    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18067   "reload_completed"
18068   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18069   "")
18070
18071 (define_expand "lrintxf<mode>2"
18072   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18073      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18074                       UNSPEC_FIST))]
18075   "TARGET_USE_FANCY_MATH_387"
18076   "")
18077
18078 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18079   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18080      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18081                         UNSPEC_FIX_NOTRUNC))]
18082   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18083    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18084   "")
18085
18086 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18087   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18088    (match_operand:MODEF 1 "register_operand" "")]
18089   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18090    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18091    && !flag_trapping_math && !flag_rounding_math"
18092 {
18093   if (optimize_insn_for_size_p ())
18094     FAIL;
18095   ix86_expand_lround (operand0, operand1);
18096   DONE;
18097 })
18098
18099 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18100 (define_insn_and_split "frndintxf2_floor"
18101   [(set (match_operand:XF 0 "register_operand" "")
18102         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18103          UNSPEC_FRNDINT_FLOOR))
18104    (clobber (reg:CC FLAGS_REG))]
18105   "TARGET_USE_FANCY_MATH_387
18106    && flag_unsafe_math_optimizations
18107    && !(reload_completed || reload_in_progress)"
18108   "#"
18109   "&& 1"
18110   [(const_int 0)]
18111 {
18112   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18113
18114   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18115   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18116
18117   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18118                                         operands[2], operands[3]));
18119   DONE;
18120 }
18121   [(set_attr "type" "frndint")
18122    (set_attr "i387_cw" "floor")
18123    (set_attr "mode" "XF")])
18124
18125 (define_insn "frndintxf2_floor_i387"
18126   [(set (match_operand:XF 0 "register_operand" "=f")
18127         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18128          UNSPEC_FRNDINT_FLOOR))
18129    (use (match_operand:HI 2 "memory_operand" "m"))
18130    (use (match_operand:HI 3 "memory_operand" "m"))]
18131   "TARGET_USE_FANCY_MATH_387
18132    && flag_unsafe_math_optimizations"
18133   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18134   [(set_attr "type" "frndint")
18135    (set_attr "i387_cw" "floor")
18136    (set_attr "mode" "XF")])
18137
18138 (define_expand "floorxf2"
18139   [(use (match_operand:XF 0 "register_operand" ""))
18140    (use (match_operand:XF 1 "register_operand" ""))]
18141   "TARGET_USE_FANCY_MATH_387
18142    && flag_unsafe_math_optimizations"
18143 {
18144   if (optimize_insn_for_size_p ())
18145     FAIL;
18146   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18147   DONE;
18148 })
18149
18150 (define_expand "floor<mode>2"
18151   [(use (match_operand:MODEF 0 "register_operand" ""))
18152    (use (match_operand:MODEF 1 "register_operand" ""))]
18153   "(TARGET_USE_FANCY_MATH_387
18154     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18155         || TARGET_MIX_SSE_I387)
18156     && flag_unsafe_math_optimizations)
18157    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18158        && !flag_trapping_math)"
18159 {
18160   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18161       && !flag_trapping_math
18162       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18163     {
18164       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18165         FAIL;
18166       if (TARGET_ROUND)
18167         emit_insn (gen_sse4_1_round<mode>2
18168                    (operands[0], operands[1], GEN_INT (0x01)));
18169       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18170         ix86_expand_floorceil (operand0, operand1, true);
18171       else
18172         ix86_expand_floorceildf_32 (operand0, operand1, true);
18173     }
18174   else
18175     {
18176       rtx op0, op1;
18177
18178       if (optimize_insn_for_size_p ())
18179         FAIL;
18180
18181       op0 = gen_reg_rtx (XFmode);
18182       op1 = gen_reg_rtx (XFmode);
18183       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18184       emit_insn (gen_frndintxf2_floor (op0, op1));
18185
18186       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18187     }
18188   DONE;
18189 })
18190
18191 (define_insn_and_split "*fist<mode>2_floor_1"
18192   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18193         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18194          UNSPEC_FIST_FLOOR))
18195    (clobber (reg:CC FLAGS_REG))]
18196   "TARGET_USE_FANCY_MATH_387
18197    && flag_unsafe_math_optimizations
18198    && !(reload_completed || reload_in_progress)"
18199   "#"
18200   "&& 1"
18201   [(const_int 0)]
18202 {
18203   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18204
18205   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18206   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18207   if (memory_operand (operands[0], VOIDmode))
18208     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18209                                       operands[2], operands[3]));
18210   else
18211     {
18212       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18213       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18214                                                   operands[2], operands[3],
18215                                                   operands[4]));
18216     }
18217   DONE;
18218 }
18219   [(set_attr "type" "fistp")
18220    (set_attr "i387_cw" "floor")
18221    (set_attr "mode" "<MODE>")])
18222
18223 (define_insn "fistdi2_floor"
18224   [(set (match_operand:DI 0 "memory_operand" "=m")
18225         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18226          UNSPEC_FIST_FLOOR))
18227    (use (match_operand:HI 2 "memory_operand" "m"))
18228    (use (match_operand:HI 3 "memory_operand" "m"))
18229    (clobber (match_scratch:XF 4 "=&1f"))]
18230   "TARGET_USE_FANCY_MATH_387
18231    && flag_unsafe_math_optimizations"
18232   "* return output_fix_trunc (insn, operands, 0);"
18233   [(set_attr "type" "fistp")
18234    (set_attr "i387_cw" "floor")
18235    (set_attr "mode" "DI")])
18236
18237 (define_insn "fistdi2_floor_with_temp"
18238   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18239         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18240          UNSPEC_FIST_FLOOR))
18241    (use (match_operand:HI 2 "memory_operand" "m,m"))
18242    (use (match_operand:HI 3 "memory_operand" "m,m"))
18243    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18244    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18245   "TARGET_USE_FANCY_MATH_387
18246    && flag_unsafe_math_optimizations"
18247   "#"
18248   [(set_attr "type" "fistp")
18249    (set_attr "i387_cw" "floor")
18250    (set_attr "mode" "DI")])
18251
18252 (define_split
18253   [(set (match_operand:DI 0 "register_operand" "")
18254         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18255          UNSPEC_FIST_FLOOR))
18256    (use (match_operand:HI 2 "memory_operand" ""))
18257    (use (match_operand:HI 3 "memory_operand" ""))
18258    (clobber (match_operand:DI 4 "memory_operand" ""))
18259    (clobber (match_scratch 5 ""))]
18260   "reload_completed"
18261   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18262               (use (match_dup 2))
18263               (use (match_dup 3))
18264               (clobber (match_dup 5))])
18265    (set (match_dup 0) (match_dup 4))]
18266   "")
18267
18268 (define_split
18269   [(set (match_operand:DI 0 "memory_operand" "")
18270         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18271          UNSPEC_FIST_FLOOR))
18272    (use (match_operand:HI 2 "memory_operand" ""))
18273    (use (match_operand:HI 3 "memory_operand" ""))
18274    (clobber (match_operand:DI 4 "memory_operand" ""))
18275    (clobber (match_scratch 5 ""))]
18276   "reload_completed"
18277   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18278               (use (match_dup 2))
18279               (use (match_dup 3))
18280               (clobber (match_dup 5))])]
18281   "")
18282
18283 (define_insn "fist<mode>2_floor"
18284   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18285         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18286          UNSPEC_FIST_FLOOR))
18287    (use (match_operand:HI 2 "memory_operand" "m"))
18288    (use (match_operand:HI 3 "memory_operand" "m"))]
18289   "TARGET_USE_FANCY_MATH_387
18290    && flag_unsafe_math_optimizations"
18291   "* return output_fix_trunc (insn, operands, 0);"
18292   [(set_attr "type" "fistp")
18293    (set_attr "i387_cw" "floor")
18294    (set_attr "mode" "<MODE>")])
18295
18296 (define_insn "fist<mode>2_floor_with_temp"
18297   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18298         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18299          UNSPEC_FIST_FLOOR))
18300    (use (match_operand:HI 2 "memory_operand" "m,m"))
18301    (use (match_operand:HI 3 "memory_operand" "m,m"))
18302    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18303   "TARGET_USE_FANCY_MATH_387
18304    && flag_unsafe_math_optimizations"
18305   "#"
18306   [(set_attr "type" "fistp")
18307    (set_attr "i387_cw" "floor")
18308    (set_attr "mode" "<MODE>")])
18309
18310 (define_split
18311   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18312         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18313          UNSPEC_FIST_FLOOR))
18314    (use (match_operand:HI 2 "memory_operand" ""))
18315    (use (match_operand:HI 3 "memory_operand" ""))
18316    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18317   "reload_completed"
18318   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18319                                   UNSPEC_FIST_FLOOR))
18320               (use (match_dup 2))
18321               (use (match_dup 3))])
18322    (set (match_dup 0) (match_dup 4))]
18323   "")
18324
18325 (define_split
18326   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18327         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18328          UNSPEC_FIST_FLOOR))
18329    (use (match_operand:HI 2 "memory_operand" ""))
18330    (use (match_operand:HI 3 "memory_operand" ""))
18331    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18332   "reload_completed"
18333   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18334                                   UNSPEC_FIST_FLOOR))
18335               (use (match_dup 2))
18336               (use (match_dup 3))])]
18337   "")
18338
18339 (define_expand "lfloorxf<mode>2"
18340   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18341                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18342                     UNSPEC_FIST_FLOOR))
18343               (clobber (reg:CC FLAGS_REG))])]
18344   "TARGET_USE_FANCY_MATH_387
18345    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18346    && flag_unsafe_math_optimizations"
18347   "")
18348
18349 (define_expand "lfloor<mode>di2"
18350   [(match_operand:DI 0 "nonimmediate_operand" "")
18351    (match_operand:MODEF 1 "register_operand" "")]
18352   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18353    && !flag_trapping_math"
18354 {
18355   if (optimize_insn_for_size_p ())
18356     FAIL;
18357   ix86_expand_lfloorceil (operand0, operand1, true);
18358   DONE;
18359 })
18360
18361 (define_expand "lfloor<mode>si2"
18362   [(match_operand:SI 0 "nonimmediate_operand" "")
18363    (match_operand:MODEF 1 "register_operand" "")]
18364   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18365    && !flag_trapping_math"
18366 {
18367   if (optimize_insn_for_size_p () && TARGET_64BIT)
18368     FAIL;
18369   ix86_expand_lfloorceil (operand0, operand1, true);
18370   DONE;
18371 })
18372
18373 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18374 (define_insn_and_split "frndintxf2_ceil"
18375   [(set (match_operand:XF 0 "register_operand" "")
18376         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18377          UNSPEC_FRNDINT_CEIL))
18378    (clobber (reg:CC FLAGS_REG))]
18379   "TARGET_USE_FANCY_MATH_387
18380    && flag_unsafe_math_optimizations
18381    && !(reload_completed || reload_in_progress)"
18382   "#"
18383   "&& 1"
18384   [(const_int 0)]
18385 {
18386   ix86_optimize_mode_switching[I387_CEIL] = 1;
18387
18388   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18389   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18390
18391   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18392                                        operands[2], operands[3]));
18393   DONE;
18394 }
18395   [(set_attr "type" "frndint")
18396    (set_attr "i387_cw" "ceil")
18397    (set_attr "mode" "XF")])
18398
18399 (define_insn "frndintxf2_ceil_i387"
18400   [(set (match_operand:XF 0 "register_operand" "=f")
18401         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18402          UNSPEC_FRNDINT_CEIL))
18403    (use (match_operand:HI 2 "memory_operand" "m"))
18404    (use (match_operand:HI 3 "memory_operand" "m"))]
18405   "TARGET_USE_FANCY_MATH_387
18406    && flag_unsafe_math_optimizations"
18407   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18408   [(set_attr "type" "frndint")
18409    (set_attr "i387_cw" "ceil")
18410    (set_attr "mode" "XF")])
18411
18412 (define_expand "ceilxf2"
18413   [(use (match_operand:XF 0 "register_operand" ""))
18414    (use (match_operand:XF 1 "register_operand" ""))]
18415   "TARGET_USE_FANCY_MATH_387
18416    && flag_unsafe_math_optimizations"
18417 {
18418   if (optimize_insn_for_size_p ())
18419     FAIL;
18420   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18421   DONE;
18422 })
18423
18424 (define_expand "ceil<mode>2"
18425   [(use (match_operand:MODEF 0 "register_operand" ""))
18426    (use (match_operand:MODEF 1 "register_operand" ""))]
18427   "(TARGET_USE_FANCY_MATH_387
18428     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18429         || TARGET_MIX_SSE_I387)
18430     && flag_unsafe_math_optimizations)
18431    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18432        && !flag_trapping_math)"
18433 {
18434   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18435       && !flag_trapping_math
18436       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18437     {
18438       if (TARGET_ROUND)
18439         emit_insn (gen_sse4_1_round<mode>2
18440                    (operands[0], operands[1], GEN_INT (0x02)));
18441       else if (optimize_insn_for_size_p ())
18442         FAIL;
18443       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18444         ix86_expand_floorceil (operand0, operand1, false);
18445       else
18446         ix86_expand_floorceildf_32 (operand0, operand1, false);
18447     }
18448   else
18449     {
18450       rtx op0, op1;
18451
18452       if (optimize_insn_for_size_p ())
18453         FAIL;
18454
18455       op0 = gen_reg_rtx (XFmode);
18456       op1 = gen_reg_rtx (XFmode);
18457       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18458       emit_insn (gen_frndintxf2_ceil (op0, op1));
18459
18460       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18461     }
18462   DONE;
18463 })
18464
18465 (define_insn_and_split "*fist<mode>2_ceil_1"
18466   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18467         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18468          UNSPEC_FIST_CEIL))
18469    (clobber (reg:CC FLAGS_REG))]
18470   "TARGET_USE_FANCY_MATH_387
18471    && flag_unsafe_math_optimizations
18472    && !(reload_completed || reload_in_progress)"
18473   "#"
18474   "&& 1"
18475   [(const_int 0)]
18476 {
18477   ix86_optimize_mode_switching[I387_CEIL] = 1;
18478
18479   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18480   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18481   if (memory_operand (operands[0], VOIDmode))
18482     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18483                                      operands[2], operands[3]));
18484   else
18485     {
18486       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18487       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18488                                                  operands[2], operands[3],
18489                                                  operands[4]));
18490     }
18491   DONE;
18492 }
18493   [(set_attr "type" "fistp")
18494    (set_attr "i387_cw" "ceil")
18495    (set_attr "mode" "<MODE>")])
18496
18497 (define_insn "fistdi2_ceil"
18498   [(set (match_operand:DI 0 "memory_operand" "=m")
18499         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18500          UNSPEC_FIST_CEIL))
18501    (use (match_operand:HI 2 "memory_operand" "m"))
18502    (use (match_operand:HI 3 "memory_operand" "m"))
18503    (clobber (match_scratch:XF 4 "=&1f"))]
18504   "TARGET_USE_FANCY_MATH_387
18505    && flag_unsafe_math_optimizations"
18506   "* return output_fix_trunc (insn, operands, 0);"
18507   [(set_attr "type" "fistp")
18508    (set_attr "i387_cw" "ceil")
18509    (set_attr "mode" "DI")])
18510
18511 (define_insn "fistdi2_ceil_with_temp"
18512   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18513         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18514          UNSPEC_FIST_CEIL))
18515    (use (match_operand:HI 2 "memory_operand" "m,m"))
18516    (use (match_operand:HI 3 "memory_operand" "m,m"))
18517    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18518    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18519   "TARGET_USE_FANCY_MATH_387
18520    && flag_unsafe_math_optimizations"
18521   "#"
18522   [(set_attr "type" "fistp")
18523    (set_attr "i387_cw" "ceil")
18524    (set_attr "mode" "DI")])
18525
18526 (define_split
18527   [(set (match_operand:DI 0 "register_operand" "")
18528         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18529          UNSPEC_FIST_CEIL))
18530    (use (match_operand:HI 2 "memory_operand" ""))
18531    (use (match_operand:HI 3 "memory_operand" ""))
18532    (clobber (match_operand:DI 4 "memory_operand" ""))
18533    (clobber (match_scratch 5 ""))]
18534   "reload_completed"
18535   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18536               (use (match_dup 2))
18537               (use (match_dup 3))
18538               (clobber (match_dup 5))])
18539    (set (match_dup 0) (match_dup 4))]
18540   "")
18541
18542 (define_split
18543   [(set (match_operand:DI 0 "memory_operand" "")
18544         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18545          UNSPEC_FIST_CEIL))
18546    (use (match_operand:HI 2 "memory_operand" ""))
18547    (use (match_operand:HI 3 "memory_operand" ""))
18548    (clobber (match_operand:DI 4 "memory_operand" ""))
18549    (clobber (match_scratch 5 ""))]
18550   "reload_completed"
18551   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18552               (use (match_dup 2))
18553               (use (match_dup 3))
18554               (clobber (match_dup 5))])]
18555   "")
18556
18557 (define_insn "fist<mode>2_ceil"
18558   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18559         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18560          UNSPEC_FIST_CEIL))
18561    (use (match_operand:HI 2 "memory_operand" "m"))
18562    (use (match_operand:HI 3 "memory_operand" "m"))]
18563   "TARGET_USE_FANCY_MATH_387
18564    && flag_unsafe_math_optimizations"
18565   "* return output_fix_trunc (insn, operands, 0);"
18566   [(set_attr "type" "fistp")
18567    (set_attr "i387_cw" "ceil")
18568    (set_attr "mode" "<MODE>")])
18569
18570 (define_insn "fist<mode>2_ceil_with_temp"
18571   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18572         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18573          UNSPEC_FIST_CEIL))
18574    (use (match_operand:HI 2 "memory_operand" "m,m"))
18575    (use (match_operand:HI 3 "memory_operand" "m,m"))
18576    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18577   "TARGET_USE_FANCY_MATH_387
18578    && flag_unsafe_math_optimizations"
18579   "#"
18580   [(set_attr "type" "fistp")
18581    (set_attr "i387_cw" "ceil")
18582    (set_attr "mode" "<MODE>")])
18583
18584 (define_split
18585   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18586         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18587          UNSPEC_FIST_CEIL))
18588    (use (match_operand:HI 2 "memory_operand" ""))
18589    (use (match_operand:HI 3 "memory_operand" ""))
18590    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18591   "reload_completed"
18592   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18593                                   UNSPEC_FIST_CEIL))
18594               (use (match_dup 2))
18595               (use (match_dup 3))])
18596    (set (match_dup 0) (match_dup 4))]
18597   "")
18598
18599 (define_split
18600   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18601         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18602          UNSPEC_FIST_CEIL))
18603    (use (match_operand:HI 2 "memory_operand" ""))
18604    (use (match_operand:HI 3 "memory_operand" ""))
18605    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18606   "reload_completed"
18607   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18608                                   UNSPEC_FIST_CEIL))
18609               (use (match_dup 2))
18610               (use (match_dup 3))])]
18611   "")
18612
18613 (define_expand "lceilxf<mode>2"
18614   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18615                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18616                     UNSPEC_FIST_CEIL))
18617               (clobber (reg:CC FLAGS_REG))])]
18618   "TARGET_USE_FANCY_MATH_387
18619    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18620    && flag_unsafe_math_optimizations"
18621   "")
18622
18623 (define_expand "lceil<mode>di2"
18624   [(match_operand:DI 0 "nonimmediate_operand" "")
18625    (match_operand:MODEF 1 "register_operand" "")]
18626   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18627    && !flag_trapping_math"
18628 {
18629   ix86_expand_lfloorceil (operand0, operand1, false);
18630   DONE;
18631 })
18632
18633 (define_expand "lceil<mode>si2"
18634   [(match_operand:SI 0 "nonimmediate_operand" "")
18635    (match_operand:MODEF 1 "register_operand" "")]
18636   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18637    && !flag_trapping_math"
18638 {
18639   ix86_expand_lfloorceil (operand0, operand1, false);
18640   DONE;
18641 })
18642
18643 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18644 (define_insn_and_split "frndintxf2_trunc"
18645   [(set (match_operand:XF 0 "register_operand" "")
18646         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18647          UNSPEC_FRNDINT_TRUNC))
18648    (clobber (reg:CC FLAGS_REG))]
18649   "TARGET_USE_FANCY_MATH_387
18650    && flag_unsafe_math_optimizations
18651    && !(reload_completed || reload_in_progress)"
18652   "#"
18653   "&& 1"
18654   [(const_int 0)]
18655 {
18656   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18657
18658   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18659   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18660
18661   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18662                                         operands[2], operands[3]));
18663   DONE;
18664 }
18665   [(set_attr "type" "frndint")
18666    (set_attr "i387_cw" "trunc")
18667    (set_attr "mode" "XF")])
18668
18669 (define_insn "frndintxf2_trunc_i387"
18670   [(set (match_operand:XF 0 "register_operand" "=f")
18671         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18672          UNSPEC_FRNDINT_TRUNC))
18673    (use (match_operand:HI 2 "memory_operand" "m"))
18674    (use (match_operand:HI 3 "memory_operand" "m"))]
18675   "TARGET_USE_FANCY_MATH_387
18676    && flag_unsafe_math_optimizations"
18677   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18678   [(set_attr "type" "frndint")
18679    (set_attr "i387_cw" "trunc")
18680    (set_attr "mode" "XF")])
18681
18682 (define_expand "btruncxf2"
18683   [(use (match_operand:XF 0 "register_operand" ""))
18684    (use (match_operand:XF 1 "register_operand" ""))]
18685   "TARGET_USE_FANCY_MATH_387
18686    && flag_unsafe_math_optimizations"
18687 {
18688   if (optimize_insn_for_size_p ())
18689     FAIL;
18690   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18691   DONE;
18692 })
18693
18694 (define_expand "btrunc<mode>2"
18695   [(use (match_operand:MODEF 0 "register_operand" ""))
18696    (use (match_operand:MODEF 1 "register_operand" ""))]
18697   "(TARGET_USE_FANCY_MATH_387
18698     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18699         || TARGET_MIX_SSE_I387)
18700     && flag_unsafe_math_optimizations)
18701    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18702        && !flag_trapping_math)"
18703 {
18704   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18705       && !flag_trapping_math
18706       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18707     {
18708       if (TARGET_ROUND)
18709         emit_insn (gen_sse4_1_round<mode>2
18710                    (operands[0], operands[1], GEN_INT (0x03)));
18711       else if (optimize_insn_for_size_p ())
18712         FAIL;
18713       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18714         ix86_expand_trunc (operand0, operand1);
18715       else
18716         ix86_expand_truncdf_32 (operand0, operand1);
18717     }
18718   else
18719     {
18720       rtx op0, op1;
18721
18722       if (optimize_insn_for_size_p ())
18723         FAIL;
18724
18725       op0 = gen_reg_rtx (XFmode);
18726       op1 = gen_reg_rtx (XFmode);
18727       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18728       emit_insn (gen_frndintxf2_trunc (op0, op1));
18729
18730       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18731     }
18732   DONE;
18733 })
18734
18735 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18736 (define_insn_and_split "frndintxf2_mask_pm"
18737   [(set (match_operand:XF 0 "register_operand" "")
18738         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18739          UNSPEC_FRNDINT_MASK_PM))
18740    (clobber (reg:CC FLAGS_REG))]
18741   "TARGET_USE_FANCY_MATH_387
18742    && flag_unsafe_math_optimizations
18743    && !(reload_completed || reload_in_progress)"
18744   "#"
18745   "&& 1"
18746   [(const_int 0)]
18747 {
18748   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18749
18750   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18751   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18752
18753   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18754                                           operands[2], operands[3]));
18755   DONE;
18756 }
18757   [(set_attr "type" "frndint")
18758    (set_attr "i387_cw" "mask_pm")
18759    (set_attr "mode" "XF")])
18760
18761 (define_insn "frndintxf2_mask_pm_i387"
18762   [(set (match_operand:XF 0 "register_operand" "=f")
18763         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18764          UNSPEC_FRNDINT_MASK_PM))
18765    (use (match_operand:HI 2 "memory_operand" "m"))
18766    (use (match_operand:HI 3 "memory_operand" "m"))]
18767   "TARGET_USE_FANCY_MATH_387
18768    && flag_unsafe_math_optimizations"
18769   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18770   [(set_attr "type" "frndint")
18771    (set_attr "i387_cw" "mask_pm")
18772    (set_attr "mode" "XF")])
18773
18774 (define_expand "nearbyintxf2"
18775   [(use (match_operand:XF 0 "register_operand" ""))
18776    (use (match_operand:XF 1 "register_operand" ""))]
18777   "TARGET_USE_FANCY_MATH_387
18778    && flag_unsafe_math_optimizations"
18779 {
18780   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18781
18782   DONE;
18783 })
18784
18785 (define_expand "nearbyint<mode>2"
18786   [(use (match_operand:MODEF 0 "register_operand" ""))
18787    (use (match_operand:MODEF 1 "register_operand" ""))]
18788   "TARGET_USE_FANCY_MATH_387
18789    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18790        || TARGET_MIX_SSE_I387)
18791    && flag_unsafe_math_optimizations"
18792 {
18793   rtx op0 = gen_reg_rtx (XFmode);
18794   rtx op1 = gen_reg_rtx (XFmode);
18795
18796   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18797   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18798
18799   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18800   DONE;
18801 })
18802
18803 (define_insn "fxam<mode>2_i387"
18804   [(set (match_operand:HI 0 "register_operand" "=a")
18805         (unspec:HI
18806           [(match_operand:X87MODEF 1 "register_operand" "f")]
18807           UNSPEC_FXAM))]
18808   "TARGET_USE_FANCY_MATH_387"
18809   "fxam\n\tfnstsw\t%0"
18810   [(set_attr "type" "multi")
18811    (set_attr "unit" "i387")
18812    (set_attr "mode" "<MODE>")])
18813
18814 (define_expand "isinf<mode>2"
18815   [(use (match_operand:SI 0 "register_operand" ""))
18816    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18817   "TARGET_USE_FANCY_MATH_387
18818    && TARGET_C99_FUNCTIONS
18819    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18820 {
18821   rtx mask = GEN_INT (0x45);
18822   rtx val = GEN_INT (0x05);
18823
18824   rtx cond;
18825
18826   rtx scratch = gen_reg_rtx (HImode);
18827   rtx res = gen_reg_rtx (QImode);
18828
18829   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18830   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18831   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18832   cond = gen_rtx_fmt_ee (EQ, QImode,
18833                          gen_rtx_REG (CCmode, FLAGS_REG),
18834                          const0_rtx);
18835   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18836   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18837   DONE;
18838 })
18839
18840 (define_expand "signbit<mode>2"
18841   [(use (match_operand:SI 0 "register_operand" ""))
18842    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18843   "TARGET_USE_FANCY_MATH_387
18844    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18845 {
18846   rtx mask = GEN_INT (0x0200);
18847
18848   rtx scratch = gen_reg_rtx (HImode);
18849
18850   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18851   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18852   DONE;
18853 })
18854 \f
18855 ;; Block operation instructions
18856
18857 (define_insn "cld"
18858   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18859   ""
18860   "cld"
18861   [(set_attr "length" "1")
18862    (set_attr "length_immediate" "0")
18863    (set_attr "modrm" "0")])
18864
18865 (define_expand "movmemsi"
18866   [(use (match_operand:BLK 0 "memory_operand" ""))
18867    (use (match_operand:BLK 1 "memory_operand" ""))
18868    (use (match_operand:SI 2 "nonmemory_operand" ""))
18869    (use (match_operand:SI 3 "const_int_operand" ""))
18870    (use (match_operand:SI 4 "const_int_operand" ""))
18871    (use (match_operand:SI 5 "const_int_operand" ""))]
18872   ""
18873 {
18874  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18875                          operands[4], operands[5]))
18876    DONE;
18877  else
18878    FAIL;
18879 })
18880
18881 (define_expand "movmemdi"
18882   [(use (match_operand:BLK 0 "memory_operand" ""))
18883    (use (match_operand:BLK 1 "memory_operand" ""))
18884    (use (match_operand:DI 2 "nonmemory_operand" ""))
18885    (use (match_operand:DI 3 "const_int_operand" ""))
18886    (use (match_operand:SI 4 "const_int_operand" ""))
18887    (use (match_operand:SI 5 "const_int_operand" ""))]
18888   "TARGET_64BIT"
18889 {
18890  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18891                          operands[4], operands[5]))
18892    DONE;
18893  else
18894    FAIL;
18895 })
18896
18897 ;; Most CPUs don't like single string operations
18898 ;; Handle this case here to simplify previous expander.
18899
18900 (define_expand "strmov"
18901   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18902    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18903    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18904               (clobber (reg:CC FLAGS_REG))])
18905    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18906               (clobber (reg:CC FLAGS_REG))])]
18907   ""
18908 {
18909   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18910
18911   /* If .md ever supports :P for Pmode, these can be directly
18912      in the pattern above.  */
18913   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18914   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18915
18916   /* Can't use this if the user has appropriated esi or edi.  */
18917   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18918       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18919     {
18920       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18921                                       operands[2], operands[3],
18922                                       operands[5], operands[6]));
18923       DONE;
18924     }
18925
18926   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18927 })
18928
18929 (define_expand "strmov_singleop"
18930   [(parallel [(set (match_operand 1 "memory_operand" "")
18931                    (match_operand 3 "memory_operand" ""))
18932               (set (match_operand 0 "register_operand" "")
18933                    (match_operand 4 "" ""))
18934               (set (match_operand 2 "register_operand" "")
18935                    (match_operand 5 "" ""))])]
18936   ""
18937   "ix86_current_function_needs_cld = 1;")
18938
18939 (define_insn "*strmovdi_rex_1"
18940   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18941         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18942    (set (match_operand:DI 0 "register_operand" "=D")
18943         (plus:DI (match_dup 2)
18944                  (const_int 8)))
18945    (set (match_operand:DI 1 "register_operand" "=S")
18946         (plus:DI (match_dup 3)
18947                  (const_int 8)))]
18948   "TARGET_64BIT"
18949   "movsq"
18950   [(set_attr "type" "str")
18951    (set_attr "mode" "DI")
18952    (set_attr "memory" "both")])
18953
18954 (define_insn "*strmovsi_1"
18955   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18956         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18957    (set (match_operand:SI 0 "register_operand" "=D")
18958         (plus:SI (match_dup 2)
18959                  (const_int 4)))
18960    (set (match_operand:SI 1 "register_operand" "=S")
18961         (plus:SI (match_dup 3)
18962                  (const_int 4)))]
18963   "!TARGET_64BIT"
18964   "movs{l|d}"
18965   [(set_attr "type" "str")
18966    (set_attr "mode" "SI")
18967    (set_attr "memory" "both")])
18968
18969 (define_insn "*strmovsi_rex_1"
18970   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18971         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18972    (set (match_operand:DI 0 "register_operand" "=D")
18973         (plus:DI (match_dup 2)
18974                  (const_int 4)))
18975    (set (match_operand:DI 1 "register_operand" "=S")
18976         (plus:DI (match_dup 3)
18977                  (const_int 4)))]
18978   "TARGET_64BIT"
18979   "movs{l|d}"
18980   [(set_attr "type" "str")
18981    (set_attr "mode" "SI")
18982    (set_attr "memory" "both")])
18983
18984 (define_insn "*strmovhi_1"
18985   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18986         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18987    (set (match_operand:SI 0 "register_operand" "=D")
18988         (plus:SI (match_dup 2)
18989                  (const_int 2)))
18990    (set (match_operand:SI 1 "register_operand" "=S")
18991         (plus:SI (match_dup 3)
18992                  (const_int 2)))]
18993   "!TARGET_64BIT"
18994   "movsw"
18995   [(set_attr "type" "str")
18996    (set_attr "memory" "both")
18997    (set_attr "mode" "HI")])
18998
18999 (define_insn "*strmovhi_rex_1"
19000   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19001         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19002    (set (match_operand:DI 0 "register_operand" "=D")
19003         (plus:DI (match_dup 2)
19004                  (const_int 2)))
19005    (set (match_operand:DI 1 "register_operand" "=S")
19006         (plus:DI (match_dup 3)
19007                  (const_int 2)))]
19008   "TARGET_64BIT"
19009   "movsw"
19010   [(set_attr "type" "str")
19011    (set_attr "memory" "both")
19012    (set_attr "mode" "HI")])
19013
19014 (define_insn "*strmovqi_1"
19015   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19016         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19017    (set (match_operand:SI 0 "register_operand" "=D")
19018         (plus:SI (match_dup 2)
19019                  (const_int 1)))
19020    (set (match_operand:SI 1 "register_operand" "=S")
19021         (plus:SI (match_dup 3)
19022                  (const_int 1)))]
19023   "!TARGET_64BIT"
19024   "movsb"
19025   [(set_attr "type" "str")
19026    (set_attr "memory" "both")
19027    (set_attr "mode" "QI")])
19028
19029 (define_insn "*strmovqi_rex_1"
19030   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19031         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19032    (set (match_operand:DI 0 "register_operand" "=D")
19033         (plus:DI (match_dup 2)
19034                  (const_int 1)))
19035    (set (match_operand:DI 1 "register_operand" "=S")
19036         (plus:DI (match_dup 3)
19037                  (const_int 1)))]
19038   "TARGET_64BIT"
19039   "movsb"
19040   [(set_attr "type" "str")
19041    (set_attr "memory" "both")
19042    (set_attr "mode" "QI")])
19043
19044 (define_expand "rep_mov"
19045   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19046               (set (match_operand 0 "register_operand" "")
19047                    (match_operand 5 "" ""))
19048               (set (match_operand 2 "register_operand" "")
19049                    (match_operand 6 "" ""))
19050               (set (match_operand 1 "memory_operand" "")
19051                    (match_operand 3 "memory_operand" ""))
19052               (use (match_dup 4))])]
19053   ""
19054   "ix86_current_function_needs_cld = 1;")
19055
19056 (define_insn "*rep_movdi_rex64"
19057   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19058    (set (match_operand:DI 0 "register_operand" "=D")
19059         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19060                             (const_int 3))
19061                  (match_operand:DI 3 "register_operand" "0")))
19062    (set (match_operand:DI 1 "register_operand" "=S")
19063         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19064                  (match_operand:DI 4 "register_operand" "1")))
19065    (set (mem:BLK (match_dup 3))
19066         (mem:BLK (match_dup 4)))
19067    (use (match_dup 5))]
19068   "TARGET_64BIT"
19069   "rep movsq"
19070   [(set_attr "type" "str")
19071    (set_attr "prefix_rep" "1")
19072    (set_attr "memory" "both")
19073    (set_attr "mode" "DI")])
19074
19075 (define_insn "*rep_movsi"
19076   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19077    (set (match_operand:SI 0 "register_operand" "=D")
19078         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19079                             (const_int 2))
19080                  (match_operand:SI 3 "register_operand" "0")))
19081    (set (match_operand:SI 1 "register_operand" "=S")
19082         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19083                  (match_operand:SI 4 "register_operand" "1")))
19084    (set (mem:BLK (match_dup 3))
19085         (mem:BLK (match_dup 4)))
19086    (use (match_dup 5))]
19087   "!TARGET_64BIT"
19088   "rep movs{l|d}"
19089   [(set_attr "type" "str")
19090    (set_attr "prefix_rep" "1")
19091    (set_attr "memory" "both")
19092    (set_attr "mode" "SI")])
19093
19094 (define_insn "*rep_movsi_rex64"
19095   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19096    (set (match_operand:DI 0 "register_operand" "=D")
19097         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19098                             (const_int 2))
19099                  (match_operand:DI 3 "register_operand" "0")))
19100    (set (match_operand:DI 1 "register_operand" "=S")
19101         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19102                  (match_operand:DI 4 "register_operand" "1")))
19103    (set (mem:BLK (match_dup 3))
19104         (mem:BLK (match_dup 4)))
19105    (use (match_dup 5))]
19106   "TARGET_64BIT"
19107   "rep movs{l|d}"
19108   [(set_attr "type" "str")
19109    (set_attr "prefix_rep" "1")
19110    (set_attr "memory" "both")
19111    (set_attr "mode" "SI")])
19112
19113 (define_insn "*rep_movqi"
19114   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19115    (set (match_operand:SI 0 "register_operand" "=D")
19116         (plus:SI (match_operand:SI 3 "register_operand" "0")
19117                  (match_operand:SI 5 "register_operand" "2")))
19118    (set (match_operand:SI 1 "register_operand" "=S")
19119         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19120    (set (mem:BLK (match_dup 3))
19121         (mem:BLK (match_dup 4)))
19122    (use (match_dup 5))]
19123   "!TARGET_64BIT"
19124   "rep movsb"
19125   [(set_attr "type" "str")
19126    (set_attr "prefix_rep" "1")
19127    (set_attr "memory" "both")
19128    (set_attr "mode" "SI")])
19129
19130 (define_insn "*rep_movqi_rex64"
19131   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19132    (set (match_operand:DI 0 "register_operand" "=D")
19133         (plus:DI (match_operand:DI 3 "register_operand" "0")
19134                  (match_operand:DI 5 "register_operand" "2")))
19135    (set (match_operand:DI 1 "register_operand" "=S")
19136         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19137    (set (mem:BLK (match_dup 3))
19138         (mem:BLK (match_dup 4)))
19139    (use (match_dup 5))]
19140   "TARGET_64BIT"
19141   "rep movsb"
19142   [(set_attr "type" "str")
19143    (set_attr "prefix_rep" "1")
19144    (set_attr "memory" "both")
19145    (set_attr "mode" "SI")])
19146
19147 (define_expand "setmemsi"
19148    [(use (match_operand:BLK 0 "memory_operand" ""))
19149     (use (match_operand:SI 1 "nonmemory_operand" ""))
19150     (use (match_operand 2 "const_int_operand" ""))
19151     (use (match_operand 3 "const_int_operand" ""))
19152     (use (match_operand:SI 4 "const_int_operand" ""))
19153     (use (match_operand:SI 5 "const_int_operand" ""))]
19154   ""
19155 {
19156  if (ix86_expand_setmem (operands[0], operands[1],
19157                          operands[2], operands[3],
19158                          operands[4], operands[5]))
19159    DONE;
19160  else
19161    FAIL;
19162 })
19163
19164 (define_expand "setmemdi"
19165    [(use (match_operand:BLK 0 "memory_operand" ""))
19166     (use (match_operand:DI 1 "nonmemory_operand" ""))
19167     (use (match_operand 2 "const_int_operand" ""))
19168     (use (match_operand 3 "const_int_operand" ""))
19169     (use (match_operand 4 "const_int_operand" ""))
19170     (use (match_operand 5 "const_int_operand" ""))]
19171   "TARGET_64BIT"
19172 {
19173  if (ix86_expand_setmem (operands[0], operands[1],
19174                          operands[2], operands[3],
19175                          operands[4], operands[5]))
19176    DONE;
19177  else
19178    FAIL;
19179 })
19180
19181 ;; Most CPUs don't like single string operations
19182 ;; Handle this case here to simplify previous expander.
19183
19184 (define_expand "strset"
19185   [(set (match_operand 1 "memory_operand" "")
19186         (match_operand 2 "register_operand" ""))
19187    (parallel [(set (match_operand 0 "register_operand" "")
19188                    (match_dup 3))
19189               (clobber (reg:CC FLAGS_REG))])]
19190   ""
19191 {
19192   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19193     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19194
19195   /* If .md ever supports :P for Pmode, this can be directly
19196      in the pattern above.  */
19197   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19198                               GEN_INT (GET_MODE_SIZE (GET_MODE
19199                                                       (operands[2]))));
19200   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19201     {
19202       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19203                                       operands[3]));
19204       DONE;
19205     }
19206 })
19207
19208 (define_expand "strset_singleop"
19209   [(parallel [(set (match_operand 1 "memory_operand" "")
19210                    (match_operand 2 "register_operand" ""))
19211               (set (match_operand 0 "register_operand" "")
19212                    (match_operand 3 "" ""))])]
19213   ""
19214   "ix86_current_function_needs_cld = 1;")
19215
19216 (define_insn "*strsetdi_rex_1"
19217   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19218         (match_operand:DI 2 "register_operand" "a"))
19219    (set (match_operand:DI 0 "register_operand" "=D")
19220         (plus:DI (match_dup 1)
19221                  (const_int 8)))]
19222   "TARGET_64BIT"
19223   "stosq"
19224   [(set_attr "type" "str")
19225    (set_attr "memory" "store")
19226    (set_attr "mode" "DI")])
19227
19228 (define_insn "*strsetsi_1"
19229   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19230         (match_operand:SI 2 "register_operand" "a"))
19231    (set (match_operand:SI 0 "register_operand" "=D")
19232         (plus:SI (match_dup 1)
19233                  (const_int 4)))]
19234   "!TARGET_64BIT"
19235   "stos{l|d}"
19236   [(set_attr "type" "str")
19237    (set_attr "memory" "store")
19238    (set_attr "mode" "SI")])
19239
19240 (define_insn "*strsetsi_rex_1"
19241   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19242         (match_operand:SI 2 "register_operand" "a"))
19243    (set (match_operand:DI 0 "register_operand" "=D")
19244         (plus:DI (match_dup 1)
19245                  (const_int 4)))]
19246   "TARGET_64BIT"
19247   "stos{l|d}"
19248   [(set_attr "type" "str")
19249    (set_attr "memory" "store")
19250    (set_attr "mode" "SI")])
19251
19252 (define_insn "*strsethi_1"
19253   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19254         (match_operand:HI 2 "register_operand" "a"))
19255    (set (match_operand:SI 0 "register_operand" "=D")
19256         (plus:SI (match_dup 1)
19257                  (const_int 2)))]
19258   "!TARGET_64BIT"
19259   "stosw"
19260   [(set_attr "type" "str")
19261    (set_attr "memory" "store")
19262    (set_attr "mode" "HI")])
19263
19264 (define_insn "*strsethi_rex_1"
19265   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19266         (match_operand:HI 2 "register_operand" "a"))
19267    (set (match_operand:DI 0 "register_operand" "=D")
19268         (plus:DI (match_dup 1)
19269                  (const_int 2)))]
19270   "TARGET_64BIT"
19271   "stosw"
19272   [(set_attr "type" "str")
19273    (set_attr "memory" "store")
19274    (set_attr "mode" "HI")])
19275
19276 (define_insn "*strsetqi_1"
19277   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19278         (match_operand:QI 2 "register_operand" "a"))
19279    (set (match_operand:SI 0 "register_operand" "=D")
19280         (plus:SI (match_dup 1)
19281                  (const_int 1)))]
19282   "!TARGET_64BIT"
19283   "stosb"
19284   [(set_attr "type" "str")
19285    (set_attr "memory" "store")
19286    (set_attr "mode" "QI")])
19287
19288 (define_insn "*strsetqi_rex_1"
19289   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19290         (match_operand:QI 2 "register_operand" "a"))
19291    (set (match_operand:DI 0 "register_operand" "=D")
19292         (plus:DI (match_dup 1)
19293                  (const_int 1)))]
19294   "TARGET_64BIT"
19295   "stosb"
19296   [(set_attr "type" "str")
19297    (set_attr "memory" "store")
19298    (set_attr "mode" "QI")])
19299
19300 (define_expand "rep_stos"
19301   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19302               (set (match_operand 0 "register_operand" "")
19303                    (match_operand 4 "" ""))
19304               (set (match_operand 2 "memory_operand" "") (const_int 0))
19305               (use (match_operand 3 "register_operand" ""))
19306               (use (match_dup 1))])]
19307   ""
19308   "ix86_current_function_needs_cld = 1;")
19309
19310 (define_insn "*rep_stosdi_rex64"
19311   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19312    (set (match_operand:DI 0 "register_operand" "=D")
19313         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19314                             (const_int 3))
19315                  (match_operand:DI 3 "register_operand" "0")))
19316    (set (mem:BLK (match_dup 3))
19317         (const_int 0))
19318    (use (match_operand:DI 2 "register_operand" "a"))
19319    (use (match_dup 4))]
19320   "TARGET_64BIT"
19321   "rep stosq"
19322   [(set_attr "type" "str")
19323    (set_attr "prefix_rep" "1")
19324    (set_attr "memory" "store")
19325    (set_attr "mode" "DI")])
19326
19327 (define_insn "*rep_stossi"
19328   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19329    (set (match_operand:SI 0 "register_operand" "=D")
19330         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19331                             (const_int 2))
19332                  (match_operand:SI 3 "register_operand" "0")))
19333    (set (mem:BLK (match_dup 3))
19334         (const_int 0))
19335    (use (match_operand:SI 2 "register_operand" "a"))
19336    (use (match_dup 4))]
19337   "!TARGET_64BIT"
19338   "rep stos{l|d}"
19339   [(set_attr "type" "str")
19340    (set_attr "prefix_rep" "1")
19341    (set_attr "memory" "store")
19342    (set_attr "mode" "SI")])
19343
19344 (define_insn "*rep_stossi_rex64"
19345   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19346    (set (match_operand:DI 0 "register_operand" "=D")
19347         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19348                             (const_int 2))
19349                  (match_operand:DI 3 "register_operand" "0")))
19350    (set (mem:BLK (match_dup 3))
19351         (const_int 0))
19352    (use (match_operand:SI 2 "register_operand" "a"))
19353    (use (match_dup 4))]
19354   "TARGET_64BIT"
19355   "rep stos{l|d}"
19356   [(set_attr "type" "str")
19357    (set_attr "prefix_rep" "1")
19358    (set_attr "memory" "store")
19359    (set_attr "mode" "SI")])
19360
19361 (define_insn "*rep_stosqi"
19362   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19363    (set (match_operand:SI 0 "register_operand" "=D")
19364         (plus:SI (match_operand:SI 3 "register_operand" "0")
19365                  (match_operand:SI 4 "register_operand" "1")))
19366    (set (mem:BLK (match_dup 3))
19367         (const_int 0))
19368    (use (match_operand:QI 2 "register_operand" "a"))
19369    (use (match_dup 4))]
19370   "!TARGET_64BIT"
19371   "rep stosb"
19372   [(set_attr "type" "str")
19373    (set_attr "prefix_rep" "1")
19374    (set_attr "memory" "store")
19375    (set_attr "mode" "QI")])
19376
19377 (define_insn "*rep_stosqi_rex64"
19378   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19379    (set (match_operand:DI 0 "register_operand" "=D")
19380         (plus:DI (match_operand:DI 3 "register_operand" "0")
19381                  (match_operand:DI 4 "register_operand" "1")))
19382    (set (mem:BLK (match_dup 3))
19383         (const_int 0))
19384    (use (match_operand:QI 2 "register_operand" "a"))
19385    (use (match_dup 4))]
19386   "TARGET_64BIT"
19387   "rep stosb"
19388   [(set_attr "type" "str")
19389    (set_attr "prefix_rep" "1")
19390    (set_attr "memory" "store")
19391    (set_attr "mode" "QI")])
19392
19393 (define_expand "cmpstrnsi"
19394   [(set (match_operand:SI 0 "register_operand" "")
19395         (compare:SI (match_operand:BLK 1 "general_operand" "")
19396                     (match_operand:BLK 2 "general_operand" "")))
19397    (use (match_operand 3 "general_operand" ""))
19398    (use (match_operand 4 "immediate_operand" ""))]
19399   ""
19400 {
19401   rtx addr1, addr2, out, outlow, count, countreg, align;
19402
19403   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19404     FAIL;
19405
19406   /* Can't use this if the user has appropriated esi or edi.  */
19407   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19408     FAIL;
19409
19410   out = operands[0];
19411   if (!REG_P (out))
19412     out = gen_reg_rtx (SImode);
19413
19414   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19415   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19416   if (addr1 != XEXP (operands[1], 0))
19417     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19418   if (addr2 != XEXP (operands[2], 0))
19419     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19420
19421   count = operands[3];
19422   countreg = ix86_zero_extend_to_Pmode (count);
19423
19424   /* %%% Iff we are testing strict equality, we can use known alignment
19425      to good advantage.  This may be possible with combine, particularly
19426      once cc0 is dead.  */
19427   align = operands[4];
19428
19429   if (CONST_INT_P (count))
19430     {
19431       if (INTVAL (count) == 0)
19432         {
19433           emit_move_insn (operands[0], const0_rtx);
19434           DONE;
19435         }
19436       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19437                                      operands[1], operands[2]));
19438     }
19439   else
19440     {
19441       if (TARGET_64BIT)
19442         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19443       else
19444         emit_insn (gen_cmpsi_1 (countreg, countreg));
19445       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19446                                   operands[1], operands[2]));
19447     }
19448
19449   outlow = gen_lowpart (QImode, out);
19450   emit_insn (gen_cmpintqi (outlow));
19451   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19452
19453   if (operands[0] != out)
19454     emit_move_insn (operands[0], out);
19455
19456   DONE;
19457 })
19458
19459 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19460
19461 (define_expand "cmpintqi"
19462   [(set (match_dup 1)
19463         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19464    (set (match_dup 2)
19465         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19466    (parallel [(set (match_operand:QI 0 "register_operand" "")
19467                    (minus:QI (match_dup 1)
19468                              (match_dup 2)))
19469               (clobber (reg:CC FLAGS_REG))])]
19470   ""
19471   "operands[1] = gen_reg_rtx (QImode);
19472    operands[2] = gen_reg_rtx (QImode);")
19473
19474 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19475 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19476
19477 (define_expand "cmpstrnqi_nz_1"
19478   [(parallel [(set (reg:CC FLAGS_REG)
19479                    (compare:CC (match_operand 4 "memory_operand" "")
19480                                (match_operand 5 "memory_operand" "")))
19481               (use (match_operand 2 "register_operand" ""))
19482               (use (match_operand:SI 3 "immediate_operand" ""))
19483               (clobber (match_operand 0 "register_operand" ""))
19484               (clobber (match_operand 1 "register_operand" ""))
19485               (clobber (match_dup 2))])]
19486   ""
19487   "ix86_current_function_needs_cld = 1;")
19488
19489 (define_insn "*cmpstrnqi_nz_1"
19490   [(set (reg:CC FLAGS_REG)
19491         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19492                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19493    (use (match_operand:SI 6 "register_operand" "2"))
19494    (use (match_operand:SI 3 "immediate_operand" "i"))
19495    (clobber (match_operand:SI 0 "register_operand" "=S"))
19496    (clobber (match_operand:SI 1 "register_operand" "=D"))
19497    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19498   "!TARGET_64BIT"
19499   "repz cmpsb"
19500   [(set_attr "type" "str")
19501    (set_attr "mode" "QI")
19502    (set_attr "prefix_rep" "1")])
19503
19504 (define_insn "*cmpstrnqi_nz_rex_1"
19505   [(set (reg:CC FLAGS_REG)
19506         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19507                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19508    (use (match_operand:DI 6 "register_operand" "2"))
19509    (use (match_operand:SI 3 "immediate_operand" "i"))
19510    (clobber (match_operand:DI 0 "register_operand" "=S"))
19511    (clobber (match_operand:DI 1 "register_operand" "=D"))
19512    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19513   "TARGET_64BIT"
19514   "repz cmpsb"
19515   [(set_attr "type" "str")
19516    (set_attr "mode" "QI")
19517    (set_attr "prefix_rep" "1")])
19518
19519 ;; The same, but the count is not known to not be zero.
19520
19521 (define_expand "cmpstrnqi_1"
19522   [(parallel [(set (reg:CC FLAGS_REG)
19523                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19524                                      (const_int 0))
19525                   (compare:CC (match_operand 4 "memory_operand" "")
19526                               (match_operand 5 "memory_operand" ""))
19527                   (const_int 0)))
19528               (use (match_operand:SI 3 "immediate_operand" ""))
19529               (use (reg:CC FLAGS_REG))
19530               (clobber (match_operand 0 "register_operand" ""))
19531               (clobber (match_operand 1 "register_operand" ""))
19532               (clobber (match_dup 2))])]
19533   ""
19534   "ix86_current_function_needs_cld = 1;")
19535
19536 (define_insn "*cmpstrnqi_1"
19537   [(set (reg:CC FLAGS_REG)
19538         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19539                              (const_int 0))
19540           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19541                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19542           (const_int 0)))
19543    (use (match_operand:SI 3 "immediate_operand" "i"))
19544    (use (reg:CC FLAGS_REG))
19545    (clobber (match_operand:SI 0 "register_operand" "=S"))
19546    (clobber (match_operand:SI 1 "register_operand" "=D"))
19547    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19548   "!TARGET_64BIT"
19549   "repz cmpsb"
19550   [(set_attr "type" "str")
19551    (set_attr "mode" "QI")
19552    (set_attr "prefix_rep" "1")])
19553
19554 (define_insn "*cmpstrnqi_rex_1"
19555   [(set (reg:CC FLAGS_REG)
19556         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19557                              (const_int 0))
19558           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19559                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19560           (const_int 0)))
19561    (use (match_operand:SI 3 "immediate_operand" "i"))
19562    (use (reg:CC FLAGS_REG))
19563    (clobber (match_operand:DI 0 "register_operand" "=S"))
19564    (clobber (match_operand:DI 1 "register_operand" "=D"))
19565    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19566   "TARGET_64BIT"
19567   "repz cmpsb"
19568   [(set_attr "type" "str")
19569    (set_attr "mode" "QI")
19570    (set_attr "prefix_rep" "1")])
19571
19572 (define_expand "strlensi"
19573   [(set (match_operand:SI 0 "register_operand" "")
19574         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19575                     (match_operand:QI 2 "immediate_operand" "")
19576                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19577   ""
19578 {
19579  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19580    DONE;
19581  else
19582    FAIL;
19583 })
19584
19585 (define_expand "strlendi"
19586   [(set (match_operand:DI 0 "register_operand" "")
19587         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19588                     (match_operand:QI 2 "immediate_operand" "")
19589                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19590   ""
19591 {
19592  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19593    DONE;
19594  else
19595    FAIL;
19596 })
19597
19598 (define_expand "strlenqi_1"
19599   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19600               (clobber (match_operand 1 "register_operand" ""))
19601               (clobber (reg:CC FLAGS_REG))])]
19602   ""
19603   "ix86_current_function_needs_cld = 1;")
19604
19605 (define_insn "*strlenqi_1"
19606   [(set (match_operand:SI 0 "register_operand" "=&c")
19607         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19608                     (match_operand:QI 2 "register_operand" "a")
19609                     (match_operand:SI 3 "immediate_operand" "i")
19610                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19611    (clobber (match_operand:SI 1 "register_operand" "=D"))
19612    (clobber (reg:CC FLAGS_REG))]
19613   "!TARGET_64BIT"
19614   "repnz scasb"
19615   [(set_attr "type" "str")
19616    (set_attr "mode" "QI")
19617    (set_attr "prefix_rep" "1")])
19618
19619 (define_insn "*strlenqi_rex_1"
19620   [(set (match_operand:DI 0 "register_operand" "=&c")
19621         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19622                     (match_operand:QI 2 "register_operand" "a")
19623                     (match_operand:DI 3 "immediate_operand" "i")
19624                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19625    (clobber (match_operand:DI 1 "register_operand" "=D"))
19626    (clobber (reg:CC FLAGS_REG))]
19627   "TARGET_64BIT"
19628   "repnz scasb"
19629   [(set_attr "type" "str")
19630    (set_attr "mode" "QI")
19631    (set_attr "prefix_rep" "1")])
19632
19633 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19634 ;; handled in combine, but it is not currently up to the task.
19635 ;; When used for their truth value, the cmpstrn* expanders generate
19636 ;; code like this:
19637 ;;
19638 ;;   repz cmpsb
19639 ;;   seta       %al
19640 ;;   setb       %dl
19641 ;;   cmpb       %al, %dl
19642 ;;   jcc        label
19643 ;;
19644 ;; The intermediate three instructions are unnecessary.
19645
19646 ;; This one handles cmpstrn*_nz_1...
19647 (define_peephole2
19648   [(parallel[
19649      (set (reg:CC FLAGS_REG)
19650           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19651                       (mem:BLK (match_operand 5 "register_operand" ""))))
19652      (use (match_operand 6 "register_operand" ""))
19653      (use (match_operand:SI 3 "immediate_operand" ""))
19654      (clobber (match_operand 0 "register_operand" ""))
19655      (clobber (match_operand 1 "register_operand" ""))
19656      (clobber (match_operand 2 "register_operand" ""))])
19657    (set (match_operand:QI 7 "register_operand" "")
19658         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19659    (set (match_operand:QI 8 "register_operand" "")
19660         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19661    (set (reg FLAGS_REG)
19662         (compare (match_dup 7) (match_dup 8)))
19663   ]
19664   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19665   [(parallel[
19666      (set (reg:CC FLAGS_REG)
19667           (compare:CC (mem:BLK (match_dup 4))
19668                       (mem:BLK (match_dup 5))))
19669      (use (match_dup 6))
19670      (use (match_dup 3))
19671      (clobber (match_dup 0))
19672      (clobber (match_dup 1))
19673      (clobber (match_dup 2))])]
19674   "")
19675
19676 ;; ...and this one handles cmpstrn*_1.
19677 (define_peephole2
19678   [(parallel[
19679      (set (reg:CC FLAGS_REG)
19680           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19681                                (const_int 0))
19682             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19683                         (mem:BLK (match_operand 5 "register_operand" "")))
19684             (const_int 0)))
19685      (use (match_operand:SI 3 "immediate_operand" ""))
19686      (use (reg:CC FLAGS_REG))
19687      (clobber (match_operand 0 "register_operand" ""))
19688      (clobber (match_operand 1 "register_operand" ""))
19689      (clobber (match_operand 2 "register_operand" ""))])
19690    (set (match_operand:QI 7 "register_operand" "")
19691         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19692    (set (match_operand:QI 8 "register_operand" "")
19693         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19694    (set (reg FLAGS_REG)
19695         (compare (match_dup 7) (match_dup 8)))
19696   ]
19697   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19698   [(parallel[
19699      (set (reg:CC FLAGS_REG)
19700           (if_then_else:CC (ne (match_dup 6)
19701                                (const_int 0))
19702             (compare:CC (mem:BLK (match_dup 4))
19703                         (mem:BLK (match_dup 5)))
19704             (const_int 0)))
19705      (use (match_dup 3))
19706      (use (reg:CC FLAGS_REG))
19707      (clobber (match_dup 0))
19708      (clobber (match_dup 1))
19709      (clobber (match_dup 2))])]
19710   "")
19711
19712
19713 \f
19714 ;; Conditional move instructions.
19715
19716 (define_expand "movdicc"
19717   [(set (match_operand:DI 0 "register_operand" "")
19718         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19719                          (match_operand:DI 2 "general_operand" "")
19720                          (match_operand:DI 3 "general_operand" "")))]
19721   "TARGET_64BIT"
19722   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19723
19724 (define_insn "x86_movdicc_0_m1_rex64"
19725   [(set (match_operand:DI 0 "register_operand" "=r")
19726         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19727           (const_int -1)
19728           (const_int 0)))
19729    (clobber (reg:CC FLAGS_REG))]
19730   "TARGET_64BIT"
19731   "sbb{q}\t%0, %0"
19732   ; Since we don't have the proper number of operands for an alu insn,
19733   ; fill in all the blanks.
19734   [(set_attr "type" "alu")
19735    (set_attr "pent_pair" "pu")
19736    (set_attr "memory" "none")
19737    (set_attr "imm_disp" "false")
19738    (set_attr "mode" "DI")
19739    (set_attr "length_immediate" "0")])
19740
19741 (define_insn "*x86_movdicc_0_m1_se"
19742   [(set (match_operand:DI 0 "register_operand" "=r")
19743         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19744                          (const_int 1)
19745                          (const_int 0)))
19746    (clobber (reg:CC FLAGS_REG))]
19747   ""
19748   "sbb{q}\t%0, %0"
19749   [(set_attr "type" "alu")
19750    (set_attr "pent_pair" "pu")
19751    (set_attr "memory" "none")
19752    (set_attr "imm_disp" "false")
19753    (set_attr "mode" "DI")
19754    (set_attr "length_immediate" "0")])
19755
19756 (define_insn "*movdicc_c_rex64"
19757   [(set (match_operand:DI 0 "register_operand" "=r,r")
19758         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19759                                 [(reg FLAGS_REG) (const_int 0)])
19760                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19761                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19762   "TARGET_64BIT && TARGET_CMOVE
19763    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19764   "@
19765    cmov%O2%C1\t{%2, %0|%0, %2}
19766    cmov%O2%c1\t{%3, %0|%0, %3}"
19767   [(set_attr "type" "icmov")
19768    (set_attr "mode" "DI")])
19769
19770 (define_expand "movsicc"
19771   [(set (match_operand:SI 0 "register_operand" "")
19772         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19773                          (match_operand:SI 2 "general_operand" "")
19774                          (match_operand:SI 3 "general_operand" "")))]
19775   ""
19776   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19777
19778 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19779 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19780 ;; So just document what we're doing explicitly.
19781
19782 (define_insn "x86_movsicc_0_m1"
19783   [(set (match_operand:SI 0 "register_operand" "=r")
19784         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19785           (const_int -1)
19786           (const_int 0)))
19787    (clobber (reg:CC FLAGS_REG))]
19788   ""
19789   "sbb{l}\t%0, %0"
19790   ; Since we don't have the proper number of operands for an alu insn,
19791   ; fill in all the blanks.
19792   [(set_attr "type" "alu")
19793    (set_attr "pent_pair" "pu")
19794    (set_attr "memory" "none")
19795    (set_attr "imm_disp" "false")
19796    (set_attr "mode" "SI")
19797    (set_attr "length_immediate" "0")])
19798
19799 (define_insn "*x86_movsicc_0_m1_se"
19800   [(set (match_operand:SI 0 "register_operand" "=r")
19801         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19802                          (const_int 1)
19803                          (const_int 0)))
19804    (clobber (reg:CC FLAGS_REG))]
19805   ""
19806   "sbb{l}\t%0, %0"
19807   [(set_attr "type" "alu")
19808    (set_attr "pent_pair" "pu")
19809    (set_attr "memory" "none")
19810    (set_attr "imm_disp" "false")
19811    (set_attr "mode" "SI")
19812    (set_attr "length_immediate" "0")])
19813
19814 (define_insn "*movsicc_noc"
19815   [(set (match_operand:SI 0 "register_operand" "=r,r")
19816         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19817                                 [(reg FLAGS_REG) (const_int 0)])
19818                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19819                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19820   "TARGET_CMOVE
19821    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19822   "@
19823    cmov%O2%C1\t{%2, %0|%0, %2}
19824    cmov%O2%c1\t{%3, %0|%0, %3}"
19825   [(set_attr "type" "icmov")
19826    (set_attr "mode" "SI")])
19827
19828 (define_expand "movhicc"
19829   [(set (match_operand:HI 0 "register_operand" "")
19830         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19831                          (match_operand:HI 2 "general_operand" "")
19832                          (match_operand:HI 3 "general_operand" "")))]
19833   "TARGET_HIMODE_MATH"
19834   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19835
19836 (define_insn "*movhicc_noc"
19837   [(set (match_operand:HI 0 "register_operand" "=r,r")
19838         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19839                                 [(reg FLAGS_REG) (const_int 0)])
19840                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19841                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19842   "TARGET_CMOVE
19843    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19844   "@
19845    cmov%O2%C1\t{%2, %0|%0, %2}
19846    cmov%O2%c1\t{%3, %0|%0, %3}"
19847   [(set_attr "type" "icmov")
19848    (set_attr "mode" "HI")])
19849
19850 (define_expand "movqicc"
19851   [(set (match_operand:QI 0 "register_operand" "")
19852         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19853                          (match_operand:QI 2 "general_operand" "")
19854                          (match_operand:QI 3 "general_operand" "")))]
19855   "TARGET_QIMODE_MATH"
19856   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19857
19858 (define_insn_and_split "*movqicc_noc"
19859   [(set (match_operand:QI 0 "register_operand" "=r,r")
19860         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19861                                 [(match_operand 4 "flags_reg_operand" "")
19862                                  (const_int 0)])
19863                       (match_operand:QI 2 "register_operand" "r,0")
19864                       (match_operand:QI 3 "register_operand" "0,r")))]
19865   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19866   "#"
19867   "&& reload_completed"
19868   [(set (match_dup 0)
19869         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19870                       (match_dup 2)
19871                       (match_dup 3)))]
19872   "operands[0] = gen_lowpart (SImode, operands[0]);
19873    operands[2] = gen_lowpart (SImode, operands[2]);
19874    operands[3] = gen_lowpart (SImode, operands[3]);"
19875   [(set_attr "type" "icmov")
19876    (set_attr "mode" "SI")])
19877
19878 (define_expand "mov<mode>cc"
19879   [(set (match_operand:X87MODEF 0 "register_operand" "")
19880         (if_then_else:X87MODEF
19881           (match_operand 1 "comparison_operator" "")
19882           (match_operand:X87MODEF 2 "register_operand" "")
19883           (match_operand:X87MODEF 3 "register_operand" "")))]
19884   "(TARGET_80387 && TARGET_CMOVE)
19885    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19886   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19887
19888 (define_insn "*movsfcc_1_387"
19889   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19890         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19891                                 [(reg FLAGS_REG) (const_int 0)])
19892                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19893                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19894   "TARGET_80387 && TARGET_CMOVE
19895    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19896   "@
19897    fcmov%F1\t{%2, %0|%0, %2}
19898    fcmov%f1\t{%3, %0|%0, %3}
19899    cmov%O2%C1\t{%2, %0|%0, %2}
19900    cmov%O2%c1\t{%3, %0|%0, %3}"
19901   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19902    (set_attr "mode" "SF,SF,SI,SI")])
19903
19904 (define_insn "*movdfcc_1"
19905   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19906         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19907                                 [(reg FLAGS_REG) (const_int 0)])
19908                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19909                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19910   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19911    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19912   "@
19913    fcmov%F1\t{%2, %0|%0, %2}
19914    fcmov%f1\t{%3, %0|%0, %3}
19915    #
19916    #"
19917   [(set_attr "type" "fcmov,fcmov,multi,multi")
19918    (set_attr "mode" "DF")])
19919
19920 (define_insn "*movdfcc_1_rex64"
19921   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19922         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19923                                 [(reg FLAGS_REG) (const_int 0)])
19924                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19925                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19926   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19927    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19928   "@
19929    fcmov%F1\t{%2, %0|%0, %2}
19930    fcmov%f1\t{%3, %0|%0, %3}
19931    cmov%O2%C1\t{%2, %0|%0, %2}
19932    cmov%O2%c1\t{%3, %0|%0, %3}"
19933   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19934    (set_attr "mode" "DF")])
19935
19936 (define_split
19937   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19938         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19939                                 [(match_operand 4 "flags_reg_operand" "")
19940                                  (const_int 0)])
19941                       (match_operand:DF 2 "nonimmediate_operand" "")
19942                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19943   "!TARGET_64BIT && reload_completed"
19944   [(set (match_dup 2)
19945         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19946                       (match_dup 5)
19947                       (match_dup 6)))
19948    (set (match_dup 3)
19949         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19950                       (match_dup 7)
19951                       (match_dup 8)))]
19952   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19953    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19954
19955 (define_insn "*movxfcc_1"
19956   [(set (match_operand:XF 0 "register_operand" "=f,f")
19957         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19958                                 [(reg FLAGS_REG) (const_int 0)])
19959                       (match_operand:XF 2 "register_operand" "f,0")
19960                       (match_operand:XF 3 "register_operand" "0,f")))]
19961   "TARGET_80387 && TARGET_CMOVE"
19962   "@
19963    fcmov%F1\t{%2, %0|%0, %2}
19964    fcmov%f1\t{%3, %0|%0, %3}"
19965   [(set_attr "type" "fcmov")
19966    (set_attr "mode" "XF")])
19967
19968 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19969 ;; the scalar versions to have only XMM registers as operands.
19970
19971 ;; SSE5 conditional move
19972 (define_insn "*sse5_pcmov_<mode>"
19973   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19974         (if_then_else:MODEF
19975           (match_operand:MODEF 1 "register_operand" "x,0")
19976           (match_operand:MODEF 2 "register_operand" "0,x")
19977           (match_operand:MODEF 3 "register_operand" "x,x")))]
19978   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19979   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19980   [(set_attr "type" "sse4arg")])
19981
19982 ;; These versions of the min/max patterns are intentionally ignorant of
19983 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19984 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19985 ;; are undefined in this condition, we're certain this is correct.
19986
19987 (define_insn "*avx_<code><mode>3"
19988   [(set (match_operand:MODEF 0 "register_operand" "=x")
19989         (smaxmin:MODEF
19990           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19991           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19992   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19993   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19994   [(set_attr "type" "sseadd")
19995    (set_attr "prefix" "vex")
19996    (set_attr "mode" "<MODE>")])
19997
19998 (define_insn "<code><mode>3"
19999   [(set (match_operand:MODEF 0 "register_operand" "=x")
20000         (smaxmin:MODEF
20001           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20002           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20003   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20004   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20005   [(set_attr "type" "sseadd")
20006    (set_attr "mode" "<MODE>")])
20007
20008 ;; These versions of the min/max patterns implement exactly the operations
20009 ;;   min = (op1 < op2 ? op1 : op2)
20010 ;;   max = (!(op1 < op2) ? op1 : op2)
20011 ;; Their operands are not commutative, and thus they may be used in the
20012 ;; presence of -0.0 and NaN.
20013
20014 (define_insn "*avx_ieee_smin<mode>3"
20015   [(set (match_operand:MODEF 0 "register_operand" "=x")
20016         (unspec:MODEF
20017           [(match_operand:MODEF 1 "register_operand" "x")
20018            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20019          UNSPEC_IEEE_MIN))]
20020   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20021   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20022   [(set_attr "type" "sseadd")
20023    (set_attr "prefix" "vex")
20024    (set_attr "mode" "<MODE>")])
20025
20026 (define_insn "*ieee_smin<mode>3"
20027   [(set (match_operand:MODEF 0 "register_operand" "=x")
20028         (unspec:MODEF
20029           [(match_operand:MODEF 1 "register_operand" "0")
20030            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20031          UNSPEC_IEEE_MIN))]
20032   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20033   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20034   [(set_attr "type" "sseadd")
20035    (set_attr "mode" "<MODE>")])
20036
20037 (define_insn "*avx_ieee_smax<mode>3"
20038   [(set (match_operand:MODEF 0 "register_operand" "=x")
20039         (unspec:MODEF
20040           [(match_operand:MODEF 1 "register_operand" "0")
20041            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20042          UNSPEC_IEEE_MAX))]
20043   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20044   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20045   [(set_attr "type" "sseadd")
20046    (set_attr "prefix" "vex")
20047    (set_attr "mode" "<MODE>")])
20048
20049 (define_insn "*ieee_smax<mode>3"
20050   [(set (match_operand:MODEF 0 "register_operand" "=x")
20051         (unspec:MODEF
20052           [(match_operand:MODEF 1 "register_operand" "0")
20053            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20054          UNSPEC_IEEE_MAX))]
20055   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20056   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20057   [(set_attr "type" "sseadd")
20058    (set_attr "mode" "<MODE>")])
20059
20060 ;; Make two stack loads independent:
20061 ;;   fld aa              fld aa
20062 ;;   fld %st(0)     ->   fld bb
20063 ;;   fmul bb             fmul %st(1), %st
20064 ;;
20065 ;; Actually we only match the last two instructions for simplicity.
20066 (define_peephole2
20067   [(set (match_operand 0 "fp_register_operand" "")
20068         (match_operand 1 "fp_register_operand" ""))
20069    (set (match_dup 0)
20070         (match_operator 2 "binary_fp_operator"
20071            [(match_dup 0)
20072             (match_operand 3 "memory_operand" "")]))]
20073   "REGNO (operands[0]) != REGNO (operands[1])"
20074   [(set (match_dup 0) (match_dup 3))
20075    (set (match_dup 0) (match_dup 4))]
20076
20077   ;; The % modifier is not operational anymore in peephole2's, so we have to
20078   ;; swap the operands manually in the case of addition and multiplication.
20079   "if (COMMUTATIVE_ARITH_P (operands[2]))
20080      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20081                                  operands[0], operands[1]);
20082    else
20083      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20084                                  operands[1], operands[0]);")
20085
20086 ;; Conditional addition patterns
20087 (define_expand "add<mode>cc"
20088   [(match_operand:SWI 0 "register_operand" "")
20089    (match_operand 1 "comparison_operator" "")
20090    (match_operand:SWI 2 "register_operand" "")
20091    (match_operand:SWI 3 "const_int_operand" "")]
20092   ""
20093   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20094
20095 \f
20096 ;; Misc patterns (?)
20097
20098 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20099 ;; Otherwise there will be nothing to keep
20100 ;;
20101 ;; [(set (reg ebp) (reg esp))]
20102 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20103 ;;  (clobber (eflags)]
20104 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20105 ;;
20106 ;; in proper program order.
20107 (define_insn "pro_epilogue_adjust_stack_1"
20108   [(set (match_operand:SI 0 "register_operand" "=r,r")
20109         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20110                  (match_operand:SI 2 "immediate_operand" "i,i")))
20111    (clobber (reg:CC FLAGS_REG))
20112    (clobber (mem:BLK (scratch)))]
20113   "!TARGET_64BIT"
20114 {
20115   switch (get_attr_type (insn))
20116     {
20117     case TYPE_IMOV:
20118       return "mov{l}\t{%1, %0|%0, %1}";
20119
20120     case TYPE_ALU:
20121       if (CONST_INT_P (operands[2])
20122           && (INTVAL (operands[2]) == 128
20123               || (INTVAL (operands[2]) < 0
20124                   && INTVAL (operands[2]) != -128)))
20125         {
20126           operands[2] = GEN_INT (-INTVAL (operands[2]));
20127           return "sub{l}\t{%2, %0|%0, %2}";
20128         }
20129       return "add{l}\t{%2, %0|%0, %2}";
20130
20131     case TYPE_LEA:
20132       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20133       return "lea{l}\t{%a2, %0|%0, %a2}";
20134
20135     default:
20136       gcc_unreachable ();
20137     }
20138 }
20139   [(set (attr "type")
20140         (cond [(eq_attr "alternative" "0")
20141                  (const_string "alu")
20142                (match_operand:SI 2 "const0_operand" "")
20143                  (const_string "imov")
20144               ]
20145               (const_string "lea")))
20146    (set_attr "mode" "SI")])
20147
20148 (define_insn "pro_epilogue_adjust_stack_rex64"
20149   [(set (match_operand:DI 0 "register_operand" "=r,r")
20150         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20151                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20152    (clobber (reg:CC FLAGS_REG))
20153    (clobber (mem:BLK (scratch)))]
20154   "TARGET_64BIT"
20155 {
20156   switch (get_attr_type (insn))
20157     {
20158     case TYPE_IMOV:
20159       return "mov{q}\t{%1, %0|%0, %1}";
20160
20161     case TYPE_ALU:
20162       if (CONST_INT_P (operands[2])
20163           /* Avoid overflows.  */
20164           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20165           && (INTVAL (operands[2]) == 128
20166               || (INTVAL (operands[2]) < 0
20167                   && INTVAL (operands[2]) != -128)))
20168         {
20169           operands[2] = GEN_INT (-INTVAL (operands[2]));
20170           return "sub{q}\t{%2, %0|%0, %2}";
20171         }
20172       return "add{q}\t{%2, %0|%0, %2}";
20173
20174     case TYPE_LEA:
20175       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20176       return "lea{q}\t{%a2, %0|%0, %a2}";
20177
20178     default:
20179       gcc_unreachable ();
20180     }
20181 }
20182   [(set (attr "type")
20183         (cond [(eq_attr "alternative" "0")
20184                  (const_string "alu")
20185                (match_operand:DI 2 "const0_operand" "")
20186                  (const_string "imov")
20187               ]
20188               (const_string "lea")))
20189    (set_attr "mode" "DI")])
20190
20191 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20192   [(set (match_operand:DI 0 "register_operand" "=r,r")
20193         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20194                  (match_operand:DI 3 "immediate_operand" "i,i")))
20195    (use (match_operand:DI 2 "register_operand" "r,r"))
20196    (clobber (reg:CC FLAGS_REG))
20197    (clobber (mem:BLK (scratch)))]
20198   "TARGET_64BIT"
20199 {
20200   switch (get_attr_type (insn))
20201     {
20202     case TYPE_ALU:
20203       return "add{q}\t{%2, %0|%0, %2}";
20204
20205     case TYPE_LEA:
20206       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20207       return "lea{q}\t{%a2, %0|%0, %a2}";
20208
20209     default:
20210       gcc_unreachable ();
20211     }
20212 }
20213   [(set_attr "type" "alu,lea")
20214    (set_attr "mode" "DI")])
20215
20216 (define_insn "allocate_stack_worker_32"
20217   [(set (match_operand:SI 0 "register_operand" "=a")
20218         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20219                             UNSPECV_STACK_PROBE))
20220    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20221    (clobber (reg:CC FLAGS_REG))]
20222   "!TARGET_64BIT && TARGET_STACK_PROBE"
20223   "call\t___chkstk"
20224   [(set_attr "type" "multi")
20225    (set_attr "length" "5")])
20226
20227 (define_insn "allocate_stack_worker_64"
20228   [(set (match_operand:DI 0 "register_operand" "=a")
20229         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20230                             UNSPECV_STACK_PROBE))
20231    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20232    (clobber (reg:DI R10_REG))
20233    (clobber (reg:DI R11_REG))
20234    (clobber (reg:CC FLAGS_REG))]
20235   "TARGET_64BIT && TARGET_STACK_PROBE"
20236   "call\t___chkstk"
20237   [(set_attr "type" "multi")
20238    (set_attr "length" "5")])
20239
20240 (define_expand "allocate_stack"
20241   [(match_operand 0 "register_operand" "")
20242    (match_operand 1 "general_operand" "")]
20243   "TARGET_STACK_PROBE"
20244 {
20245   rtx x;
20246
20247 #ifndef CHECK_STACK_LIMIT
20248 #define CHECK_STACK_LIMIT 0
20249 #endif
20250
20251   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20252       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20253     {
20254       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20255                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20256       if (x != stack_pointer_rtx)
20257         emit_move_insn (stack_pointer_rtx, x);
20258     }
20259   else
20260     {
20261       x = copy_to_mode_reg (Pmode, operands[1]);
20262       if (TARGET_64BIT)
20263         x = gen_allocate_stack_worker_64 (x, x);
20264       else
20265         x = gen_allocate_stack_worker_32 (x, x);
20266       emit_insn (x);
20267     }
20268
20269   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20270   DONE;
20271 })
20272
20273 (define_expand "builtin_setjmp_receiver"
20274   [(label_ref (match_operand 0 "" ""))]
20275   "!TARGET_64BIT && flag_pic"
20276 {
20277 #if TARGET_MACHO
20278   if (TARGET_MACHO)
20279     {
20280       rtx xops[3];
20281       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20282       rtx label_rtx = gen_label_rtx ();
20283       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20284       xops[0] = xops[1] = picreg;
20285       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20286       ix86_expand_binary_operator (MINUS, SImode, xops);
20287     }
20288   else
20289 #endif
20290     emit_insn (gen_set_got (pic_offset_table_rtx));
20291   DONE;
20292 })
20293 \f
20294 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20295
20296 (define_split
20297   [(set (match_operand 0 "register_operand" "")
20298         (match_operator 3 "promotable_binary_operator"
20299            [(match_operand 1 "register_operand" "")
20300             (match_operand 2 "aligned_operand" "")]))
20301    (clobber (reg:CC FLAGS_REG))]
20302   "! TARGET_PARTIAL_REG_STALL && reload_completed
20303    && ((GET_MODE (operands[0]) == HImode
20304         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20305             /* ??? next two lines just !satisfies_constraint_K (...) */
20306             || !CONST_INT_P (operands[2])
20307             || satisfies_constraint_K (operands[2])))
20308        || (GET_MODE (operands[0]) == QImode
20309            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20310   [(parallel [(set (match_dup 0)
20311                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20312               (clobber (reg:CC FLAGS_REG))])]
20313   "operands[0] = gen_lowpart (SImode, operands[0]);
20314    operands[1] = gen_lowpart (SImode, operands[1]);
20315    if (GET_CODE (operands[3]) != ASHIFT)
20316      operands[2] = gen_lowpart (SImode, operands[2]);
20317    PUT_MODE (operands[3], SImode);")
20318
20319 ; Promote the QImode tests, as i386 has encoding of the AND
20320 ; instruction with 32-bit sign-extended immediate and thus the
20321 ; instruction size is unchanged, except in the %eax case for
20322 ; which it is increased by one byte, hence the ! optimize_size.
20323 (define_split
20324   [(set (match_operand 0 "flags_reg_operand" "")
20325         (match_operator 2 "compare_operator"
20326           [(and (match_operand 3 "aligned_operand" "")
20327                 (match_operand 4 "const_int_operand" ""))
20328            (const_int 0)]))
20329    (set (match_operand 1 "register_operand" "")
20330         (and (match_dup 3) (match_dup 4)))]
20331   "! TARGET_PARTIAL_REG_STALL && reload_completed
20332    && optimize_insn_for_speed_p ()
20333    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20334        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20335    /* Ensure that the operand will remain sign-extended immediate.  */
20336    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20337   [(parallel [(set (match_dup 0)
20338                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20339                                     (const_int 0)]))
20340               (set (match_dup 1)
20341                    (and:SI (match_dup 3) (match_dup 4)))])]
20342 {
20343   operands[4]
20344     = gen_int_mode (INTVAL (operands[4])
20345                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20346   operands[1] = gen_lowpart (SImode, operands[1]);
20347   operands[3] = gen_lowpart (SImode, operands[3]);
20348 })
20349
20350 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20351 ; the TEST instruction with 32-bit sign-extended immediate and thus
20352 ; the instruction size would at least double, which is not what we
20353 ; want even with ! optimize_size.
20354 (define_split
20355   [(set (match_operand 0 "flags_reg_operand" "")
20356         (match_operator 1 "compare_operator"
20357           [(and (match_operand:HI 2 "aligned_operand" "")
20358                 (match_operand:HI 3 "const_int_operand" ""))
20359            (const_int 0)]))]
20360   "! TARGET_PARTIAL_REG_STALL && reload_completed
20361    && ! TARGET_FAST_PREFIX
20362    && optimize_insn_for_speed_p ()
20363    /* Ensure that the operand will remain sign-extended immediate.  */
20364    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20365   [(set (match_dup 0)
20366         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20367                          (const_int 0)]))]
20368 {
20369   operands[3]
20370     = gen_int_mode (INTVAL (operands[3])
20371                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20372   operands[2] = gen_lowpart (SImode, operands[2]);
20373 })
20374
20375 (define_split
20376   [(set (match_operand 0 "register_operand" "")
20377         (neg (match_operand 1 "register_operand" "")))
20378    (clobber (reg:CC FLAGS_REG))]
20379   "! TARGET_PARTIAL_REG_STALL && reload_completed
20380    && (GET_MODE (operands[0]) == HImode
20381        || (GET_MODE (operands[0]) == QImode
20382            && (TARGET_PROMOTE_QImode
20383                || optimize_insn_for_size_p ())))"
20384   [(parallel [(set (match_dup 0)
20385                    (neg:SI (match_dup 1)))
20386               (clobber (reg:CC FLAGS_REG))])]
20387   "operands[0] = gen_lowpart (SImode, operands[0]);
20388    operands[1] = gen_lowpart (SImode, operands[1]);")
20389
20390 (define_split
20391   [(set (match_operand 0 "register_operand" "")
20392         (not (match_operand 1 "register_operand" "")))]
20393   "! TARGET_PARTIAL_REG_STALL && reload_completed
20394    && (GET_MODE (operands[0]) == HImode
20395        || (GET_MODE (operands[0]) == QImode
20396            && (TARGET_PROMOTE_QImode
20397                || optimize_insn_for_size_p ())))"
20398   [(set (match_dup 0)
20399         (not:SI (match_dup 1)))]
20400   "operands[0] = gen_lowpart (SImode, operands[0]);
20401    operands[1] = gen_lowpart (SImode, operands[1]);")
20402
20403 (define_split
20404   [(set (match_operand 0 "register_operand" "")
20405         (if_then_else (match_operator 1 "comparison_operator"
20406                                 [(reg FLAGS_REG) (const_int 0)])
20407                       (match_operand 2 "register_operand" "")
20408                       (match_operand 3 "register_operand" "")))]
20409   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20410    && (GET_MODE (operands[0]) == HImode
20411        || (GET_MODE (operands[0]) == QImode
20412            && (TARGET_PROMOTE_QImode
20413                || optimize_insn_for_size_p ())))"
20414   [(set (match_dup 0)
20415         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20416   "operands[0] = gen_lowpart (SImode, operands[0]);
20417    operands[2] = gen_lowpart (SImode, operands[2]);
20418    operands[3] = gen_lowpart (SImode, operands[3]);")
20419
20420 \f
20421 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20422 ;; transform a complex memory operation into two memory to register operations.
20423
20424 ;; Don't push memory operands
20425 (define_peephole2
20426   [(set (match_operand:SI 0 "push_operand" "")
20427         (match_operand:SI 1 "memory_operand" ""))
20428    (match_scratch:SI 2 "r")]
20429   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20430    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20431   [(set (match_dup 2) (match_dup 1))
20432    (set (match_dup 0) (match_dup 2))]
20433   "")
20434
20435 (define_peephole2
20436   [(set (match_operand:DI 0 "push_operand" "")
20437         (match_operand:DI 1 "memory_operand" ""))
20438    (match_scratch:DI 2 "r")]
20439   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20440    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20441   [(set (match_dup 2) (match_dup 1))
20442    (set (match_dup 0) (match_dup 2))]
20443   "")
20444
20445 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20446 ;; SImode pushes.
20447 (define_peephole2
20448   [(set (match_operand:SF 0 "push_operand" "")
20449         (match_operand:SF 1 "memory_operand" ""))
20450    (match_scratch:SF 2 "r")]
20451   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20452    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20453   [(set (match_dup 2) (match_dup 1))
20454    (set (match_dup 0) (match_dup 2))]
20455   "")
20456
20457 (define_peephole2
20458   [(set (match_operand:HI 0 "push_operand" "")
20459         (match_operand:HI 1 "memory_operand" ""))
20460    (match_scratch:HI 2 "r")]
20461   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20462    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20463   [(set (match_dup 2) (match_dup 1))
20464    (set (match_dup 0) (match_dup 2))]
20465   "")
20466
20467 (define_peephole2
20468   [(set (match_operand:QI 0 "push_operand" "")
20469         (match_operand:QI 1 "memory_operand" ""))
20470    (match_scratch:QI 2 "q")]
20471   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20472    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20473   [(set (match_dup 2) (match_dup 1))
20474    (set (match_dup 0) (match_dup 2))]
20475   "")
20476
20477 ;; Don't move an immediate directly to memory when the instruction
20478 ;; gets too big.
20479 (define_peephole2
20480   [(match_scratch:SI 1 "r")
20481    (set (match_operand:SI 0 "memory_operand" "")
20482         (const_int 0))]
20483   "optimize_insn_for_speed_p ()
20484    && ! TARGET_USE_MOV0
20485    && TARGET_SPLIT_LONG_MOVES
20486    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20487    && peep2_regno_dead_p (0, FLAGS_REG)"
20488   [(parallel [(set (match_dup 1) (const_int 0))
20489               (clobber (reg:CC FLAGS_REG))])
20490    (set (match_dup 0) (match_dup 1))]
20491   "")
20492
20493 (define_peephole2
20494   [(match_scratch:HI 1 "r")
20495    (set (match_operand:HI 0 "memory_operand" "")
20496         (const_int 0))]
20497   "optimize_insn_for_speed_p ()
20498    && ! TARGET_USE_MOV0
20499    && TARGET_SPLIT_LONG_MOVES
20500    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20501    && peep2_regno_dead_p (0, FLAGS_REG)"
20502   [(parallel [(set (match_dup 2) (const_int 0))
20503               (clobber (reg:CC FLAGS_REG))])
20504    (set (match_dup 0) (match_dup 1))]
20505   "operands[2] = gen_lowpart (SImode, operands[1]);")
20506
20507 (define_peephole2
20508   [(match_scratch:QI 1 "q")
20509    (set (match_operand:QI 0 "memory_operand" "")
20510         (const_int 0))]
20511   "optimize_insn_for_speed_p ()
20512    && ! TARGET_USE_MOV0
20513    && TARGET_SPLIT_LONG_MOVES
20514    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20515    && peep2_regno_dead_p (0, FLAGS_REG)"
20516   [(parallel [(set (match_dup 2) (const_int 0))
20517               (clobber (reg:CC FLAGS_REG))])
20518    (set (match_dup 0) (match_dup 1))]
20519   "operands[2] = gen_lowpart (SImode, operands[1]);")
20520
20521 (define_peephole2
20522   [(match_scratch:SI 2 "r")
20523    (set (match_operand:SI 0 "memory_operand" "")
20524         (match_operand:SI 1 "immediate_operand" ""))]
20525   "optimize_insn_for_speed_p ()
20526    && TARGET_SPLIT_LONG_MOVES
20527    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20528   [(set (match_dup 2) (match_dup 1))
20529    (set (match_dup 0) (match_dup 2))]
20530   "")
20531
20532 (define_peephole2
20533   [(match_scratch:HI 2 "r")
20534    (set (match_operand:HI 0 "memory_operand" "")
20535         (match_operand:HI 1 "immediate_operand" ""))]
20536   "optimize_insn_for_speed_p ()
20537    && TARGET_SPLIT_LONG_MOVES
20538    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20539   [(set (match_dup 2) (match_dup 1))
20540    (set (match_dup 0) (match_dup 2))]
20541   "")
20542
20543 (define_peephole2
20544   [(match_scratch:QI 2 "q")
20545    (set (match_operand:QI 0 "memory_operand" "")
20546         (match_operand:QI 1 "immediate_operand" ""))]
20547   "optimize_insn_for_speed_p ()
20548    && TARGET_SPLIT_LONG_MOVES
20549    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20550   [(set (match_dup 2) (match_dup 1))
20551    (set (match_dup 0) (match_dup 2))]
20552   "")
20553
20554 ;; Don't compare memory with zero, load and use a test instead.
20555 (define_peephole2
20556   [(set (match_operand 0 "flags_reg_operand" "")
20557         (match_operator 1 "compare_operator"
20558           [(match_operand:SI 2 "memory_operand" "")
20559            (const_int 0)]))
20560    (match_scratch:SI 3 "r")]
20561   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20562   [(set (match_dup 3) (match_dup 2))
20563    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20564   "")
20565
20566 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20567 ;; Don't split NOTs with a displacement operand, because resulting XOR
20568 ;; will not be pairable anyway.
20569 ;;
20570 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20571 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20572 ;; so this split helps here as well.
20573 ;;
20574 ;; Note: Can't do this as a regular split because we can't get proper
20575 ;; lifetime information then.
20576
20577 (define_peephole2
20578   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20579         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20580   "optimize_insn_for_speed_p ()
20581    && ((TARGET_NOT_UNPAIRABLE
20582         && (!MEM_P (operands[0])
20583             || !memory_displacement_operand (operands[0], SImode)))
20584        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20585    && peep2_regno_dead_p (0, FLAGS_REG)"
20586   [(parallel [(set (match_dup 0)
20587                    (xor:SI (match_dup 1) (const_int -1)))
20588               (clobber (reg:CC FLAGS_REG))])]
20589   "")
20590
20591 (define_peephole2
20592   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20593         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20594   "optimize_insn_for_speed_p ()
20595    && ((TARGET_NOT_UNPAIRABLE
20596         && (!MEM_P (operands[0])
20597             || !memory_displacement_operand (operands[0], HImode)))
20598        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20599    && peep2_regno_dead_p (0, FLAGS_REG)"
20600   [(parallel [(set (match_dup 0)
20601                    (xor:HI (match_dup 1) (const_int -1)))
20602               (clobber (reg:CC FLAGS_REG))])]
20603   "")
20604
20605 (define_peephole2
20606   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20607         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20608   "optimize_insn_for_speed_p ()
20609    && ((TARGET_NOT_UNPAIRABLE
20610         && (!MEM_P (operands[0])
20611             || !memory_displacement_operand (operands[0], QImode)))
20612        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20613    && peep2_regno_dead_p (0, FLAGS_REG)"
20614   [(parallel [(set (match_dup 0)
20615                    (xor:QI (match_dup 1) (const_int -1)))
20616               (clobber (reg:CC FLAGS_REG))])]
20617   "")
20618
20619 ;; Non pairable "test imm, reg" instructions can be translated to
20620 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20621 ;; byte opcode instead of two, have a short form for byte operands),
20622 ;; so do it for other CPUs as well.  Given that the value was dead,
20623 ;; this should not create any new dependencies.  Pass on the sub-word
20624 ;; versions if we're concerned about partial register stalls.
20625
20626 (define_peephole2
20627   [(set (match_operand 0 "flags_reg_operand" "")
20628         (match_operator 1 "compare_operator"
20629           [(and:SI (match_operand:SI 2 "register_operand" "")
20630                    (match_operand:SI 3 "immediate_operand" ""))
20631            (const_int 0)]))]
20632   "ix86_match_ccmode (insn, CCNOmode)
20633    && (true_regnum (operands[2]) != AX_REG
20634        || satisfies_constraint_K (operands[3]))
20635    && peep2_reg_dead_p (1, operands[2])"
20636   [(parallel
20637      [(set (match_dup 0)
20638            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20639                             (const_int 0)]))
20640       (set (match_dup 2)
20641            (and:SI (match_dup 2) (match_dup 3)))])]
20642   "")
20643
20644 ;; We don't need to handle HImode case, because it will be promoted to SImode
20645 ;; on ! TARGET_PARTIAL_REG_STALL
20646
20647 (define_peephole2
20648   [(set (match_operand 0 "flags_reg_operand" "")
20649         (match_operator 1 "compare_operator"
20650           [(and:QI (match_operand:QI 2 "register_operand" "")
20651                    (match_operand:QI 3 "immediate_operand" ""))
20652            (const_int 0)]))]
20653   "! TARGET_PARTIAL_REG_STALL
20654    && ix86_match_ccmode (insn, CCNOmode)
20655    && true_regnum (operands[2]) != AX_REG
20656    && peep2_reg_dead_p (1, operands[2])"
20657   [(parallel
20658      [(set (match_dup 0)
20659            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20660                             (const_int 0)]))
20661       (set (match_dup 2)
20662            (and:QI (match_dup 2) (match_dup 3)))])]
20663   "")
20664
20665 (define_peephole2
20666   [(set (match_operand 0 "flags_reg_operand" "")
20667         (match_operator 1 "compare_operator"
20668           [(and:SI
20669              (zero_extract:SI
20670                (match_operand 2 "ext_register_operand" "")
20671                (const_int 8)
20672                (const_int 8))
20673              (match_operand 3 "const_int_operand" ""))
20674            (const_int 0)]))]
20675   "! TARGET_PARTIAL_REG_STALL
20676    && ix86_match_ccmode (insn, CCNOmode)
20677    && true_regnum (operands[2]) != AX_REG
20678    && peep2_reg_dead_p (1, operands[2])"
20679   [(parallel [(set (match_dup 0)
20680                    (match_op_dup 1
20681                      [(and:SI
20682                         (zero_extract:SI
20683                           (match_dup 2)
20684                           (const_int 8)
20685                           (const_int 8))
20686                         (match_dup 3))
20687                       (const_int 0)]))
20688               (set (zero_extract:SI (match_dup 2)
20689                                     (const_int 8)
20690                                     (const_int 8))
20691                    (and:SI
20692                      (zero_extract:SI
20693                        (match_dup 2)
20694                        (const_int 8)
20695                        (const_int 8))
20696                      (match_dup 3)))])]
20697   "")
20698
20699 ;; Don't do logical operations with memory inputs.
20700 (define_peephole2
20701   [(match_scratch:SI 2 "r")
20702    (parallel [(set (match_operand:SI 0 "register_operand" "")
20703                    (match_operator:SI 3 "arith_or_logical_operator"
20704                      [(match_dup 0)
20705                       (match_operand:SI 1 "memory_operand" "")]))
20706               (clobber (reg:CC FLAGS_REG))])]
20707   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20708   [(set (match_dup 2) (match_dup 1))
20709    (parallel [(set (match_dup 0)
20710                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20711               (clobber (reg:CC FLAGS_REG))])]
20712   "")
20713
20714 (define_peephole2
20715   [(match_scratch:SI 2 "r")
20716    (parallel [(set (match_operand:SI 0 "register_operand" "")
20717                    (match_operator:SI 3 "arith_or_logical_operator"
20718                      [(match_operand:SI 1 "memory_operand" "")
20719                       (match_dup 0)]))
20720               (clobber (reg:CC FLAGS_REG))])]
20721   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20722   [(set (match_dup 2) (match_dup 1))
20723    (parallel [(set (match_dup 0)
20724                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20725               (clobber (reg:CC FLAGS_REG))])]
20726   "")
20727
20728 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20729 ;; refers to the destination of the load!
20730
20731 (define_peephole2
20732   [(set (match_operand:SI 0 "register_operand" "")
20733         (match_operand:SI 1 "register_operand" ""))
20734    (parallel [(set (match_dup 0)
20735                    (match_operator:SI 3 "commutative_operator"
20736                      [(match_dup 0)
20737                       (match_operand:SI 2 "memory_operand" "")]))
20738               (clobber (reg:CC FLAGS_REG))])]
20739   "operands[0] != operands[1]
20740    && GENERAL_REGNO_P (REGNO (operands[0]))
20741    && GENERAL_REGNO_P (REGNO (operands[1]))"
20742   [(set (match_dup 0) (match_dup 4))
20743    (parallel [(set (match_dup 0)
20744                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20745               (clobber (reg:CC FLAGS_REG))])]
20746   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20747
20748 (define_peephole2
20749   [(set (match_operand 0 "register_operand" "")
20750         (match_operand 1 "register_operand" ""))
20751    (set (match_dup 0)
20752                    (match_operator 3 "commutative_operator"
20753                      [(match_dup 0)
20754                       (match_operand 2 "memory_operand" "")]))]
20755   "operands[0] != operands[1]
20756    && (MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
20757   [(set (match_dup 0) (match_dup 2))
20758    (set (match_dup 0)
20759         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20760   "")
20761
20762 ; Don't do logical operations with memory outputs
20763 ;
20764 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20765 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20766 ; the same decoder scheduling characteristics as the original.
20767
20768 (define_peephole2
20769   [(match_scratch:SI 2 "r")
20770    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20771                    (match_operator:SI 3 "arith_or_logical_operator"
20772                      [(match_dup 0)
20773                       (match_operand:SI 1 "nonmemory_operand" "")]))
20774               (clobber (reg:CC FLAGS_REG))])]
20775   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20776   [(set (match_dup 2) (match_dup 0))
20777    (parallel [(set (match_dup 2)
20778                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20779               (clobber (reg:CC FLAGS_REG))])
20780    (set (match_dup 0) (match_dup 2))]
20781   "")
20782
20783 (define_peephole2
20784   [(match_scratch:SI 2 "r")
20785    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20786                    (match_operator:SI 3 "arith_or_logical_operator"
20787                      [(match_operand:SI 1 "nonmemory_operand" "")
20788                       (match_dup 0)]))
20789               (clobber (reg:CC FLAGS_REG))])]
20790   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20791   [(set (match_dup 2) (match_dup 0))
20792    (parallel [(set (match_dup 2)
20793                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20794               (clobber (reg:CC FLAGS_REG))])
20795    (set (match_dup 0) (match_dup 2))]
20796   "")
20797
20798 ;; Attempt to always use XOR for zeroing registers.
20799 (define_peephole2
20800   [(set (match_operand 0 "register_operand" "")
20801         (match_operand 1 "const0_operand" ""))]
20802   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20803    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20804    && GENERAL_REG_P (operands[0])
20805    && peep2_regno_dead_p (0, FLAGS_REG)"
20806   [(parallel [(set (match_dup 0) (const_int 0))
20807               (clobber (reg:CC FLAGS_REG))])]
20808 {
20809   operands[0] = gen_lowpart (word_mode, operands[0]);
20810 })
20811
20812 (define_peephole2
20813   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20814         (const_int 0))]
20815   "(GET_MODE (operands[0]) == QImode
20816     || GET_MODE (operands[0]) == HImode)
20817    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20818    && peep2_regno_dead_p (0, FLAGS_REG)"
20819   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20820               (clobber (reg:CC FLAGS_REG))])])
20821
20822 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20823 (define_peephole2
20824   [(set (match_operand 0 "register_operand" "")
20825         (const_int -1))]
20826   "(GET_MODE (operands[0]) == HImode
20827     || GET_MODE (operands[0]) == SImode
20828     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20829    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20830    && peep2_regno_dead_p (0, FLAGS_REG)"
20831   [(parallel [(set (match_dup 0) (const_int -1))
20832               (clobber (reg:CC FLAGS_REG))])]
20833   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20834                               operands[0]);")
20835
20836 ;; Attempt to convert simple leas to adds. These can be created by
20837 ;; move expanders.
20838 (define_peephole2
20839   [(set (match_operand:SI 0 "register_operand" "")
20840         (plus:SI (match_dup 0)
20841                  (match_operand:SI 1 "nonmemory_operand" "")))]
20842   "peep2_regno_dead_p (0, FLAGS_REG)"
20843   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20844               (clobber (reg:CC FLAGS_REG))])]
20845   "")
20846
20847 (define_peephole2
20848   [(set (match_operand:SI 0 "register_operand" "")
20849         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20850                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20851   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20852   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20853               (clobber (reg:CC FLAGS_REG))])]
20854   "operands[2] = gen_lowpart (SImode, operands[2]);")
20855
20856 (define_peephole2
20857   [(set (match_operand:DI 0 "register_operand" "")
20858         (plus:DI (match_dup 0)
20859                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20860   "peep2_regno_dead_p (0, FLAGS_REG)"
20861   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20862               (clobber (reg:CC FLAGS_REG))])]
20863   "")
20864
20865 (define_peephole2
20866   [(set (match_operand:SI 0 "register_operand" "")
20867         (mult:SI (match_dup 0)
20868                  (match_operand:SI 1 "const_int_operand" "")))]
20869   "exact_log2 (INTVAL (operands[1])) >= 0
20870    && peep2_regno_dead_p (0, FLAGS_REG)"
20871   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20872               (clobber (reg:CC FLAGS_REG))])]
20873   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20874
20875 (define_peephole2
20876   [(set (match_operand:DI 0 "register_operand" "")
20877         (mult:DI (match_dup 0)
20878                  (match_operand:DI 1 "const_int_operand" "")))]
20879   "exact_log2 (INTVAL (operands[1])) >= 0
20880    && peep2_regno_dead_p (0, FLAGS_REG)"
20881   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20882               (clobber (reg:CC FLAGS_REG))])]
20883   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20884
20885 (define_peephole2
20886   [(set (match_operand:SI 0 "register_operand" "")
20887         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20888                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20889   "exact_log2 (INTVAL (operands[2])) >= 0
20890    && REGNO (operands[0]) == REGNO (operands[1])
20891    && peep2_regno_dead_p (0, FLAGS_REG)"
20892   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20893               (clobber (reg:CC FLAGS_REG))])]
20894   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20895
20896 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20897 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20898 ;; many CPUs it is also faster, since special hardware to avoid esp
20899 ;; dependencies is present.
20900
20901 ;; While some of these conversions may be done using splitters, we use peepholes
20902 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20903
20904 ;; Convert prologue esp subtractions to push.
20905 ;; We need register to push.  In order to keep verify_flow_info happy we have
20906 ;; two choices
20907 ;; - use scratch and clobber it in order to avoid dependencies
20908 ;; - use already live register
20909 ;; We can't use the second way right now, since there is no reliable way how to
20910 ;; verify that given register is live.  First choice will also most likely in
20911 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20912 ;; call clobbered registers are dead.  We may want to use base pointer as an
20913 ;; alternative when no register is available later.
20914
20915 (define_peephole2
20916   [(match_scratch:SI 0 "r")
20917    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20918               (clobber (reg:CC FLAGS_REG))
20919               (clobber (mem:BLK (scratch)))])]
20920   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20921   [(clobber (match_dup 0))
20922    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20923               (clobber (mem:BLK (scratch)))])])
20924
20925 (define_peephole2
20926   [(match_scratch:SI 0 "r")
20927    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20928               (clobber (reg:CC FLAGS_REG))
20929               (clobber (mem:BLK (scratch)))])]
20930   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20931   [(clobber (match_dup 0))
20932    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20933    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20934               (clobber (mem:BLK (scratch)))])])
20935
20936 ;; Convert esp subtractions to push.
20937 (define_peephole2
20938   [(match_scratch:SI 0 "r")
20939    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20940               (clobber (reg:CC FLAGS_REG))])]
20941   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20942   [(clobber (match_dup 0))
20943    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20944
20945 (define_peephole2
20946   [(match_scratch:SI 0 "r")
20947    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20948               (clobber (reg:CC FLAGS_REG))])]
20949   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20950   [(clobber (match_dup 0))
20951    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20952    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20953
20954 ;; Convert epilogue deallocator to pop.
20955 (define_peephole2
20956   [(match_scratch:SI 0 "r")
20957    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20958               (clobber (reg:CC FLAGS_REG))
20959               (clobber (mem:BLK (scratch)))])]
20960   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_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               (clobber (mem:BLK (scratch)))])]
20964   "")
20965
20966 ;; Two pops case is tricky, since pop causes dependency on destination register.
20967 ;; We use two registers if available.
20968 (define_peephole2
20969   [(match_scratch:SI 0 "r")
20970    (match_scratch:SI 1 "r")
20971    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20972               (clobber (reg:CC FLAGS_REG))
20973               (clobber (mem:BLK (scratch)))])]
20974   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20975   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20976               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20977               (clobber (mem:BLK (scratch)))])
20978    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20979               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20980   "")
20981
20982 (define_peephole2
20983   [(match_scratch:SI 0 "r")
20984    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20985               (clobber (reg:CC FLAGS_REG))
20986               (clobber (mem:BLK (scratch)))])]
20987   "optimize_insn_for_size_p ()"
20988   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20989               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20990               (clobber (mem:BLK (scratch)))])
20991    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20992               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20993   "")
20994
20995 ;; Convert esp additions to pop.
20996 (define_peephole2
20997   [(match_scratch:SI 0 "r")
20998    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20999               (clobber (reg:CC FLAGS_REG))])]
21000   ""
21001   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21002               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21003   "")
21004
21005 ;; Two pops case is tricky, since pop causes dependency on destination register.
21006 ;; We use two registers if available.
21007 (define_peephole2
21008   [(match_scratch:SI 0 "r")
21009    (match_scratch:SI 1 "r")
21010    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21011               (clobber (reg:CC FLAGS_REG))])]
21012   ""
21013   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21014               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21015    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21016               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21017   "")
21018
21019 (define_peephole2
21020   [(match_scratch:SI 0 "r")
21021    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21022               (clobber (reg:CC FLAGS_REG))])]
21023   "optimize_insn_for_size_p ()"
21024   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21025               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21026    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21027               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21028   "")
21029 \f
21030 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21031 ;; required and register dies.  Similarly for 128 to -128.
21032 (define_peephole2
21033   [(set (match_operand 0 "flags_reg_operand" "")
21034         (match_operator 1 "compare_operator"
21035           [(match_operand 2 "register_operand" "")
21036            (match_operand 3 "const_int_operand" "")]))]
21037   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21038      && incdec_operand (operands[3], GET_MODE (operands[3])))
21039     || (!TARGET_FUSE_CMP_AND_BRANCH
21040         && INTVAL (operands[3]) == 128))
21041    && ix86_match_ccmode (insn, CCGCmode)
21042    && peep2_reg_dead_p (1, operands[2])"
21043   [(parallel [(set (match_dup 0)
21044                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21045               (clobber (match_dup 2))])]
21046   "")
21047 \f
21048 (define_peephole2
21049   [(match_scratch:DI 0 "r")
21050    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21051               (clobber (reg:CC FLAGS_REG))
21052               (clobber (mem:BLK (scratch)))])]
21053   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21054   [(clobber (match_dup 0))
21055    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21056               (clobber (mem:BLK (scratch)))])])
21057
21058 (define_peephole2
21059   [(match_scratch:DI 0 "r")
21060    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21061               (clobber (reg:CC FLAGS_REG))
21062               (clobber (mem:BLK (scratch)))])]
21063   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21064   [(clobber (match_dup 0))
21065    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21066    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21067               (clobber (mem:BLK (scratch)))])])
21068
21069 ;; Convert esp subtractions to push.
21070 (define_peephole2
21071   [(match_scratch:DI 0 "r")
21072    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21073               (clobber (reg:CC FLAGS_REG))])]
21074   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21075   [(clobber (match_dup 0))
21076    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21077
21078 (define_peephole2
21079   [(match_scratch:DI 0 "r")
21080    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21081               (clobber (reg:CC FLAGS_REG))])]
21082   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21083   [(clobber (match_dup 0))
21084    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21085    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21086
21087 ;; Convert epilogue deallocator to pop.
21088 (define_peephole2
21089   [(match_scratch:DI 0 "r")
21090    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21091               (clobber (reg:CC FLAGS_REG))
21092               (clobber (mem:BLK (scratch)))])]
21093   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
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               (clobber (mem:BLK (scratch)))])]
21097   "")
21098
21099 ;; Two pops case is tricky, since pop causes dependency on destination register.
21100 ;; We use two registers if available.
21101 (define_peephole2
21102   [(match_scratch:DI 0 "r")
21103    (match_scratch:DI 1 "r")
21104    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21105               (clobber (reg:CC FLAGS_REG))
21106               (clobber (mem:BLK (scratch)))])]
21107   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21108   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21109               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21110               (clobber (mem:BLK (scratch)))])
21111    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21112               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21113   "")
21114
21115 (define_peephole2
21116   [(match_scratch:DI 0 "r")
21117    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21118               (clobber (reg:CC FLAGS_REG))
21119               (clobber (mem:BLK (scratch)))])]
21120   "optimize_insn_for_size_p ()"
21121   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21122               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21123               (clobber (mem:BLK (scratch)))])
21124    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21125               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21126   "")
21127
21128 ;; Convert esp additions to pop.
21129 (define_peephole2
21130   [(match_scratch:DI 0 "r")
21131    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21132               (clobber (reg:CC FLAGS_REG))])]
21133   ""
21134   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21135               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21136   "")
21137
21138 ;; Two pops case is tricky, since pop causes dependency on destination register.
21139 ;; We use two registers if available.
21140 (define_peephole2
21141   [(match_scratch:DI 0 "r")
21142    (match_scratch:DI 1 "r")
21143    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21144               (clobber (reg:CC FLAGS_REG))])]
21145   ""
21146   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21147               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21148    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21149               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21150   "")
21151
21152 (define_peephole2
21153   [(match_scratch:DI 0 "r")
21154    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21155               (clobber (reg:CC FLAGS_REG))])]
21156   "optimize_insn_for_size_p ()"
21157   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21158               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21159    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21160               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21161   "")
21162 \f
21163 ;; Convert imul by three, five and nine into lea
21164 (define_peephole2
21165   [(parallel
21166     [(set (match_operand:SI 0 "register_operand" "")
21167           (mult:SI (match_operand:SI 1 "register_operand" "")
21168                    (match_operand:SI 2 "const_int_operand" "")))
21169      (clobber (reg:CC FLAGS_REG))])]
21170   "INTVAL (operands[2]) == 3
21171    || INTVAL (operands[2]) == 5
21172    || INTVAL (operands[2]) == 9"
21173   [(set (match_dup 0)
21174         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21175                  (match_dup 1)))]
21176   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21177
21178 (define_peephole2
21179   [(parallel
21180     [(set (match_operand:SI 0 "register_operand" "")
21181           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21182                    (match_operand:SI 2 "const_int_operand" "")))
21183      (clobber (reg:CC FLAGS_REG))])]
21184   "optimize_insn_for_speed_p ()
21185    && (INTVAL (operands[2]) == 3
21186        || INTVAL (operands[2]) == 5
21187        || INTVAL (operands[2]) == 9)"
21188   [(set (match_dup 0) (match_dup 1))
21189    (set (match_dup 0)
21190         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21191                  (match_dup 0)))]
21192   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21193
21194 (define_peephole2
21195   [(parallel
21196     [(set (match_operand:DI 0 "register_operand" "")
21197           (mult:DI (match_operand:DI 1 "register_operand" "")
21198                    (match_operand:DI 2 "const_int_operand" "")))
21199      (clobber (reg:CC FLAGS_REG))])]
21200   "TARGET_64BIT
21201    && (INTVAL (operands[2]) == 3
21202        || INTVAL (operands[2]) == 5
21203        || INTVAL (operands[2]) == 9)"
21204   [(set (match_dup 0)
21205         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21206                  (match_dup 1)))]
21207   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21208
21209 (define_peephole2
21210   [(parallel
21211     [(set (match_operand:DI 0 "register_operand" "")
21212           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21213                    (match_operand:DI 2 "const_int_operand" "")))
21214      (clobber (reg:CC FLAGS_REG))])]
21215   "TARGET_64BIT
21216    && optimize_insn_for_speed_p ()
21217    && (INTVAL (operands[2]) == 3
21218        || INTVAL (operands[2]) == 5
21219        || INTVAL (operands[2]) == 9)"
21220   [(set (match_dup 0) (match_dup 1))
21221    (set (match_dup 0)
21222         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21223                  (match_dup 0)))]
21224   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21225
21226 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21227 ;; imul $32bit_imm, reg, reg is direct decoded.
21228 (define_peephole2
21229   [(match_scratch:DI 3 "r")
21230    (parallel [(set (match_operand:DI 0 "register_operand" "")
21231                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21232                             (match_operand:DI 2 "immediate_operand" "")))
21233               (clobber (reg:CC FLAGS_REG))])]
21234   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21235    && !satisfies_constraint_K (operands[2])"
21236   [(set (match_dup 3) (match_dup 1))
21237    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21238               (clobber (reg:CC FLAGS_REG))])]
21239 "")
21240
21241 (define_peephole2
21242   [(match_scratch:SI 3 "r")
21243    (parallel [(set (match_operand:SI 0 "register_operand" "")
21244                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21245                             (match_operand:SI 2 "immediate_operand" "")))
21246               (clobber (reg:CC FLAGS_REG))])]
21247   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21248    && !satisfies_constraint_K (operands[2])"
21249   [(set (match_dup 3) (match_dup 1))
21250    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21251               (clobber (reg:CC FLAGS_REG))])]
21252 "")
21253
21254 (define_peephole2
21255   [(match_scratch:SI 3 "r")
21256    (parallel [(set (match_operand:DI 0 "register_operand" "")
21257                    (zero_extend:DI
21258                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21259                               (match_operand:SI 2 "immediate_operand" ""))))
21260               (clobber (reg:CC FLAGS_REG))])]
21261   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21262    && !satisfies_constraint_K (operands[2])"
21263   [(set (match_dup 3) (match_dup 1))
21264    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21265               (clobber (reg:CC FLAGS_REG))])]
21266 "")
21267
21268 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21269 ;; Convert it into imul reg, reg
21270 ;; It would be better to force assembler to encode instruction using long
21271 ;; immediate, but there is apparently no way to do so.
21272 (define_peephole2
21273   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21274                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21275                             (match_operand:DI 2 "const_int_operand" "")))
21276               (clobber (reg:CC FLAGS_REG))])
21277    (match_scratch:DI 3 "r")]
21278   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21279    && satisfies_constraint_K (operands[2])"
21280   [(set (match_dup 3) (match_dup 2))
21281    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21282               (clobber (reg:CC FLAGS_REG))])]
21283 {
21284   if (!rtx_equal_p (operands[0], operands[1]))
21285     emit_move_insn (operands[0], operands[1]);
21286 })
21287
21288 (define_peephole2
21289   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21290                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21291                             (match_operand:SI 2 "const_int_operand" "")))
21292               (clobber (reg:CC FLAGS_REG))])
21293    (match_scratch:SI 3 "r")]
21294   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21295    && satisfies_constraint_K (operands[2])"
21296   [(set (match_dup 3) (match_dup 2))
21297    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21298               (clobber (reg:CC FLAGS_REG))])]
21299 {
21300   if (!rtx_equal_p (operands[0], operands[1]))
21301     emit_move_insn (operands[0], operands[1]);
21302 })
21303
21304 (define_peephole2
21305   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21306                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21307                             (match_operand:HI 2 "immediate_operand" "")))
21308               (clobber (reg:CC FLAGS_REG))])
21309    (match_scratch:HI 3 "r")]
21310   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21311   [(set (match_dup 3) (match_dup 2))
21312    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21313               (clobber (reg:CC FLAGS_REG))])]
21314 {
21315   if (!rtx_equal_p (operands[0], operands[1]))
21316     emit_move_insn (operands[0], operands[1]);
21317 })
21318
21319 ;; After splitting up read-modify operations, array accesses with memory
21320 ;; operands might end up in form:
21321 ;;  sall    $2, %eax
21322 ;;  movl    4(%esp), %edx
21323 ;;  addl    %edx, %eax
21324 ;; instead of pre-splitting:
21325 ;;  sall    $2, %eax
21326 ;;  addl    4(%esp), %eax
21327 ;; Turn it into:
21328 ;;  movl    4(%esp), %edx
21329 ;;  leal    (%edx,%eax,4), %eax
21330
21331 (define_peephole2
21332   [(parallel [(set (match_operand 0 "register_operand" "")
21333                    (ashift (match_operand 1 "register_operand" "")
21334                            (match_operand 2 "const_int_operand" "")))
21335                (clobber (reg:CC FLAGS_REG))])
21336    (set (match_operand 3 "register_operand")
21337         (match_operand 4 "x86_64_general_operand" ""))
21338    (parallel [(set (match_operand 5 "register_operand" "")
21339                    (plus (match_operand 6 "register_operand" "")
21340                          (match_operand 7 "register_operand" "")))
21341                    (clobber (reg:CC FLAGS_REG))])]
21342   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21343    /* Validate MODE for lea.  */
21344    && ((!TARGET_PARTIAL_REG_STALL
21345         && (GET_MODE (operands[0]) == QImode
21346             || GET_MODE (operands[0]) == HImode))
21347        || GET_MODE (operands[0]) == SImode
21348        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21349    /* We reorder load and the shift.  */
21350    && !rtx_equal_p (operands[1], operands[3])
21351    && !reg_overlap_mentioned_p (operands[0], operands[4])
21352    /* Last PLUS must consist of operand 0 and 3.  */
21353    && !rtx_equal_p (operands[0], operands[3])
21354    && (rtx_equal_p (operands[3], operands[6])
21355        || rtx_equal_p (operands[3], operands[7]))
21356    && (rtx_equal_p (operands[0], operands[6])
21357        || rtx_equal_p (operands[0], operands[7]))
21358    /* The intermediate operand 0 must die or be same as output.  */
21359    && (rtx_equal_p (operands[0], operands[5])
21360        || peep2_reg_dead_p (3, operands[0]))"
21361   [(set (match_dup 3) (match_dup 4))
21362    (set (match_dup 0) (match_dup 1))]
21363 {
21364   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21365   int scale = 1 << INTVAL (operands[2]);
21366   rtx index = gen_lowpart (Pmode, operands[1]);
21367   rtx base = gen_lowpart (Pmode, operands[3]);
21368   rtx dest = gen_lowpart (mode, operands[5]);
21369
21370   operands[1] = gen_rtx_PLUS (Pmode, base,
21371                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21372   if (mode != Pmode)
21373     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21374   operands[0] = dest;
21375 })
21376 \f
21377 ;; Call-value patterns last so that the wildcard operand does not
21378 ;; disrupt insn-recog's switch tables.
21379
21380 (define_insn "*call_value_pop_0"
21381   [(set (match_operand 0 "" "")
21382         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21383               (match_operand:SI 2 "" "")))
21384    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21385                             (match_operand:SI 3 "immediate_operand" "")))]
21386   "!TARGET_64BIT"
21387 {
21388   if (SIBLING_CALL_P (insn))
21389     return "jmp\t%P1";
21390   else
21391     return "call\t%P1";
21392 }
21393   [(set_attr "type" "callv")])
21394
21395 (define_insn "*call_value_pop_1"
21396   [(set (match_operand 0 "" "")
21397         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21398               (match_operand:SI 2 "" "")))
21399    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21400                             (match_operand:SI 3 "immediate_operand" "i")))]
21401   "!TARGET_64BIT"
21402 {
21403   if (constant_call_address_operand (operands[1], Pmode))
21404     {
21405       if (SIBLING_CALL_P (insn))
21406         return "jmp\t%P1";
21407       else
21408         return "call\t%P1";
21409     }
21410   if (SIBLING_CALL_P (insn))
21411     return "jmp\t%A1";
21412   else
21413     return "call\t%A1";
21414 }
21415   [(set_attr "type" "callv")])
21416
21417 (define_insn "*call_value_0"
21418   [(set (match_operand 0 "" "")
21419         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21420               (match_operand:SI 2 "" "")))]
21421   "!TARGET_64BIT"
21422 {
21423   if (SIBLING_CALL_P (insn))
21424     return "jmp\t%P1";
21425   else
21426     return "call\t%P1";
21427 }
21428   [(set_attr "type" "callv")])
21429
21430 (define_insn "*call_value_0_rex64"
21431   [(set (match_operand 0 "" "")
21432         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21433               (match_operand:DI 2 "const_int_operand" "")))]
21434   "TARGET_64BIT"
21435 {
21436   if (SIBLING_CALL_P (insn))
21437     return "jmp\t%P1";
21438   else
21439     return "call\t%P1";
21440 }
21441   [(set_attr "type" "callv")])
21442
21443 (define_insn "*call_value_0_rex64_ms_sysv"
21444   [(set (match_operand 0 "" "")
21445         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21446               (match_operand:DI 2 "const_int_operand" "")))
21447    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21448    (clobber (reg:TI 27))
21449    (clobber (reg:TI 28))
21450    (clobber (reg:TI 45))
21451    (clobber (reg:TI 46))
21452    (clobber (reg:TI 47))
21453    (clobber (reg:TI 48))
21454    (clobber (reg:TI 49))
21455    (clobber (reg:TI 50))
21456    (clobber (reg:TI 51))
21457    (clobber (reg:TI 52))
21458    (clobber (reg:DI SI_REG))
21459    (clobber (reg:DI DI_REG))]
21460   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21461 {
21462   if (SIBLING_CALL_P (insn))
21463     return "jmp\t%P1";
21464   else
21465     return "call\t%P1";
21466 }
21467   [(set_attr "type" "callv")])
21468
21469 (define_insn "*call_value_1"
21470   [(set (match_operand 0 "" "")
21471         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21472               (match_operand:SI 2 "" "")))]
21473   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21474 {
21475   if (constant_call_address_operand (operands[1], Pmode))
21476     return "call\t%P1";
21477   return "call\t%A1";
21478 }
21479   [(set_attr "type" "callv")])
21480
21481 (define_insn "*sibcall_value_1"
21482   [(set (match_operand 0 "" "")
21483         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21484               (match_operand:SI 2 "" "")))]
21485   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21486 {
21487   if (constant_call_address_operand (operands[1], Pmode))
21488     return "jmp\t%P1";
21489   return "jmp\t%A1";
21490 }
21491   [(set_attr "type" "callv")])
21492
21493 (define_insn "*call_value_1_rex64"
21494   [(set (match_operand 0 "" "")
21495         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21496               (match_operand:DI 2 "" "")))]
21497   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21498    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21499 {
21500   if (constant_call_address_operand (operands[1], Pmode))
21501     return "call\t%P1";
21502   return "call\t%A1";
21503 }
21504   [(set_attr "type" "callv")])
21505
21506 (define_insn "*call_value_1_rex64_ms_sysv"
21507   [(set (match_operand 0 "" "")
21508         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21509               (match_operand:DI 2 "" "")))
21510    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21511    (clobber (reg:TI 27))
21512    (clobber (reg:TI 28))
21513    (clobber (reg:TI 45))
21514    (clobber (reg:TI 46))
21515    (clobber (reg:TI 47))
21516    (clobber (reg:TI 48))
21517    (clobber (reg:TI 49))
21518    (clobber (reg:TI 50))
21519    (clobber (reg:TI 51))
21520    (clobber (reg:TI 52))
21521    (clobber (reg:DI SI_REG))
21522    (clobber (reg:DI DI_REG))]
21523   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21524 {
21525   if (constant_call_address_operand (operands[1], Pmode))
21526     return "call\t%P1";
21527   return "call\t%A1";
21528 }
21529   [(set_attr "type" "callv")])
21530
21531 (define_insn "*call_value_1_rex64_large"
21532   [(set (match_operand 0 "" "")
21533         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21534               (match_operand:DI 2 "" "")))]
21535   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21536   "call\t%A1"
21537   [(set_attr "type" "callv")])
21538
21539 (define_insn "*sibcall_value_1_rex64"
21540   [(set (match_operand 0 "" "")
21541         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21542               (match_operand:DI 2 "" "")))]
21543   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21544   "jmp\t%P1"
21545   [(set_attr "type" "callv")])
21546
21547 (define_insn "*sibcall_value_1_rex64_v"
21548   [(set (match_operand 0 "" "")
21549         (call (mem:QI (reg:DI R11_REG))
21550               (match_operand:DI 1 "" "")))]
21551   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21552   "jmp\t{*%%}r11"
21553   [(set_attr "type" "callv")])
21554 \f
21555 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21556 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21557 ;; caught for use by garbage collectors and the like.  Using an insn that
21558 ;; maps to SIGILL makes it more likely the program will rightfully die.
21559 ;; Keeping with tradition, "6" is in honor of #UD.
21560 (define_insn "trap"
21561   [(trap_if (const_int 1) (const_int 6))]
21562   ""
21563   { return ASM_SHORT "0x0b0f"; }
21564   [(set_attr "length" "2")])
21565
21566 (define_expand "sse_prologue_save"
21567   [(parallel [(set (match_operand:BLK 0 "" "")
21568                    (unspec:BLK [(reg:DI 21)
21569                                 (reg:DI 22)
21570                                 (reg:DI 23)
21571                                 (reg:DI 24)
21572                                 (reg:DI 25)
21573                                 (reg:DI 26)
21574                                 (reg:DI 27)
21575                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21576               (use (match_operand:DI 1 "register_operand" ""))
21577               (use (match_operand:DI 2 "immediate_operand" ""))
21578               (use (label_ref:DI (match_operand 3 "" "")))])]
21579   "TARGET_64BIT"
21580   "")
21581
21582 (define_insn "*sse_prologue_save_insn"
21583   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21584                           (match_operand:DI 4 "const_int_operand" "n")))
21585         (unspec:BLK [(reg:DI 21)
21586                      (reg:DI 22)
21587                      (reg:DI 23)
21588                      (reg:DI 24)
21589                      (reg:DI 25)
21590                      (reg:DI 26)
21591                      (reg:DI 27)
21592                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21593    (use (match_operand:DI 1 "register_operand" "r"))
21594    (use (match_operand:DI 2 "const_int_operand" "i"))
21595    (use (label_ref:DI (match_operand 3 "" "X")))]
21596   "TARGET_64BIT
21597    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21598    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21599 {
21600   int i;
21601   operands[0] = gen_rtx_MEM (Pmode,
21602                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21603   /* VEX instruction with a REX prefix will #UD.  */
21604   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21605     gcc_unreachable ();
21606
21607   output_asm_insn ("jmp\t%A1", operands);
21608   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21609     {
21610       operands[4] = adjust_address (operands[0], DImode, i*16);
21611       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21612       PUT_MODE (operands[4], TImode);
21613       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21614         output_asm_insn ("rex", operands);
21615       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21616     }
21617   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21618                                      CODE_LABEL_NUMBER (operands[3]));
21619   return "";
21620 }
21621   [(set_attr "type" "other")
21622    (set_attr "length_immediate" "0")
21623    (set_attr "length_address" "0")
21624    (set (attr "length")
21625      (if_then_else
21626        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21627        (const_string "34")
21628        (const_string "42")))
21629    (set_attr "memory" "store")
21630    (set_attr "modrm" "0")
21631    (set_attr "prefix" "maybe_vex")
21632    (set_attr "mode" "DI")])
21633
21634 (define_expand "prefetch"
21635   [(prefetch (match_operand 0 "address_operand" "")
21636              (match_operand:SI 1 "const_int_operand" "")
21637              (match_operand:SI 2 "const_int_operand" ""))]
21638   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21639 {
21640   int rw = INTVAL (operands[1]);
21641   int locality = INTVAL (operands[2]);
21642
21643   gcc_assert (rw == 0 || rw == 1);
21644   gcc_assert (locality >= 0 && locality <= 3);
21645   gcc_assert (GET_MODE (operands[0]) == Pmode
21646               || GET_MODE (operands[0]) == VOIDmode);
21647
21648   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21649      supported by SSE counterpart or the SSE prefetch is not available
21650      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21651      of locality.  */
21652   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21653     operands[2] = GEN_INT (3);
21654   else
21655     operands[1] = const0_rtx;
21656 })
21657
21658 (define_insn "*prefetch_sse"
21659   [(prefetch (match_operand:SI 0 "address_operand" "p")
21660              (const_int 0)
21661              (match_operand:SI 1 "const_int_operand" ""))]
21662   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21663 {
21664   static const char * const patterns[4] = {
21665    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21666   };
21667
21668   int locality = INTVAL (operands[1]);
21669   gcc_assert (locality >= 0 && locality <= 3);
21670
21671   return patterns[locality];
21672 }
21673   [(set_attr "type" "sse")
21674    (set_attr "memory" "none")])
21675
21676 (define_insn "*prefetch_sse_rex"
21677   [(prefetch (match_operand:DI 0 "address_operand" "p")
21678              (const_int 0)
21679              (match_operand:SI 1 "const_int_operand" ""))]
21680   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21681 {
21682   static const char * const patterns[4] = {
21683    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21684   };
21685
21686   int locality = INTVAL (operands[1]);
21687   gcc_assert (locality >= 0 && locality <= 3);
21688
21689   return patterns[locality];
21690 }
21691   [(set_attr "type" "sse")
21692    (set_attr "memory" "none")])
21693
21694 (define_insn "*prefetch_3dnow"
21695   [(prefetch (match_operand:SI 0 "address_operand" "p")
21696              (match_operand:SI 1 "const_int_operand" "n")
21697              (const_int 3))]
21698   "TARGET_3DNOW && !TARGET_64BIT"
21699 {
21700   if (INTVAL (operands[1]) == 0)
21701     return "prefetch\t%a0";
21702   else
21703     return "prefetchw\t%a0";
21704 }
21705   [(set_attr "type" "mmx")
21706    (set_attr "memory" "none")])
21707
21708 (define_insn "*prefetch_3dnow_rex"
21709   [(prefetch (match_operand:DI 0 "address_operand" "p")
21710              (match_operand:SI 1 "const_int_operand" "n")
21711              (const_int 3))]
21712   "TARGET_3DNOW && TARGET_64BIT"
21713 {
21714   if (INTVAL (operands[1]) == 0)
21715     return "prefetch\t%a0";
21716   else
21717     return "prefetchw\t%a0";
21718 }
21719   [(set_attr "type" "mmx")
21720    (set_attr "memory" "none")])
21721
21722 (define_expand "stack_protect_set"
21723   [(match_operand 0 "memory_operand" "")
21724    (match_operand 1 "memory_operand" "")]
21725   ""
21726 {
21727 #ifdef TARGET_THREAD_SSP_OFFSET
21728   if (TARGET_64BIT)
21729     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21730                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21731   else
21732     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21733                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21734 #else
21735   if (TARGET_64BIT)
21736     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21737   else
21738     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21739 #endif
21740   DONE;
21741 })
21742
21743 (define_insn "stack_protect_set_si"
21744   [(set (match_operand:SI 0 "memory_operand" "=m")
21745         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21746    (set (match_scratch:SI 2 "=&r") (const_int 0))
21747    (clobber (reg:CC FLAGS_REG))]
21748   ""
21749   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21750   [(set_attr "type" "multi")])
21751
21752 (define_insn "stack_protect_set_di"
21753   [(set (match_operand:DI 0 "memory_operand" "=m")
21754         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21755    (set (match_scratch:DI 2 "=&r") (const_int 0))
21756    (clobber (reg:CC FLAGS_REG))]
21757   "TARGET_64BIT"
21758   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21759   [(set_attr "type" "multi")])
21760
21761 (define_insn "stack_tls_protect_set_si"
21762   [(set (match_operand:SI 0 "memory_operand" "=m")
21763         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21764    (set (match_scratch:SI 2 "=&r") (const_int 0))
21765    (clobber (reg:CC FLAGS_REG))]
21766   ""
21767   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21768   [(set_attr "type" "multi")])
21769
21770 (define_insn "stack_tls_protect_set_di"
21771   [(set (match_operand:DI 0 "memory_operand" "=m")
21772         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21773    (set (match_scratch:DI 2 "=&r") (const_int 0))
21774    (clobber (reg:CC FLAGS_REG))]
21775   "TARGET_64BIT"
21776   {
21777      /* The kernel uses a different segment register for performance reasons; a
21778         system call would not have to trash the userspace segment register,
21779         which would be expensive */
21780      if (ix86_cmodel != CM_KERNEL)
21781         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21782      else
21783         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21784   }
21785   [(set_attr "type" "multi")])
21786
21787 (define_expand "stack_protect_test"
21788   [(match_operand 0 "memory_operand" "")
21789    (match_operand 1 "memory_operand" "")
21790    (match_operand 2 "" "")]
21791   ""
21792 {
21793   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21794   ix86_compare_op0 = operands[0];
21795   ix86_compare_op1 = operands[1];
21796   ix86_compare_emitted = flags;
21797
21798 #ifdef TARGET_THREAD_SSP_OFFSET
21799   if (TARGET_64BIT)
21800     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21801                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21802   else
21803     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21804                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21805 #else
21806   if (TARGET_64BIT)
21807     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21808   else
21809     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21810 #endif
21811   emit_jump_insn (gen_beq (operands[2]));
21812   DONE;
21813 })
21814
21815 (define_insn "stack_protect_test_si"
21816   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21817         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21818                      (match_operand:SI 2 "memory_operand" "m")]
21819                     UNSPEC_SP_TEST))
21820    (clobber (match_scratch:SI 3 "=&r"))]
21821   ""
21822   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21823   [(set_attr "type" "multi")])
21824
21825 (define_insn "stack_protect_test_di"
21826   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21827         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21828                      (match_operand:DI 2 "memory_operand" "m")]
21829                     UNSPEC_SP_TEST))
21830    (clobber (match_scratch:DI 3 "=&r"))]
21831   "TARGET_64BIT"
21832   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21833   [(set_attr "type" "multi")])
21834
21835 (define_insn "stack_tls_protect_test_si"
21836   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21837         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21838                      (match_operand:SI 2 "const_int_operand" "i")]
21839                     UNSPEC_SP_TLS_TEST))
21840    (clobber (match_scratch:SI 3 "=r"))]
21841   ""
21842   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21843   [(set_attr "type" "multi")])
21844
21845 (define_insn "stack_tls_protect_test_di"
21846   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21847         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21848                      (match_operand:DI 2 "const_int_operand" "i")]
21849                     UNSPEC_SP_TLS_TEST))
21850    (clobber (match_scratch:DI 3 "=r"))]
21851   "TARGET_64BIT"
21852   {
21853      /* The kernel uses a different segment register for performance reasons; a
21854         system call would not have to trash the userspace segment register,
21855         which would be expensive */
21856      if (ix86_cmodel != CM_KERNEL)
21857         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21858      else
21859         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21860   }
21861   [(set_attr "type" "multi")])
21862
21863 (define_mode_iterator CRC32MODE [QI HI SI])
21864 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21865 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21866
21867 (define_insn "sse4_2_crc32<mode>"
21868   [(set (match_operand:SI 0 "register_operand" "=r")
21869         (unspec:SI
21870           [(match_operand:SI 1 "register_operand" "0")
21871            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21872           UNSPEC_CRC32))]
21873   "TARGET_SSE4_2"
21874   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21875   [(set_attr "type" "sselog1")
21876    (set_attr "prefix_rep" "1")
21877    (set_attr "prefix_extra" "1")
21878    (set_attr "mode" "SI")])
21879
21880 (define_insn "sse4_2_crc32di"
21881   [(set (match_operand:DI 0 "register_operand" "=r")
21882         (unspec:DI
21883           [(match_operand:DI 1 "register_operand" "0")
21884            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21885           UNSPEC_CRC32))]
21886   "TARGET_SSE4_2 && TARGET_64BIT"
21887   "crc32q\t{%2, %0|%0, %2}"
21888   [(set_attr "type" "sselog1")
21889    (set_attr "prefix_rep" "1")
21890    (set_attr "prefix_extra" "1")
21891    (set_attr "mode" "DI")])
21892
21893 (include "mmx.md")
21894 (include "sse.md")
21895 (include "sync.md")