OSDN Git Service

2008-07-30 Joey Ye <joey.ye@intel.com>
[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
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
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
70
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_PFRCP                49)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDDQU                47)
107
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
112
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122    (UNSPEC_TAN                  68)
123    (UNSPEC_FXAM                 69)
124
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
132
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
144
145    (UNSPEC_C2_FLAG              95)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
163
164    ; For SSE4.1 support
165    (UNSPEC_BLENDV               134)
166    (UNSPEC_INSERTPS             135)
167    (UNSPEC_DP                   136)
168    (UNSPEC_MOVNTDQA             137)
169    (UNSPEC_MPSADBW              138)
170    (UNSPEC_PHMINPOSUW           139)
171    (UNSPEC_PTEST                140)
172    (UNSPEC_ROUND                141)
173
174    ; For SSE4.2 support
175    (UNSPEC_CRC32                143)
176    (UNSPEC_PCMPESTR             144)
177    (UNSPEC_PCMPISTR             145)
178
179    ;; For SSE5
180    (UNSPEC_SSE5_INTRINSIC       150)
181    (UNSPEC_SSE5_UNSIGNED_CMP    151)
182    (UNSPEC_SSE5_TRUEFALSE       152)
183    (UNSPEC_SSE5_PERMUTE         153)
184    (UNSPEC_FRCZ                 154)
185    (UNSPEC_CVTPH2PS             155)
186    (UNSPEC_CVTPS2PH             156)
187
188    ; For AES support
189    (UNSPEC_AESENC               159)
190    (UNSPEC_AESENCLAST           160)
191    (UNSPEC_AESDEC               161)
192    (UNSPEC_AESDECLAST           162)
193    (UNSPEC_AESIMC               163)
194    (UNSPEC_AESKEYGENASSIST      164)
195
196    ; For PCLMUL support
197    (UNSPEC_PCLMUL               165)
198   ])
199
200 (define_constants
201   [(UNSPECV_BLOCKAGE            0)
202    (UNSPECV_STACK_PROBE         1)
203    (UNSPECV_EMMS                2)
204    (UNSPECV_LDMXCSR             3)
205    (UNSPECV_STMXCSR             4)
206    (UNSPECV_FEMMS               5)
207    (UNSPECV_CLFLUSH             6)
208    (UNSPECV_ALIGN               7)
209    (UNSPECV_MONITOR             8)
210    (UNSPECV_MWAIT               9)
211    (UNSPECV_CMPXCHG_1           10)
212    (UNSPECV_CMPXCHG_2           11)
213    (UNSPECV_XCHG                12)
214    (UNSPECV_LOCK                13)
215    (UNSPECV_PROLOGUE_USE        14)
216    (UNSPECV_CLD                 15)
217   ])
218
219 ;; Constants to represent pcomtrue/pcomfalse variants
220 (define_constants
221   [(PCOM_FALSE                  0)
222    (PCOM_TRUE                   1)
223    (COM_FALSE_S                 2)
224    (COM_FALSE_P                 3)
225    (COM_TRUE_S                  4)
226    (COM_TRUE_P                  5)
227   ])
228
229 ;; Constants used in the SSE5 pperm instruction
230 (define_constants
231   [(PPERM_SRC                   0x00)   /* copy source */
232    (PPERM_INVERT                0x20)   /* invert source */
233    (PPERM_REVERSE               0x40)   /* bit reverse source */
234    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
235    (PPERM_ZERO                  0x80)   /* all 0's */
236    (PPERM_ONES                  0xa0)   /* all 1's */
237    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
238    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
239    (PPERM_SRC1                  0x00)   /* use first source byte */
240    (PPERM_SRC2                  0x10)   /* use second source byte */
241    ])
242
243 ;; Registers by name.
244 (define_constants
245   [(AX_REG                       0)
246    (DX_REG                       1)
247    (CX_REG                       2)
248    (BX_REG                       3)
249    (SI_REG                       4)
250    (DI_REG                       5)
251    (BP_REG                       6)
252    (SP_REG                       7)
253    (FLAGS_REG                   17)
254    (FPSR_REG                    18)
255    (FPCR_REG                    19)
256    (R10_REG                     39)
257    (R11_REG                     40)
258    (R13_REG                     42)
259   ])
260
261 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
262 ;; from i386.c.
263
264 ;; In C guard expressions, put expressions which may be compile-time
265 ;; constants first.  This allows for better optimization.  For
266 ;; example, write "TARGET_64BIT && reload_completed", not
267 ;; "reload_completed && TARGET_64BIT".
268
269 \f
270 ;; Processor type.  This attribute must exactly match the processor_type
271 ;; enumeration in i386.h.
272 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
273                     nocona,core2,generic32,generic64,amdfam10"
274   (const (symbol_ref "ix86_tune")))
275
276 ;; A basic instruction type.  Refinements due to arguments to be
277 ;; provided in other attributes.
278 (define_attr "type"
279   "other,multi,
280    alu,alu1,negnot,imov,imovx,lea,
281    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
282    icmp,test,ibr,setcc,icmov,
283    push,pop,call,callv,leave,
284    str,bitmanip,
285    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
286    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
287    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
288    ssemuladd,sse4arg,
289    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
290   (const_string "other"))
291
292 ;; Main data type used by the insn
293 (define_attr "mode"
294   "unknown,none,QI,HI,SI,DI,TI,SF,DF,XF,TF,V4SF,V2DF,V2SF,V1DF"
295   (const_string "unknown"))
296
297 ;; The CPU unit operations uses.
298 (define_attr "unit" "integer,i387,sse,mmx,unknown"
299   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
300            (const_string "i387")
301          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
302                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
303                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
304            (const_string "sse")
305          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
306            (const_string "mmx")
307          (eq_attr "type" "other")
308            (const_string "unknown")]
309          (const_string "integer")))
310
311 ;; The (bounding maximum) length of an instruction immediate.
312 (define_attr "length_immediate" ""
313   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
314                           bitmanip")
315            (const_int 0)
316          (eq_attr "unit" "i387,sse,mmx")
317            (const_int 0)
318          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
319                           imul,icmp,push,pop")
320            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
321          (eq_attr "type" "imov,test")
322            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
323          (eq_attr "type" "call")
324            (if_then_else (match_operand 0 "constant_call_address_operand" "")
325              (const_int 4)
326              (const_int 0))
327          (eq_attr "type" "callv")
328            (if_then_else (match_operand 1 "constant_call_address_operand" "")
329              (const_int 4)
330              (const_int 0))
331          ;; We don't know the size before shorten_branches.  Expect
332          ;; the instruction to fit for better scheduling.
333          (eq_attr "type" "ibr")
334            (const_int 1)
335          ]
336          (symbol_ref "/* Update immediate_length and other attributes! */
337                       gcc_unreachable (),1")))
338
339 ;; The (bounding maximum) length of an instruction address.
340 (define_attr "length_address" ""
341   (cond [(eq_attr "type" "str,other,multi,fxch")
342            (const_int 0)
343          (and (eq_attr "type" "call")
344               (match_operand 0 "constant_call_address_operand" ""))
345              (const_int 0)
346          (and (eq_attr "type" "callv")
347               (match_operand 1 "constant_call_address_operand" ""))
348              (const_int 0)
349          ]
350          (symbol_ref "ix86_attr_length_address_default (insn)")))
351
352 ;; Set when length prefix is used.
353 (define_attr "prefix_data16" ""
354   (if_then_else (ior (eq_attr "mode" "HI")
355                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
356     (const_int 1)
357     (const_int 0)))
358
359 ;; Set when string REP prefix is used.
360 (define_attr "prefix_rep" ""
361   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
362     (const_int 1)
363     (const_int 0)))
364
365 ;; Set when 0f opcode prefix is used.
366 (define_attr "prefix_0f" ""
367   (if_then_else
368     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
369          (eq_attr "unit" "sse,mmx"))
370     (const_int 1)
371     (const_int 0)))
372
373 ;; Set when REX opcode prefix is used.
374 (define_attr "prefix_rex" ""
375   (cond [(and (eq_attr "mode" "DI")
376               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
377            (const_int 1)
378          (and (eq_attr "mode" "QI")
379               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
380                   (const_int 0)))
381            (const_int 1)
382          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
383              (const_int 0))
384            (const_int 1)
385         ]
386         (const_int 0)))
387
388 ;; There are also additional prefixes in SSSE3.
389 (define_attr "prefix_extra" "" (const_int 0))
390
391 ;; Set when modrm byte is used.
392 (define_attr "modrm" ""
393   (cond [(eq_attr "type" "str,leave")
394            (const_int 0)
395          (eq_attr "unit" "i387")
396            (const_int 0)
397          (and (eq_attr "type" "incdec")
398               (ior (match_operand:SI 1 "register_operand" "")
399                    (match_operand:HI 1 "register_operand" "")))
400            (const_int 0)
401          (and (eq_attr "type" "push")
402               (not (match_operand 1 "memory_operand" "")))
403            (const_int 0)
404          (and (eq_attr "type" "pop")
405               (not (match_operand 0 "memory_operand" "")))
406            (const_int 0)
407          (and (eq_attr "type" "imov")
408               (ior (and (match_operand 0 "register_operand" "")
409                         (match_operand 1 "immediate_operand" ""))
410                    (ior (and (match_operand 0 "ax_reg_operand" "")
411                              (match_operand 1 "memory_displacement_only_operand" ""))
412                         (and (match_operand 0 "memory_displacement_only_operand" "")
413                              (match_operand 1 "ax_reg_operand" "")))))
414            (const_int 0)
415          (and (eq_attr "type" "call")
416               (match_operand 0 "constant_call_address_operand" ""))
417              (const_int 0)
418          (and (eq_attr "type" "callv")
419               (match_operand 1 "constant_call_address_operand" ""))
420              (const_int 0)
421          ]
422          (const_int 1)))
423
424 ;; The (bounding maximum) length of an instruction in bytes.
425 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
426 ;; Later we may want to split them and compute proper length as for
427 ;; other insns.
428 (define_attr "length" ""
429   (cond [(eq_attr "type" "other,multi,fistp,frndint")
430            (const_int 16)
431          (eq_attr "type" "fcmp")
432            (const_int 4)
433          (eq_attr "unit" "i387")
434            (plus (const_int 2)
435                  (plus (attr "prefix_data16")
436                        (attr "length_address")))]
437          (plus (plus (attr "modrm")
438                      (plus (attr "prefix_0f")
439                            (plus (attr "prefix_rex")
440                                  (plus (attr "prefix_extra")
441                                        (const_int 1)))))
442                (plus (attr "prefix_rep")
443                      (plus (attr "prefix_data16")
444                            (plus (attr "length_immediate")
445                                  (attr "length_address")))))))
446
447 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
448 ;; `store' if there is a simple memory reference therein, or `unknown'
449 ;; if the instruction is complex.
450
451 (define_attr "memory" "none,load,store,both,unknown"
452   (cond [(eq_attr "type" "other,multi,str")
453            (const_string "unknown")
454          (eq_attr "type" "lea,fcmov,fpspc")
455            (const_string "none")
456          (eq_attr "type" "fistp,leave")
457            (const_string "both")
458          (eq_attr "type" "frndint")
459            (const_string "load")
460          (eq_attr "type" "push")
461            (if_then_else (match_operand 1 "memory_operand" "")
462              (const_string "both")
463              (const_string "store"))
464          (eq_attr "type" "pop")
465            (if_then_else (match_operand 0 "memory_operand" "")
466              (const_string "both")
467              (const_string "load"))
468          (eq_attr "type" "setcc")
469            (if_then_else (match_operand 0 "memory_operand" "")
470              (const_string "store")
471              (const_string "none"))
472          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
473            (if_then_else (ior (match_operand 0 "memory_operand" "")
474                               (match_operand 1 "memory_operand" ""))
475              (const_string "load")
476              (const_string "none"))
477          (eq_attr "type" "ibr")
478            (if_then_else (match_operand 0 "memory_operand" "")
479              (const_string "load")
480              (const_string "none"))
481          (eq_attr "type" "call")
482            (if_then_else (match_operand 0 "constant_call_address_operand" "")
483              (const_string "none")
484              (const_string "load"))
485          (eq_attr "type" "callv")
486            (if_then_else (match_operand 1 "constant_call_address_operand" "")
487              (const_string "none")
488              (const_string "load"))
489          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
490               (match_operand 1 "memory_operand" ""))
491            (const_string "both")
492          (and (match_operand 0 "memory_operand" "")
493               (match_operand 1 "memory_operand" ""))
494            (const_string "both")
495          (match_operand 0 "memory_operand" "")
496            (const_string "store")
497          (match_operand 1 "memory_operand" "")
498            (const_string "load")
499          (and (eq_attr "type"
500                  "!alu1,negnot,ishift1,
501                    imov,imovx,icmp,test,bitmanip,
502                    fmov,fcmp,fsgn,
503                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
504                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
505               (match_operand 2 "memory_operand" ""))
506            (const_string "load")
507          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
508               (match_operand 3 "memory_operand" ""))
509            (const_string "load")
510         ]
511         (const_string "none")))
512
513 ;; Indicates if an instruction has both an immediate and a displacement.
514
515 (define_attr "imm_disp" "false,true,unknown"
516   (cond [(eq_attr "type" "other,multi")
517            (const_string "unknown")
518          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
519               (and (match_operand 0 "memory_displacement_operand" "")
520                    (match_operand 1 "immediate_operand" "")))
521            (const_string "true")
522          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
523               (and (match_operand 0 "memory_displacement_operand" "")
524                    (match_operand 2 "immediate_operand" "")))
525            (const_string "true")
526         ]
527         (const_string "false")))
528
529 ;; Indicates if an FP operation has an integer source.
530
531 (define_attr "fp_int_src" "false,true"
532   (const_string "false"))
533
534 ;; Defines rounding mode of an FP operation.
535
536 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
537   (const_string "any"))
538
539 ;; Describe a user's asm statement.
540 (define_asm_attributes
541   [(set_attr "length" "128")
542    (set_attr "type" "multi")])
543
544 ;; All integer comparison codes.
545 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
546
547 ;; All floating-point comparison codes.
548 (define_code_iterator fp_cond [unordered ordered
549                                uneq unge ungt unle unlt ltgt ])
550
551 (define_code_iterator plusminus [plus minus])
552
553 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
554
555 ;; Base name for define_insn
556 (define_code_attr plusminus_insn
557   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
558    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
559
560 ;; Base name for insn mnemonic.
561 (define_code_attr plusminus_mnemonic
562   [(plus "add") (ss_plus "adds") (us_plus "addus")
563    (minus "sub") (ss_minus "subs") (us_minus "subus")])
564
565 ;; Mark commutative operators as such in constraints.
566 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
567                         (minus "") (ss_minus "") (us_minus "")])
568
569 ;; Mapping of signed max and min
570 (define_code_iterator smaxmin [smax smin])
571
572 ;; Mapping of unsigned max and min
573 (define_code_iterator umaxmin [umax umin])
574
575 ;; Base name for integer and FP insn mnemonic
576 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
577                                  (umax "maxu") (umin "minu")])
578 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
579
580 ;; Mapping of parallel logic operators
581 (define_code_iterator plogic [and ior xor])
582
583 ;; Base name for insn mnemonic.
584 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
585
586 ;; Mapping of abs neg operators
587 (define_code_iterator absneg [abs neg])
588
589 ;; Base name for x87 insn mnemonic.
590 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
591
592 ;; All single word integer modes.
593 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
594
595 ;; Instruction suffix for integer modes.
596 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
597
598 ;; Register class for integer modes.
599 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
600
601 ;; Immediate operand constraint for integer modes.
602 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
603
604 ;; General operand predicate for integer modes.
605 (define_mode_attr general_operand
606         [(QI "general_operand")
607          (HI "general_operand")
608          (SI "general_operand")
609          (DI "x86_64_general_operand")])
610
611 ;; SSE and x87 SFmode and DFmode floating point modes
612 (define_mode_iterator MODEF [SF DF])
613
614 ;; All x87 floating point modes
615 (define_mode_iterator X87MODEF [SF DF XF])
616
617 ;; All integer modes handled by x87 fisttp operator.
618 (define_mode_iterator X87MODEI [HI SI DI])
619
620 ;; All integer modes handled by integer x87 operators.
621 (define_mode_iterator X87MODEI12 [HI SI])
622
623 ;; All integer modes handled by SSE cvtts?2si* operators.
624 (define_mode_iterator SSEMODEI24 [SI DI])
625
626 ;; SSE asm suffix for floating point modes
627 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
628
629 ;; SSE vector mode corresponding to a scalar mode
630 (define_mode_attr ssevecmode
631   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
632
633 ;; Instruction suffix for REX 64bit operators.
634 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
635
636 ;; This mode iterator allows :P to be used for patterns that operate on
637 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
638 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
639
640 \f
641 ;; Scheduling descriptions
642
643 (include "pentium.md")
644 (include "ppro.md")
645 (include "k6.md")
646 (include "athlon.md")
647 (include "geode.md")
648
649 \f
650 ;; Operand and operator predicates and constraints
651
652 (include "predicates.md")
653 (include "constraints.md")
654
655 \f
656 ;; Compare instructions.
657
658 ;; All compare insns have expanders that save the operands away without
659 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
660 ;; after the cmp) will actually emit the cmpM.
661
662 (define_expand "cmpti"
663   [(set (reg:CC FLAGS_REG)
664         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
665                     (match_operand:TI 1 "x86_64_general_operand" "")))]
666   "TARGET_64BIT"
667 {
668   if (MEM_P (operands[0]) && MEM_P (operands[1]))
669     operands[0] = force_reg (TImode, operands[0]);
670   ix86_compare_op0 = operands[0];
671   ix86_compare_op1 = operands[1];
672   DONE;
673 })
674
675 (define_expand "cmpdi"
676   [(set (reg:CC FLAGS_REG)
677         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
678                     (match_operand:DI 1 "x86_64_general_operand" "")))]
679   ""
680 {
681   if (MEM_P (operands[0]) && MEM_P (operands[1]))
682     operands[0] = force_reg (DImode, operands[0]);
683   ix86_compare_op0 = operands[0];
684   ix86_compare_op1 = operands[1];
685   DONE;
686 })
687
688 (define_expand "cmpsi"
689   [(set (reg:CC FLAGS_REG)
690         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
691                     (match_operand:SI 1 "general_operand" "")))]
692   ""
693 {
694   if (MEM_P (operands[0]) && MEM_P (operands[1]))
695     operands[0] = force_reg (SImode, operands[0]);
696   ix86_compare_op0 = operands[0];
697   ix86_compare_op1 = operands[1];
698   DONE;
699 })
700
701 (define_expand "cmphi"
702   [(set (reg:CC FLAGS_REG)
703         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
704                     (match_operand:HI 1 "general_operand" "")))]
705   ""
706 {
707   if (MEM_P (operands[0]) && MEM_P (operands[1]))
708     operands[0] = force_reg (HImode, operands[0]);
709   ix86_compare_op0 = operands[0];
710   ix86_compare_op1 = operands[1];
711   DONE;
712 })
713
714 (define_expand "cmpqi"
715   [(set (reg:CC FLAGS_REG)
716         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
717                     (match_operand:QI 1 "general_operand" "")))]
718   "TARGET_QIMODE_MATH"
719 {
720   if (MEM_P (operands[0]) && MEM_P (operands[1]))
721     operands[0] = force_reg (QImode, operands[0]);
722   ix86_compare_op0 = operands[0];
723   ix86_compare_op1 = operands[1];
724   DONE;
725 })
726
727 (define_insn "cmpdi_ccno_1_rex64"
728   [(set (reg FLAGS_REG)
729         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
730                  (match_operand:DI 1 "const0_operand" "")))]
731   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
732   "@
733    test{q}\t%0, %0
734    cmp{q}\t{%1, %0|%0, %1}"
735   [(set_attr "type" "test,icmp")
736    (set_attr "length_immediate" "0,1")
737    (set_attr "mode" "DI")])
738
739 (define_insn "*cmpdi_minus_1_rex64"
740   [(set (reg FLAGS_REG)
741         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
742                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
743                  (const_int 0)))]
744   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
745   "cmp{q}\t{%1, %0|%0, %1}"
746   [(set_attr "type" "icmp")
747    (set_attr "mode" "DI")])
748
749 (define_expand "cmpdi_1_rex64"
750   [(set (reg:CC FLAGS_REG)
751         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
752                     (match_operand:DI 1 "general_operand" "")))]
753   "TARGET_64BIT"
754   "")
755
756 (define_insn "cmpdi_1_insn_rex64"
757   [(set (reg FLAGS_REG)
758         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
759                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
760   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761   "cmp{q}\t{%1, %0|%0, %1}"
762   [(set_attr "type" "icmp")
763    (set_attr "mode" "DI")])
764
765
766 (define_insn "*cmpsi_ccno_1"
767   [(set (reg FLAGS_REG)
768         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
769                  (match_operand:SI 1 "const0_operand" "")))]
770   "ix86_match_ccmode (insn, CCNOmode)"
771   "@
772    test{l}\t%0, %0
773    cmp{l}\t{%1, %0|%0, %1}"
774   [(set_attr "type" "test,icmp")
775    (set_attr "length_immediate" "0,1")
776    (set_attr "mode" "SI")])
777
778 (define_insn "*cmpsi_minus_1"
779   [(set (reg FLAGS_REG)
780         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
781                            (match_operand:SI 1 "general_operand" "ri,mr"))
782                  (const_int 0)))]
783   "ix86_match_ccmode (insn, CCGOCmode)"
784   "cmp{l}\t{%1, %0|%0, %1}"
785   [(set_attr "type" "icmp")
786    (set_attr "mode" "SI")])
787
788 (define_expand "cmpsi_1"
789   [(set (reg:CC FLAGS_REG)
790         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
791                     (match_operand:SI 1 "general_operand" "")))]
792   ""
793   "")
794
795 (define_insn "*cmpsi_1_insn"
796   [(set (reg FLAGS_REG)
797         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
798                  (match_operand:SI 1 "general_operand" "ri,mr")))]
799   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
800     && ix86_match_ccmode (insn, CCmode)"
801   "cmp{l}\t{%1, %0|%0, %1}"
802   [(set_attr "type" "icmp")
803    (set_attr "mode" "SI")])
804
805 (define_insn "*cmphi_ccno_1"
806   [(set (reg FLAGS_REG)
807         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
808                  (match_operand:HI 1 "const0_operand" "")))]
809   "ix86_match_ccmode (insn, CCNOmode)"
810   "@
811    test{w}\t%0, %0
812    cmp{w}\t{%1, %0|%0, %1}"
813   [(set_attr "type" "test,icmp")
814    (set_attr "length_immediate" "0,1")
815    (set_attr "mode" "HI")])
816
817 (define_insn "*cmphi_minus_1"
818   [(set (reg FLAGS_REG)
819         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
820                            (match_operand:HI 1 "general_operand" "rn,mr"))
821                  (const_int 0)))]
822   "ix86_match_ccmode (insn, CCGOCmode)"
823   "cmp{w}\t{%1, %0|%0, %1}"
824   [(set_attr "type" "icmp")
825    (set_attr "mode" "HI")])
826
827 (define_insn "*cmphi_1"
828   [(set (reg FLAGS_REG)
829         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
830                  (match_operand:HI 1 "general_operand" "rn,mr")))]
831   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
832    && ix86_match_ccmode (insn, CCmode)"
833   "cmp{w}\t{%1, %0|%0, %1}"
834   [(set_attr "type" "icmp")
835    (set_attr "mode" "HI")])
836
837 (define_insn "*cmpqi_ccno_1"
838   [(set (reg FLAGS_REG)
839         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
840                  (match_operand:QI 1 "const0_operand" "")))]
841   "ix86_match_ccmode (insn, CCNOmode)"
842   "@
843    test{b}\t%0, %0
844    cmp{b}\t{$0, %0|%0, 0}"
845   [(set_attr "type" "test,icmp")
846    (set_attr "length_immediate" "0,1")
847    (set_attr "mode" "QI")])
848
849 (define_insn "*cmpqi_1"
850   [(set (reg FLAGS_REG)
851         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
852                  (match_operand:QI 1 "general_operand" "qn,mq")))]
853   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
854     && ix86_match_ccmode (insn, CCmode)"
855   "cmp{b}\t{%1, %0|%0, %1}"
856   [(set_attr "type" "icmp")
857    (set_attr "mode" "QI")])
858
859 (define_insn "*cmpqi_minus_1"
860   [(set (reg FLAGS_REG)
861         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
862                            (match_operand:QI 1 "general_operand" "qn,mq"))
863                  (const_int 0)))]
864   "ix86_match_ccmode (insn, CCGOCmode)"
865   "cmp{b}\t{%1, %0|%0, %1}"
866   [(set_attr "type" "icmp")
867    (set_attr "mode" "QI")])
868
869 (define_insn "*cmpqi_ext_1"
870   [(set (reg FLAGS_REG)
871         (compare
872           (match_operand:QI 0 "general_operand" "Qm")
873           (subreg:QI
874             (zero_extract:SI
875               (match_operand 1 "ext_register_operand" "Q")
876               (const_int 8)
877               (const_int 8)) 0)))]
878   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
879   "cmp{b}\t{%h1, %0|%0, %h1}"
880   [(set_attr "type" "icmp")
881    (set_attr "mode" "QI")])
882
883 (define_insn "*cmpqi_ext_1_rex64"
884   [(set (reg FLAGS_REG)
885         (compare
886           (match_operand:QI 0 "register_operand" "Q")
887           (subreg:QI
888             (zero_extract:SI
889               (match_operand 1 "ext_register_operand" "Q")
890               (const_int 8)
891               (const_int 8)) 0)))]
892   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
893   "cmp{b}\t{%h1, %0|%0, %h1}"
894   [(set_attr "type" "icmp")
895    (set_attr "mode" "QI")])
896
897 (define_insn "*cmpqi_ext_2"
898   [(set (reg FLAGS_REG)
899         (compare
900           (subreg:QI
901             (zero_extract:SI
902               (match_operand 0 "ext_register_operand" "Q")
903               (const_int 8)
904               (const_int 8)) 0)
905           (match_operand:QI 1 "const0_operand" "")))]
906   "ix86_match_ccmode (insn, CCNOmode)"
907   "test{b}\t%h0, %h0"
908   [(set_attr "type" "test")
909    (set_attr "length_immediate" "0")
910    (set_attr "mode" "QI")])
911
912 (define_expand "cmpqi_ext_3"
913   [(set (reg:CC FLAGS_REG)
914         (compare:CC
915           (subreg:QI
916             (zero_extract:SI
917               (match_operand 0 "ext_register_operand" "")
918               (const_int 8)
919               (const_int 8)) 0)
920           (match_operand:QI 1 "general_operand" "")))]
921   ""
922   "")
923
924 (define_insn "cmpqi_ext_3_insn"
925   [(set (reg FLAGS_REG)
926         (compare
927           (subreg:QI
928             (zero_extract:SI
929               (match_operand 0 "ext_register_operand" "Q")
930               (const_int 8)
931               (const_int 8)) 0)
932           (match_operand:QI 1 "general_operand" "Qmn")))]
933   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
934   "cmp{b}\t{%1, %h0|%h0, %1}"
935   [(set_attr "type" "icmp")
936    (set_attr "mode" "QI")])
937
938 (define_insn "cmpqi_ext_3_insn_rex64"
939   [(set (reg FLAGS_REG)
940         (compare
941           (subreg:QI
942             (zero_extract:SI
943               (match_operand 0 "ext_register_operand" "Q")
944               (const_int 8)
945               (const_int 8)) 0)
946           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
947   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
948   "cmp{b}\t{%1, %h0|%h0, %1}"
949   [(set_attr "type" "icmp")
950    (set_attr "mode" "QI")])
951
952 (define_insn "*cmpqi_ext_4"
953   [(set (reg FLAGS_REG)
954         (compare
955           (subreg:QI
956             (zero_extract:SI
957               (match_operand 0 "ext_register_operand" "Q")
958               (const_int 8)
959               (const_int 8)) 0)
960           (subreg:QI
961             (zero_extract:SI
962               (match_operand 1 "ext_register_operand" "Q")
963               (const_int 8)
964               (const_int 8)) 0)))]
965   "ix86_match_ccmode (insn, CCmode)"
966   "cmp{b}\t{%h1, %h0|%h0, %h1}"
967   [(set_attr "type" "icmp")
968    (set_attr "mode" "QI")])
969
970 ;; These implement float point compares.
971 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
972 ;; which would allow mix and match FP modes on the compares.  Which is what
973 ;; the old patterns did, but with many more of them.
974
975 (define_expand "cmpxf"
976   [(set (reg:CC FLAGS_REG)
977         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
978                     (match_operand:XF 1 "nonmemory_operand" "")))]
979   "TARGET_80387"
980 {
981   ix86_compare_op0 = operands[0];
982   ix86_compare_op1 = operands[1];
983   DONE;
984 })
985
986 (define_expand "cmp<mode>"
987   [(set (reg:CC FLAGS_REG)
988         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
989                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
990   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
991 {
992   ix86_compare_op0 = operands[0];
993   ix86_compare_op1 = operands[1];
994   DONE;
995 })
996
997 ;; FP compares, step 1:
998 ;; Set the FP condition codes.
999 ;;
1000 ;; CCFPmode     compare with exceptions
1001 ;; CCFPUmode    compare with no exceptions
1002
1003 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1004 ;; used to manage the reg stack popping would not be preserved.
1005
1006 (define_insn "*cmpfp_0"
1007   [(set (match_operand:HI 0 "register_operand" "=a")
1008         (unspec:HI
1009           [(compare:CCFP
1010              (match_operand 1 "register_operand" "f")
1011              (match_operand 2 "const0_operand" ""))]
1012         UNSPEC_FNSTSW))]
1013   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1014    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1015   "* return output_fp_compare (insn, operands, 0, 0);"
1016   [(set_attr "type" "multi")
1017    (set_attr "unit" "i387")
1018    (set (attr "mode")
1019      (cond [(match_operand:SF 1 "" "")
1020               (const_string "SF")
1021             (match_operand:DF 1 "" "")
1022               (const_string "DF")
1023            ]
1024            (const_string "XF")))])
1025
1026 (define_insn_and_split "*cmpfp_0_cc"
1027   [(set (reg:CCFP FLAGS_REG)
1028         (compare:CCFP
1029           (match_operand 1 "register_operand" "f")
1030           (match_operand 2 "const0_operand" "")))
1031    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1032   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1033    && TARGET_SAHF && !TARGET_CMOVE
1034    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1035   "#"
1036   "&& reload_completed"
1037   [(set (match_dup 0)
1038         (unspec:HI
1039           [(compare:CCFP (match_dup 1)(match_dup 2))]
1040         UNSPEC_FNSTSW))
1041    (set (reg:CC FLAGS_REG)
1042         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1043   ""
1044   [(set_attr "type" "multi")
1045    (set_attr "unit" "i387")
1046    (set (attr "mode")
1047      (cond [(match_operand:SF 1 "" "")
1048               (const_string "SF")
1049             (match_operand:DF 1 "" "")
1050               (const_string "DF")
1051            ]
1052            (const_string "XF")))])
1053
1054 (define_insn "*cmpfp_xf"
1055   [(set (match_operand:HI 0 "register_operand" "=a")
1056         (unspec:HI
1057           [(compare:CCFP
1058              (match_operand:XF 1 "register_operand" "f")
1059              (match_operand:XF 2 "register_operand" "f"))]
1060           UNSPEC_FNSTSW))]
1061   "TARGET_80387"
1062   "* return output_fp_compare (insn, operands, 0, 0);"
1063   [(set_attr "type" "multi")
1064    (set_attr "unit" "i387")
1065    (set_attr "mode" "XF")])
1066
1067 (define_insn_and_split "*cmpfp_xf_cc"
1068   [(set (reg:CCFP FLAGS_REG)
1069         (compare:CCFP
1070           (match_operand:XF 1 "register_operand" "f")
1071           (match_operand:XF 2 "register_operand" "f")))
1072    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1073   "TARGET_80387
1074    && TARGET_SAHF && !TARGET_CMOVE"
1075   "#"
1076   "&& reload_completed"
1077   [(set (match_dup 0)
1078         (unspec:HI
1079           [(compare:CCFP (match_dup 1)(match_dup 2))]
1080         UNSPEC_FNSTSW))
1081    (set (reg:CC FLAGS_REG)
1082         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1083   ""
1084   [(set_attr "type" "multi")
1085    (set_attr "unit" "i387")
1086    (set_attr "mode" "XF")])
1087
1088 (define_insn "*cmpfp_<mode>"
1089   [(set (match_operand:HI 0 "register_operand" "=a")
1090         (unspec:HI
1091           [(compare:CCFP
1092              (match_operand:MODEF 1 "register_operand" "f")
1093              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1094           UNSPEC_FNSTSW))]
1095   "TARGET_80387"
1096   "* return output_fp_compare (insn, operands, 0, 0);"
1097   [(set_attr "type" "multi")
1098    (set_attr "unit" "i387")
1099    (set_attr "mode" "<MODE>")])
1100
1101 (define_insn_and_split "*cmpfp_<mode>_cc"
1102   [(set (reg:CCFP FLAGS_REG)
1103         (compare:CCFP
1104           (match_operand:MODEF 1 "register_operand" "f")
1105           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1106    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1107   "TARGET_80387
1108    && TARGET_SAHF && !TARGET_CMOVE"
1109   "#"
1110   "&& reload_completed"
1111   [(set (match_dup 0)
1112         (unspec:HI
1113           [(compare:CCFP (match_dup 1)(match_dup 2))]
1114         UNSPEC_FNSTSW))
1115    (set (reg:CC FLAGS_REG)
1116         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1117   ""
1118   [(set_attr "type" "multi")
1119    (set_attr "unit" "i387")
1120    (set_attr "mode" "<MODE>")])
1121
1122 (define_insn "*cmpfp_u"
1123   [(set (match_operand:HI 0 "register_operand" "=a")
1124         (unspec:HI
1125           [(compare:CCFPU
1126              (match_operand 1 "register_operand" "f")
1127              (match_operand 2 "register_operand" "f"))]
1128           UNSPEC_FNSTSW))]
1129   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1130    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1131   "* return output_fp_compare (insn, operands, 0, 1);"
1132   [(set_attr "type" "multi")
1133    (set_attr "unit" "i387")
1134    (set (attr "mode")
1135      (cond [(match_operand:SF 1 "" "")
1136               (const_string "SF")
1137             (match_operand:DF 1 "" "")
1138               (const_string "DF")
1139            ]
1140            (const_string "XF")))])
1141
1142 (define_insn_and_split "*cmpfp_u_cc"
1143   [(set (reg:CCFPU FLAGS_REG)
1144         (compare:CCFPU
1145           (match_operand 1 "register_operand" "f")
1146           (match_operand 2 "register_operand" "f")))
1147    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1148   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1149    && TARGET_SAHF && !TARGET_CMOVE
1150    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1151   "#"
1152   "&& reload_completed"
1153   [(set (match_dup 0)
1154         (unspec:HI
1155           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1156         UNSPEC_FNSTSW))
1157    (set (reg:CC FLAGS_REG)
1158         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1159   ""
1160   [(set_attr "type" "multi")
1161    (set_attr "unit" "i387")
1162    (set (attr "mode")
1163      (cond [(match_operand:SF 1 "" "")
1164               (const_string "SF")
1165             (match_operand:DF 1 "" "")
1166               (const_string "DF")
1167            ]
1168            (const_string "XF")))])
1169
1170 (define_insn "*cmpfp_<mode>"
1171   [(set (match_operand:HI 0 "register_operand" "=a")
1172         (unspec:HI
1173           [(compare:CCFP
1174              (match_operand 1 "register_operand" "f")
1175              (match_operator 3 "float_operator"
1176                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1177           UNSPEC_FNSTSW))]
1178   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1179    && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1180    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1181   "* return output_fp_compare (insn, operands, 0, 0);"
1182   [(set_attr "type" "multi")
1183    (set_attr "unit" "i387")
1184    (set_attr "fp_int_src" "true")
1185    (set_attr "mode" "<MODE>")])
1186
1187 (define_insn_and_split "*cmpfp_<mode>_cc"
1188   [(set (reg:CCFP FLAGS_REG)
1189         (compare:CCFP
1190           (match_operand 1 "register_operand" "f")
1191           (match_operator 3 "float_operator"
1192             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1193    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1194   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1195    && TARGET_SAHF && !TARGET_CMOVE
1196    && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1197    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1198   "#"
1199   "&& reload_completed"
1200   [(set (match_dup 0)
1201         (unspec:HI
1202           [(compare:CCFP
1203              (match_dup 1)
1204              (match_op_dup 3 [(match_dup 2)]))]
1205         UNSPEC_FNSTSW))
1206    (set (reg:CC FLAGS_REG)
1207         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1208   ""
1209   [(set_attr "type" "multi")
1210    (set_attr "unit" "i387")
1211    (set_attr "fp_int_src" "true")
1212    (set_attr "mode" "<MODE>")])
1213
1214 ;; FP compares, step 2
1215 ;; Move the fpsw to ax.
1216
1217 (define_insn "x86_fnstsw_1"
1218   [(set (match_operand:HI 0 "register_operand" "=a")
1219         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1220   "TARGET_80387"
1221   "fnstsw\t%0"
1222   [(set_attr "length" "2")
1223    (set_attr "mode" "SI")
1224    (set_attr "unit" "i387")])
1225
1226 ;; FP compares, step 3
1227 ;; Get ax into flags, general case.
1228
1229 (define_insn "x86_sahf_1"
1230   [(set (reg:CC FLAGS_REG)
1231         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1232                    UNSPEC_SAHF))]
1233   "TARGET_SAHF"
1234 {
1235 #ifdef HAVE_AS_IX86_SAHF
1236   return "sahf";
1237 #else
1238   return ".byte\t0x9e";
1239 #endif
1240 }
1241   [(set_attr "length" "1")
1242    (set_attr "athlon_decode" "vector")
1243    (set_attr "amdfam10_decode" "direct")
1244    (set_attr "mode" "SI")])
1245
1246 ;; Pentium Pro can do steps 1 through 3 in one go.
1247 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1248 (define_insn "*cmpfp_i_mixed"
1249   [(set (reg:CCFP FLAGS_REG)
1250         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1251                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1252   "TARGET_MIX_SSE_I387
1253    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1254    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1255   "* return output_fp_compare (insn, operands, 1, 0);"
1256   [(set_attr "type" "fcmp,ssecomi")
1257    (set (attr "mode")
1258      (if_then_else (match_operand:SF 1 "" "")
1259         (const_string "SF")
1260         (const_string "DF")))
1261    (set_attr "athlon_decode" "vector")
1262    (set_attr "amdfam10_decode" "direct")])
1263
1264 (define_insn "*cmpfp_i_sse"
1265   [(set (reg:CCFP FLAGS_REG)
1266         (compare:CCFP (match_operand 0 "register_operand" "x")
1267                       (match_operand 1 "nonimmediate_operand" "xm")))]
1268   "TARGET_SSE_MATH
1269    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1270    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1271   "* return output_fp_compare (insn, operands, 1, 0);"
1272   [(set_attr "type" "ssecomi")
1273    (set (attr "mode")
1274      (if_then_else (match_operand:SF 1 "" "")
1275         (const_string "SF")
1276         (const_string "DF")))
1277    (set_attr "athlon_decode" "vector")
1278    (set_attr "amdfam10_decode" "direct")])
1279
1280 (define_insn "*cmpfp_i_i387"
1281   [(set (reg:CCFP FLAGS_REG)
1282         (compare:CCFP (match_operand 0 "register_operand" "f")
1283                       (match_operand 1 "register_operand" "f")))]
1284   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1285    && TARGET_CMOVE
1286    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1287    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1288   "* return output_fp_compare (insn, operands, 1, 0);"
1289   [(set_attr "type" "fcmp")
1290    (set (attr "mode")
1291      (cond [(match_operand:SF 1 "" "")
1292               (const_string "SF")
1293             (match_operand:DF 1 "" "")
1294               (const_string "DF")
1295            ]
1296            (const_string "XF")))
1297    (set_attr "athlon_decode" "vector")
1298    (set_attr "amdfam10_decode" "direct")])
1299
1300 (define_insn "*cmpfp_iu_mixed"
1301   [(set (reg:CCFPU FLAGS_REG)
1302         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1303                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1304   "TARGET_MIX_SSE_I387
1305    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1306    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1307   "* return output_fp_compare (insn, operands, 1, 1);"
1308   [(set_attr "type" "fcmp,ssecomi")
1309    (set (attr "mode")
1310      (if_then_else (match_operand:SF 1 "" "")
1311         (const_string "SF")
1312         (const_string "DF")))
1313    (set_attr "athlon_decode" "vector")
1314    (set_attr "amdfam10_decode" "direct")])
1315
1316 (define_insn "*cmpfp_iu_sse"
1317   [(set (reg:CCFPU FLAGS_REG)
1318         (compare:CCFPU (match_operand 0 "register_operand" "x")
1319                        (match_operand 1 "nonimmediate_operand" "xm")))]
1320   "TARGET_SSE_MATH
1321    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1322    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1323   "* return output_fp_compare (insn, operands, 1, 1);"
1324   [(set_attr "type" "ssecomi")
1325    (set (attr "mode")
1326      (if_then_else (match_operand:SF 1 "" "")
1327         (const_string "SF")
1328         (const_string "DF")))
1329    (set_attr "athlon_decode" "vector")
1330    (set_attr "amdfam10_decode" "direct")])
1331
1332 (define_insn "*cmpfp_iu_387"
1333   [(set (reg:CCFPU FLAGS_REG)
1334         (compare:CCFPU (match_operand 0 "register_operand" "f")
1335                        (match_operand 1 "register_operand" "f")))]
1336   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1337    && TARGET_CMOVE
1338    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1339    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1340   "* return output_fp_compare (insn, operands, 1, 1);"
1341   [(set_attr "type" "fcmp")
1342    (set (attr "mode")
1343      (cond [(match_operand:SF 1 "" "")
1344               (const_string "SF")
1345             (match_operand:DF 1 "" "")
1346               (const_string "DF")
1347            ]
1348            (const_string "XF")))
1349    (set_attr "athlon_decode" "vector")
1350    (set_attr "amdfam10_decode" "direct")])
1351 \f
1352 ;; Move instructions.
1353
1354 ;; General case of fullword move.
1355
1356 (define_expand "movsi"
1357   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1358         (match_operand:SI 1 "general_operand" ""))]
1359   ""
1360   "ix86_expand_move (SImode, operands); DONE;")
1361
1362 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1363 ;; general_operand.
1364 ;;
1365 ;; %%% We don't use a post-inc memory reference because x86 is not a
1366 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1367 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1368 ;; targets without our curiosities, and it is just as easy to represent
1369 ;; this differently.
1370
1371 (define_insn "*pushsi2"
1372   [(set (match_operand:SI 0 "push_operand" "=<")
1373         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1374   "!TARGET_64BIT"
1375   "push{l}\t%1"
1376   [(set_attr "type" "push")
1377    (set_attr "mode" "SI")])
1378
1379 ;; For 64BIT abi we always round up to 8 bytes.
1380 (define_insn "*pushsi2_rex64"
1381   [(set (match_operand:SI 0 "push_operand" "=X")
1382         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1383   "TARGET_64BIT"
1384   "push{q}\t%q1"
1385   [(set_attr "type" "push")
1386    (set_attr "mode" "SI")])
1387
1388 (define_insn "*pushsi2_prologue"
1389   [(set (match_operand:SI 0 "push_operand" "=<")
1390         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1391    (clobber (mem:BLK (scratch)))]
1392   "!TARGET_64BIT"
1393   "push{l}\t%1"
1394   [(set_attr "type" "push")
1395    (set_attr "mode" "SI")])
1396
1397 (define_insn "*popsi1_epilogue"
1398   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1399         (mem:SI (reg:SI SP_REG)))
1400    (set (reg:SI SP_REG)
1401         (plus:SI (reg:SI SP_REG) (const_int 4)))
1402    (clobber (mem:BLK (scratch)))]
1403   "!TARGET_64BIT"
1404   "pop{l}\t%0"
1405   [(set_attr "type" "pop")
1406    (set_attr "mode" "SI")])
1407
1408 (define_insn "popsi1"
1409   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1410         (mem:SI (reg:SI SP_REG)))
1411    (set (reg:SI SP_REG)
1412         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1413   "!TARGET_64BIT"
1414   "pop{l}\t%0"
1415   [(set_attr "type" "pop")
1416    (set_attr "mode" "SI")])
1417
1418 (define_insn "*movsi_xor"
1419   [(set (match_operand:SI 0 "register_operand" "=r")
1420         (match_operand:SI 1 "const0_operand" ""))
1421    (clobber (reg:CC FLAGS_REG))]
1422   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1423   "xor{l}\t%0, %0"
1424   [(set_attr "type" "alu1")
1425    (set_attr "mode" "SI")
1426    (set_attr "length_immediate" "0")])
1427
1428 (define_insn "*movsi_or"
1429   [(set (match_operand:SI 0 "register_operand" "=r")
1430         (match_operand:SI 1 "immediate_operand" "i"))
1431    (clobber (reg:CC FLAGS_REG))]
1432   "reload_completed
1433    && operands[1] == constm1_rtx
1434    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1435 {
1436   operands[1] = constm1_rtx;
1437   return "or{l}\t{%1, %0|%0, %1}";
1438 }
1439   [(set_attr "type" "alu1")
1440    (set_attr "mode" "SI")
1441    (set_attr "length_immediate" "1")])
1442
1443 (define_insn "*movsi_1"
1444   [(set (match_operand:SI 0 "nonimmediate_operand"
1445                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1446         (match_operand:SI 1 "general_operand"
1447                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1448   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1449 {
1450   switch (get_attr_type (insn))
1451     {
1452     case TYPE_SSELOG1:
1453       if (get_attr_mode (insn) == MODE_TI)
1454         return "pxor\t%0, %0";
1455       return "xorps\t%0, %0";
1456
1457     case TYPE_SSEMOV:
1458       switch (get_attr_mode (insn))
1459         {
1460         case MODE_TI:
1461           return "movdqa\t{%1, %0|%0, %1}";
1462         case MODE_V4SF:
1463           return "movaps\t{%1, %0|%0, %1}";
1464         case MODE_SI:
1465           return "movd\t{%1, %0|%0, %1}";
1466         case MODE_SF:
1467           return "movss\t{%1, %0|%0, %1}";
1468         default:
1469           gcc_unreachable ();
1470         }
1471
1472     case TYPE_MMXADD:
1473       return "pxor\t%0, %0";
1474
1475     case TYPE_MMXMOV:
1476       if (get_attr_mode (insn) == MODE_DI)
1477         return "movq\t{%1, %0|%0, %1}";
1478       return "movd\t{%1, %0|%0, %1}";
1479
1480     case TYPE_LEA:
1481       return "lea{l}\t{%1, %0|%0, %1}";
1482
1483     default:
1484       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1485       return "mov{l}\t{%1, %0|%0, %1}";
1486     }
1487 }
1488   [(set (attr "type")
1489      (cond [(eq_attr "alternative" "2")
1490               (const_string "mmxadd")
1491             (eq_attr "alternative" "3,4,5")
1492               (const_string "mmxmov")
1493             (eq_attr "alternative" "6")
1494               (const_string "sselog1")
1495             (eq_attr "alternative" "7,8,9,10,11")
1496               (const_string "ssemov")
1497             (match_operand:DI 1 "pic_32bit_operand" "")
1498               (const_string "lea")
1499            ]
1500            (const_string "imov")))
1501    (set (attr "mode")
1502      (cond [(eq_attr "alternative" "2,3")
1503               (const_string "DI")
1504             (eq_attr "alternative" "6,7")
1505               (if_then_else
1506                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1507                 (const_string "V4SF")
1508                 (const_string "TI"))
1509             (and (eq_attr "alternative" "8,9,10,11")
1510                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1511               (const_string "SF")
1512            ]
1513            (const_string "SI")))])
1514
1515 ;; Stores and loads of ax to arbitrary constant address.
1516 ;; We fake an second form of instruction to force reload to load address
1517 ;; into register when rax is not available
1518 (define_insn "*movabssi_1_rex64"
1519   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1520         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1521   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1522   "@
1523    movabs{l}\t{%1, %P0|%P0, %1}
1524    mov{l}\t{%1, %a0|%a0, %1}"
1525   [(set_attr "type" "imov")
1526    (set_attr "modrm" "0,*")
1527    (set_attr "length_address" "8,0")
1528    (set_attr "length_immediate" "0,*")
1529    (set_attr "memory" "store")
1530    (set_attr "mode" "SI")])
1531
1532 (define_insn "*movabssi_2_rex64"
1533   [(set (match_operand:SI 0 "register_operand" "=a,r")
1534         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1535   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1536   "@
1537    movabs{l}\t{%P1, %0|%0, %P1}
1538    mov{l}\t{%a1, %0|%0, %a1}"
1539   [(set_attr "type" "imov")
1540    (set_attr "modrm" "0,*")
1541    (set_attr "length_address" "8,0")
1542    (set_attr "length_immediate" "0")
1543    (set_attr "memory" "load")
1544    (set_attr "mode" "SI")])
1545
1546 (define_insn "*swapsi"
1547   [(set (match_operand:SI 0 "register_operand" "+r")
1548         (match_operand:SI 1 "register_operand" "+r"))
1549    (set (match_dup 1)
1550         (match_dup 0))]
1551   ""
1552   "xchg{l}\t%1, %0"
1553   [(set_attr "type" "imov")
1554    (set_attr "mode" "SI")
1555    (set_attr "pent_pair" "np")
1556    (set_attr "athlon_decode" "vector")
1557    (set_attr "amdfam10_decode" "double")])
1558
1559 (define_expand "movhi"
1560   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1561         (match_operand:HI 1 "general_operand" ""))]
1562   ""
1563   "ix86_expand_move (HImode, operands); DONE;")
1564
1565 (define_insn "*pushhi2"
1566   [(set (match_operand:HI 0 "push_operand" "=X")
1567         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1568   "!TARGET_64BIT"
1569   "push{l}\t%k1"
1570   [(set_attr "type" "push")
1571    (set_attr "mode" "SI")])
1572
1573 ;; For 64BIT abi we always round up to 8 bytes.
1574 (define_insn "*pushhi2_rex64"
1575   [(set (match_operand:HI 0 "push_operand" "=X")
1576         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1577   "TARGET_64BIT"
1578   "push{q}\t%q1"
1579   [(set_attr "type" "push")
1580    (set_attr "mode" "DI")])
1581
1582 (define_insn "*movhi_1"
1583   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1584         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1585   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1586 {
1587   switch (get_attr_type (insn))
1588     {
1589     case TYPE_IMOVX:
1590       /* movzwl is faster than movw on p2 due to partial word stalls,
1591          though not as fast as an aligned movl.  */
1592       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1593     default:
1594       if (get_attr_mode (insn) == MODE_SI)
1595         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1596       else
1597         return "mov{w}\t{%1, %0|%0, %1}";
1598     }
1599 }
1600   [(set (attr "type")
1601      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1602               (const_string "imov")
1603             (and (eq_attr "alternative" "0")
1604                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1605                           (const_int 0))
1606                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1607                           (const_int 0))))
1608               (const_string "imov")
1609             (and (eq_attr "alternative" "1,2")
1610                  (match_operand:HI 1 "aligned_operand" ""))
1611               (const_string "imov")
1612             (and (ne (symbol_ref "TARGET_MOVX")
1613                      (const_int 0))
1614                  (eq_attr "alternative" "0,2"))
1615               (const_string "imovx")
1616            ]
1617            (const_string "imov")))
1618     (set (attr "mode")
1619       (cond [(eq_attr "type" "imovx")
1620                (const_string "SI")
1621              (and (eq_attr "alternative" "1,2")
1622                   (match_operand:HI 1 "aligned_operand" ""))
1623                (const_string "SI")
1624              (and (eq_attr "alternative" "0")
1625                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1626                            (const_int 0))
1627                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1628                            (const_int 0))))
1629                (const_string "SI")
1630             ]
1631             (const_string "HI")))])
1632
1633 ;; Stores and loads of ax to arbitrary constant address.
1634 ;; We fake an second form of instruction to force reload to load address
1635 ;; into register when rax is not available
1636 (define_insn "*movabshi_1_rex64"
1637   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1638         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1639   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1640   "@
1641    movabs{w}\t{%1, %P0|%P0, %1}
1642    mov{w}\t{%1, %a0|%a0, %1}"
1643   [(set_attr "type" "imov")
1644    (set_attr "modrm" "0,*")
1645    (set_attr "length_address" "8,0")
1646    (set_attr "length_immediate" "0,*")
1647    (set_attr "memory" "store")
1648    (set_attr "mode" "HI")])
1649
1650 (define_insn "*movabshi_2_rex64"
1651   [(set (match_operand:HI 0 "register_operand" "=a,r")
1652         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1653   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1654   "@
1655    movabs{w}\t{%P1, %0|%0, %P1}
1656    mov{w}\t{%a1, %0|%0, %a1}"
1657   [(set_attr "type" "imov")
1658    (set_attr "modrm" "0,*")
1659    (set_attr "length_address" "8,0")
1660    (set_attr "length_immediate" "0")
1661    (set_attr "memory" "load")
1662    (set_attr "mode" "HI")])
1663
1664 (define_insn "*swaphi_1"
1665   [(set (match_operand:HI 0 "register_operand" "+r")
1666         (match_operand:HI 1 "register_operand" "+r"))
1667    (set (match_dup 1)
1668         (match_dup 0))]
1669   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1670   "xchg{l}\t%k1, %k0"
1671   [(set_attr "type" "imov")
1672    (set_attr "mode" "SI")
1673    (set_attr "pent_pair" "np")
1674    (set_attr "athlon_decode" "vector")
1675    (set_attr "amdfam10_decode" "double")])
1676
1677 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1678 (define_insn "*swaphi_2"
1679   [(set (match_operand:HI 0 "register_operand" "+r")
1680         (match_operand:HI 1 "register_operand" "+r"))
1681    (set (match_dup 1)
1682         (match_dup 0))]
1683   "TARGET_PARTIAL_REG_STALL"
1684   "xchg{w}\t%1, %0"
1685   [(set_attr "type" "imov")
1686    (set_attr "mode" "HI")
1687    (set_attr "pent_pair" "np")
1688    (set_attr "athlon_decode" "vector")])
1689
1690 (define_expand "movstricthi"
1691   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1692         (match_operand:HI 1 "general_operand" ""))]
1693   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1694 {
1695   /* Don't generate memory->memory moves, go through a register */
1696   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1697     operands[1] = force_reg (HImode, operands[1]);
1698 })
1699
1700 (define_insn "*movstricthi_1"
1701   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1702         (match_operand:HI 1 "general_operand" "rn,m"))]
1703   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1704    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1705   "mov{w}\t{%1, %0|%0, %1}"
1706   [(set_attr "type" "imov")
1707    (set_attr "mode" "HI")])
1708
1709 (define_insn "*movstricthi_xor"
1710   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1711         (match_operand:HI 1 "const0_operand" ""))
1712    (clobber (reg:CC FLAGS_REG))]
1713   "reload_completed
1714    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1715   "xor{w}\t%0, %0"
1716   [(set_attr "type" "alu1")
1717    (set_attr "mode" "HI")
1718    (set_attr "length_immediate" "0")])
1719
1720 (define_expand "movqi"
1721   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1722         (match_operand:QI 1 "general_operand" ""))]
1723   ""
1724   "ix86_expand_move (QImode, operands); DONE;")
1725
1726 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1727 ;; "push a byte".  But actually we use pushl, which has the effect
1728 ;; of rounding the amount pushed up to a word.
1729
1730 (define_insn "*pushqi2"
1731   [(set (match_operand:QI 0 "push_operand" "=X")
1732         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1733   "!TARGET_64BIT"
1734   "push{l}\t%k1"
1735   [(set_attr "type" "push")
1736    (set_attr "mode" "SI")])
1737
1738 ;; For 64BIT abi we always round up to 8 bytes.
1739 (define_insn "*pushqi2_rex64"
1740   [(set (match_operand:QI 0 "push_operand" "=X")
1741         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1742   "TARGET_64BIT"
1743   "push{q}\t%q1"
1744   [(set_attr "type" "push")
1745    (set_attr "mode" "DI")])
1746
1747 ;; Situation is quite tricky about when to choose full sized (SImode) move
1748 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1749 ;; partial register dependency machines (such as AMD Athlon), where QImode
1750 ;; moves issue extra dependency and for partial register stalls machines
1751 ;; that don't use QImode patterns (and QImode move cause stall on the next
1752 ;; instruction).
1753 ;;
1754 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1755 ;; register stall machines with, where we use QImode instructions, since
1756 ;; partial register stall can be caused there.  Then we use movzx.
1757 (define_insn "*movqi_1"
1758   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1759         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1760   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1761 {
1762   switch (get_attr_type (insn))
1763     {
1764     case TYPE_IMOVX:
1765       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1766       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1767     default:
1768       if (get_attr_mode (insn) == MODE_SI)
1769         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1770       else
1771         return "mov{b}\t{%1, %0|%0, %1}";
1772     }
1773 }
1774   [(set (attr "type")
1775      (cond [(and (eq_attr "alternative" "5")
1776                  (not (match_operand:QI 1 "aligned_operand" "")))
1777               (const_string "imovx")
1778             (ne (symbol_ref "optimize_size") (const_int 0))
1779               (const_string "imov")
1780             (and (eq_attr "alternative" "3")
1781                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1782                           (const_int 0))
1783                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1784                           (const_int 0))))
1785               (const_string "imov")
1786             (eq_attr "alternative" "3,5")
1787               (const_string "imovx")
1788             (and (ne (symbol_ref "TARGET_MOVX")
1789                      (const_int 0))
1790                  (eq_attr "alternative" "2"))
1791               (const_string "imovx")
1792            ]
1793            (const_string "imov")))
1794    (set (attr "mode")
1795       (cond [(eq_attr "alternative" "3,4,5")
1796                (const_string "SI")
1797              (eq_attr "alternative" "6")
1798                (const_string "QI")
1799              (eq_attr "type" "imovx")
1800                (const_string "SI")
1801              (and (eq_attr "type" "imov")
1802                   (and (eq_attr "alternative" "0,1")
1803                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1804                                 (const_int 0))
1805                             (and (eq (symbol_ref "optimize_size")
1806                                      (const_int 0))
1807                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1808                                      (const_int 0))))))
1809                (const_string "SI")
1810              ;; Avoid partial register stalls when not using QImode arithmetic
1811              (and (eq_attr "type" "imov")
1812                   (and (eq_attr "alternative" "0,1")
1813                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1814                                 (const_int 0))
1815                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1816                                 (const_int 0)))))
1817                (const_string "SI")
1818            ]
1819            (const_string "QI")))])
1820
1821 (define_insn "*swapqi_1"
1822   [(set (match_operand:QI 0 "register_operand" "+r")
1823         (match_operand:QI 1 "register_operand" "+r"))
1824    (set (match_dup 1)
1825         (match_dup 0))]
1826   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1827   "xchg{l}\t%k1, %k0"
1828   [(set_attr "type" "imov")
1829    (set_attr "mode" "SI")
1830    (set_attr "pent_pair" "np")
1831    (set_attr "athlon_decode" "vector")
1832    (set_attr "amdfam10_decode" "vector")])
1833
1834 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1835 (define_insn "*swapqi_2"
1836   [(set (match_operand:QI 0 "register_operand" "+q")
1837         (match_operand:QI 1 "register_operand" "+q"))
1838    (set (match_dup 1)
1839         (match_dup 0))]
1840   "TARGET_PARTIAL_REG_STALL"
1841   "xchg{b}\t%1, %0"
1842   [(set_attr "type" "imov")
1843    (set_attr "mode" "QI")
1844    (set_attr "pent_pair" "np")
1845    (set_attr "athlon_decode" "vector")])
1846
1847 (define_expand "movstrictqi"
1848   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1849         (match_operand:QI 1 "general_operand" ""))]
1850   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1851 {
1852   /* Don't generate memory->memory moves, go through a register.  */
1853   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1854     operands[1] = force_reg (QImode, operands[1]);
1855 })
1856
1857 (define_insn "*movstrictqi_1"
1858   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1859         (match_operand:QI 1 "general_operand" "*qn,m"))]
1860   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1861    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1862   "mov{b}\t{%1, %0|%0, %1}"
1863   [(set_attr "type" "imov")
1864    (set_attr "mode" "QI")])
1865
1866 (define_insn "*movstrictqi_xor"
1867   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1868         (match_operand:QI 1 "const0_operand" ""))
1869    (clobber (reg:CC FLAGS_REG))]
1870   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1871   "xor{b}\t%0, %0"
1872   [(set_attr "type" "alu1")
1873    (set_attr "mode" "QI")
1874    (set_attr "length_immediate" "0")])
1875
1876 (define_insn "*movsi_extv_1"
1877   [(set (match_operand:SI 0 "register_operand" "=R")
1878         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1879                          (const_int 8)
1880                          (const_int 8)))]
1881   ""
1882   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1883   [(set_attr "type" "imovx")
1884    (set_attr "mode" "SI")])
1885
1886 (define_insn "*movhi_extv_1"
1887   [(set (match_operand:HI 0 "register_operand" "=R")
1888         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1889                          (const_int 8)
1890                          (const_int 8)))]
1891   ""
1892   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1893   [(set_attr "type" "imovx")
1894    (set_attr "mode" "SI")])
1895
1896 (define_insn "*movqi_extv_1"
1897   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1898         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1899                          (const_int 8)
1900                          (const_int 8)))]
1901   "!TARGET_64BIT"
1902 {
1903   switch (get_attr_type (insn))
1904     {
1905     case TYPE_IMOVX:
1906       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1907     default:
1908       return "mov{b}\t{%h1, %0|%0, %h1}";
1909     }
1910 }
1911   [(set (attr "type")
1912      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1913                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1914                              (ne (symbol_ref "TARGET_MOVX")
1915                                  (const_int 0))))
1916         (const_string "imovx")
1917         (const_string "imov")))
1918    (set (attr "mode")
1919      (if_then_else (eq_attr "type" "imovx")
1920         (const_string "SI")
1921         (const_string "QI")))])
1922
1923 (define_insn "*movqi_extv_1_rex64"
1924   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1925         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1926                          (const_int 8)
1927                          (const_int 8)))]
1928   "TARGET_64BIT"
1929 {
1930   switch (get_attr_type (insn))
1931     {
1932     case TYPE_IMOVX:
1933       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1934     default:
1935       return "mov{b}\t{%h1, %0|%0, %h1}";
1936     }
1937 }
1938   [(set (attr "type")
1939      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1940                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1941                              (ne (symbol_ref "TARGET_MOVX")
1942                                  (const_int 0))))
1943         (const_string "imovx")
1944         (const_string "imov")))
1945    (set (attr "mode")
1946      (if_then_else (eq_attr "type" "imovx")
1947         (const_string "SI")
1948         (const_string "QI")))])
1949
1950 ;; Stores and loads of ax to arbitrary constant address.
1951 ;; We fake an second form of instruction to force reload to load address
1952 ;; into register when rax is not available
1953 (define_insn "*movabsqi_1_rex64"
1954   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1955         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1956   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1957   "@
1958    movabs{b}\t{%1, %P0|%P0, %1}
1959    mov{b}\t{%1, %a0|%a0, %1}"
1960   [(set_attr "type" "imov")
1961    (set_attr "modrm" "0,*")
1962    (set_attr "length_address" "8,0")
1963    (set_attr "length_immediate" "0,*")
1964    (set_attr "memory" "store")
1965    (set_attr "mode" "QI")])
1966
1967 (define_insn "*movabsqi_2_rex64"
1968   [(set (match_operand:QI 0 "register_operand" "=a,r")
1969         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1970   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1971   "@
1972    movabs{b}\t{%P1, %0|%0, %P1}
1973    mov{b}\t{%a1, %0|%0, %a1}"
1974   [(set_attr "type" "imov")
1975    (set_attr "modrm" "0,*")
1976    (set_attr "length_address" "8,0")
1977    (set_attr "length_immediate" "0")
1978    (set_attr "memory" "load")
1979    (set_attr "mode" "QI")])
1980
1981 (define_insn "*movdi_extzv_1"
1982   [(set (match_operand:DI 0 "register_operand" "=R")
1983         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1984                          (const_int 8)
1985                          (const_int 8)))]
1986   "TARGET_64BIT"
1987   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1988   [(set_attr "type" "imovx")
1989    (set_attr "mode" "DI")])
1990
1991 (define_insn "*movsi_extzv_1"
1992   [(set (match_operand:SI 0 "register_operand" "=R")
1993         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1994                          (const_int 8)
1995                          (const_int 8)))]
1996   ""
1997   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1998   [(set_attr "type" "imovx")
1999    (set_attr "mode" "SI")])
2000
2001 (define_insn "*movqi_extzv_2"
2002   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2003         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2004                                     (const_int 8)
2005                                     (const_int 8)) 0))]
2006   "!TARGET_64BIT"
2007 {
2008   switch (get_attr_type (insn))
2009     {
2010     case TYPE_IMOVX:
2011       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2012     default:
2013       return "mov{b}\t{%h1, %0|%0, %h1}";
2014     }
2015 }
2016   [(set (attr "type")
2017      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2018                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2019                              (ne (symbol_ref "TARGET_MOVX")
2020                                  (const_int 0))))
2021         (const_string "imovx")
2022         (const_string "imov")))
2023    (set (attr "mode")
2024      (if_then_else (eq_attr "type" "imovx")
2025         (const_string "SI")
2026         (const_string "QI")))])
2027
2028 (define_insn "*movqi_extzv_2_rex64"
2029   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2030         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2031                                     (const_int 8)
2032                                     (const_int 8)) 0))]
2033   "TARGET_64BIT"
2034 {
2035   switch (get_attr_type (insn))
2036     {
2037     case TYPE_IMOVX:
2038       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2039     default:
2040       return "mov{b}\t{%h1, %0|%0, %h1}";
2041     }
2042 }
2043   [(set (attr "type")
2044      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2045                         (ne (symbol_ref "TARGET_MOVX")
2046                             (const_int 0)))
2047         (const_string "imovx")
2048         (const_string "imov")))
2049    (set (attr "mode")
2050      (if_then_else (eq_attr "type" "imovx")
2051         (const_string "SI")
2052         (const_string "QI")))])
2053
2054 (define_insn "movsi_insv_1"
2055   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2056                          (const_int 8)
2057                          (const_int 8))
2058         (match_operand:SI 1 "general_operand" "Qmn"))]
2059   "!TARGET_64BIT"
2060   "mov{b}\t{%b1, %h0|%h0, %b1}"
2061   [(set_attr "type" "imov")
2062    (set_attr "mode" "QI")])
2063
2064 (define_insn "*movsi_insv_1_rex64"
2065   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2066                          (const_int 8)
2067                          (const_int 8))
2068         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2069   "TARGET_64BIT"
2070   "mov{b}\t{%b1, %h0|%h0, %b1}"
2071   [(set_attr "type" "imov")
2072    (set_attr "mode" "QI")])
2073
2074 (define_insn "movdi_insv_1_rex64"
2075   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2076                          (const_int 8)
2077                          (const_int 8))
2078         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2079   "TARGET_64BIT"
2080   "mov{b}\t{%b1, %h0|%h0, %b1}"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "QI")])
2083
2084 (define_insn "*movqi_insv_2"
2085   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2086                          (const_int 8)
2087                          (const_int 8))
2088         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2089                      (const_int 8)))]
2090   ""
2091   "mov{b}\t{%h1, %h0|%h0, %h1}"
2092   [(set_attr "type" "imov")
2093    (set_attr "mode" "QI")])
2094
2095 (define_expand "movdi"
2096   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2097         (match_operand:DI 1 "general_operand" ""))]
2098   ""
2099   "ix86_expand_move (DImode, operands); DONE;")
2100
2101 (define_insn "*pushdi"
2102   [(set (match_operand:DI 0 "push_operand" "=<")
2103         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2104   "!TARGET_64BIT"
2105   "#")
2106
2107 (define_insn "*pushdi2_rex64"
2108   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2109         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2110   "TARGET_64BIT"
2111   "@
2112    push{q}\t%1
2113    #"
2114   [(set_attr "type" "push,multi")
2115    (set_attr "mode" "DI")])
2116
2117 ;; Convert impossible pushes of immediate to existing instructions.
2118 ;; First try to get scratch register and go through it.  In case this
2119 ;; fails, push sign extended lower part first and then overwrite
2120 ;; upper part by 32bit move.
2121 (define_peephole2
2122   [(match_scratch:DI 2 "r")
2123    (set (match_operand:DI 0 "push_operand" "")
2124         (match_operand:DI 1 "immediate_operand" ""))]
2125   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2126    && !x86_64_immediate_operand (operands[1], DImode)"
2127   [(set (match_dup 2) (match_dup 1))
2128    (set (match_dup 0) (match_dup 2))]
2129   "")
2130
2131 ;; We need to define this as both peepholer and splitter for case
2132 ;; peephole2 pass is not run.
2133 ;; "&& 1" is needed to keep it from matching the previous pattern.
2134 (define_peephole2
2135   [(set (match_operand:DI 0 "push_operand" "")
2136         (match_operand:DI 1 "immediate_operand" ""))]
2137   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2138    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2139   [(set (match_dup 0) (match_dup 1))
2140    (set (match_dup 2) (match_dup 3))]
2141   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2142    operands[1] = gen_lowpart (DImode, operands[2]);
2143    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2144                                                     GEN_INT (4)));
2145   ")
2146
2147 (define_split
2148   [(set (match_operand:DI 0 "push_operand" "")
2149         (match_operand:DI 1 "immediate_operand" ""))]
2150   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151                     ? epilogue_completed : reload_completed)
2152    && !symbolic_operand (operands[1], DImode)
2153    && !x86_64_immediate_operand (operands[1], DImode)"
2154   [(set (match_dup 0) (match_dup 1))
2155    (set (match_dup 2) (match_dup 3))]
2156   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2157    operands[1] = gen_lowpart (DImode, operands[2]);
2158    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2159                                                     GEN_INT (4)));
2160   ")
2161
2162 (define_insn "*pushdi2_prologue_rex64"
2163   [(set (match_operand:DI 0 "push_operand" "=<")
2164         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2165    (clobber (mem:BLK (scratch)))]
2166   "TARGET_64BIT"
2167   "push{q}\t%1"
2168   [(set_attr "type" "push")
2169    (set_attr "mode" "DI")])
2170
2171 (define_insn "*popdi1_epilogue_rex64"
2172   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2173         (mem:DI (reg:DI SP_REG)))
2174    (set (reg:DI SP_REG)
2175         (plus:DI (reg:DI SP_REG) (const_int 8)))
2176    (clobber (mem:BLK (scratch)))]
2177   "TARGET_64BIT"
2178   "pop{q}\t%0"
2179   [(set_attr "type" "pop")
2180    (set_attr "mode" "DI")])
2181
2182 (define_insn "popdi1"
2183   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2184         (mem:DI (reg:DI SP_REG)))
2185    (set (reg:DI SP_REG)
2186         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2187   "TARGET_64BIT"
2188   "pop{q}\t%0"
2189   [(set_attr "type" "pop")
2190    (set_attr "mode" "DI")])
2191
2192 (define_insn "*movdi_xor_rex64"
2193   [(set (match_operand:DI 0 "register_operand" "=r")
2194         (match_operand:DI 1 "const0_operand" ""))
2195    (clobber (reg:CC FLAGS_REG))]
2196   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2197    && reload_completed"
2198   "xor{l}\t%k0, %k0";
2199   [(set_attr "type" "alu1")
2200    (set_attr "mode" "SI")
2201    (set_attr "length_immediate" "0")])
2202
2203 (define_insn "*movdi_or_rex64"
2204   [(set (match_operand:DI 0 "register_operand" "=r")
2205         (match_operand:DI 1 "const_int_operand" "i"))
2206    (clobber (reg:CC FLAGS_REG))]
2207   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2208    && reload_completed
2209    && operands[1] == constm1_rtx"
2210 {
2211   operands[1] = constm1_rtx;
2212   return "or{q}\t{%1, %0|%0, %1}";
2213 }
2214   [(set_attr "type" "alu1")
2215    (set_attr "mode" "DI")
2216    (set_attr "length_immediate" "1")])
2217
2218 (define_insn "*movdi_2"
2219   [(set (match_operand:DI 0 "nonimmediate_operand"
2220                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2221         (match_operand:DI 1 "general_operand"
2222                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2223   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2224   "@
2225    #
2226    #
2227    pxor\t%0, %0
2228    movq\t{%1, %0|%0, %1}
2229    movq\t{%1, %0|%0, %1}
2230    pxor\t%0, %0
2231    movq\t{%1, %0|%0, %1}
2232    movdqa\t{%1, %0|%0, %1}
2233    movq\t{%1, %0|%0, %1}
2234    xorps\t%0, %0
2235    movlps\t{%1, %0|%0, %1}
2236    movaps\t{%1, %0|%0, %1}
2237    movlps\t{%1, %0|%0, %1}"
2238   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2239    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2240
2241 (define_split
2242   [(set (match_operand:DI 0 "push_operand" "")
2243         (match_operand:DI 1 "general_operand" ""))]
2244   "!TARGET_64BIT && reload_completed
2245    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2246   [(const_int 0)]
2247   "ix86_split_long_move (operands); DONE;")
2248
2249 ;; %%% This multiword shite has got to go.
2250 (define_split
2251   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2252         (match_operand:DI 1 "general_operand" ""))]
2253   "!TARGET_64BIT && reload_completed
2254    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2255    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2256   [(const_int 0)]
2257   "ix86_split_long_move (operands); DONE;")
2258
2259 (define_insn "*movdi_1_rex64"
2260   [(set (match_operand:DI 0 "nonimmediate_operand"
2261           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2262         (match_operand:DI 1 "general_operand"
2263           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2264   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2265 {
2266   switch (get_attr_type (insn))
2267     {
2268     case TYPE_SSECVT:
2269       if (SSE_REG_P (operands[0]))
2270         return "movq2dq\t{%1, %0|%0, %1}";
2271       else
2272         return "movdq2q\t{%1, %0|%0, %1}";
2273
2274     case TYPE_SSEMOV:
2275       if (get_attr_mode (insn) == MODE_TI)
2276         return "movdqa\t{%1, %0|%0, %1}";
2277       /* FALLTHRU */
2278
2279     case TYPE_MMXMOV:
2280       /* Moves from and into integer register is done using movd
2281          opcode with REX prefix.  */
2282       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2283         return "movd\t{%1, %0|%0, %1}";
2284       return "movq\t{%1, %0|%0, %1}";
2285
2286     case TYPE_SSELOG1:
2287     case TYPE_MMXADD:
2288       return "pxor\t%0, %0";
2289
2290     case TYPE_MULTI:
2291       return "#";
2292
2293     case TYPE_LEA:
2294       return "lea{q}\t{%a1, %0|%0, %a1}";
2295
2296     default:
2297       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2298       if (get_attr_mode (insn) == MODE_SI)
2299         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2300       else if (which_alternative == 2)
2301         return "movabs{q}\t{%1, %0|%0, %1}";
2302       else
2303         return "mov{q}\t{%1, %0|%0, %1}";
2304     }
2305 }
2306   [(set (attr "type")
2307      (cond [(eq_attr "alternative" "5")
2308               (const_string "mmxadd")
2309             (eq_attr "alternative" "6,7,8,9,10")
2310               (const_string "mmxmov")
2311             (eq_attr "alternative" "11")
2312               (const_string "sselog1")
2313             (eq_attr "alternative" "12,13,14,15,16")
2314               (const_string "ssemov")
2315             (eq_attr "alternative" "17,18")
2316               (const_string "ssecvt")
2317             (eq_attr "alternative" "4")
2318               (const_string "multi")
2319             (match_operand:DI 1 "pic_32bit_operand" "")
2320               (const_string "lea")
2321            ]
2322            (const_string "imov")))
2323    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2324    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2325    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2326
2327 ;; Stores and loads of ax to arbitrary constant address.
2328 ;; We fake an second form of instruction to force reload to load address
2329 ;; into register when rax is not available
2330 (define_insn "*movabsdi_1_rex64"
2331   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2332         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2333   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2334   "@
2335    movabs{q}\t{%1, %P0|%P0, %1}
2336    mov{q}\t{%1, %a0|%a0, %1}"
2337   [(set_attr "type" "imov")
2338    (set_attr "modrm" "0,*")
2339    (set_attr "length_address" "8,0")
2340    (set_attr "length_immediate" "0,*")
2341    (set_attr "memory" "store")
2342    (set_attr "mode" "DI")])
2343
2344 (define_insn "*movabsdi_2_rex64"
2345   [(set (match_operand:DI 0 "register_operand" "=a,r")
2346         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2347   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2348   "@
2349    movabs{q}\t{%P1, %0|%0, %P1}
2350    mov{q}\t{%a1, %0|%0, %a1}"
2351   [(set_attr "type" "imov")
2352    (set_attr "modrm" "0,*")
2353    (set_attr "length_address" "8,0")
2354    (set_attr "length_immediate" "0")
2355    (set_attr "memory" "load")
2356    (set_attr "mode" "DI")])
2357
2358 ;; Convert impossible stores of immediate to existing instructions.
2359 ;; First try to get scratch register and go through it.  In case this
2360 ;; fails, move by 32bit parts.
2361 (define_peephole2
2362   [(match_scratch:DI 2 "r")
2363    (set (match_operand:DI 0 "memory_operand" "")
2364         (match_operand:DI 1 "immediate_operand" ""))]
2365   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2366    && !x86_64_immediate_operand (operands[1], DImode)"
2367   [(set (match_dup 2) (match_dup 1))
2368    (set (match_dup 0) (match_dup 2))]
2369   "")
2370
2371 ;; We need to define this as both peepholer and splitter for case
2372 ;; peephole2 pass is not run.
2373 ;; "&& 1" is needed to keep it from matching the previous pattern.
2374 (define_peephole2
2375   [(set (match_operand:DI 0 "memory_operand" "")
2376         (match_operand:DI 1 "immediate_operand" ""))]
2377   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2378    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2379   [(set (match_dup 2) (match_dup 3))
2380    (set (match_dup 4) (match_dup 5))]
2381   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2382
2383 (define_split
2384   [(set (match_operand:DI 0 "memory_operand" "")
2385         (match_operand:DI 1 "immediate_operand" ""))]
2386   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2387                     ? epilogue_completed : reload_completed)
2388    && !symbolic_operand (operands[1], DImode)
2389    && !x86_64_immediate_operand (operands[1], DImode)"
2390   [(set (match_dup 2) (match_dup 3))
2391    (set (match_dup 4) (match_dup 5))]
2392   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2393
2394 (define_insn "*swapdi_rex64"
2395   [(set (match_operand:DI 0 "register_operand" "+r")
2396         (match_operand:DI 1 "register_operand" "+r"))
2397    (set (match_dup 1)
2398         (match_dup 0))]
2399   "TARGET_64BIT"
2400   "xchg{q}\t%1, %0"
2401   [(set_attr "type" "imov")
2402    (set_attr "mode" "DI")
2403    (set_attr "pent_pair" "np")
2404    (set_attr "athlon_decode" "vector")
2405    (set_attr "amdfam10_decode" "double")])
2406
2407 (define_expand "movti"
2408   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2409         (match_operand:TI 1 "nonimmediate_operand" ""))]
2410   "TARGET_SSE || TARGET_64BIT"
2411 {
2412   if (TARGET_64BIT)
2413     ix86_expand_move (TImode, operands);
2414   else if (push_operand (operands[0], TImode))
2415     ix86_expand_push (TImode, operands[1]);
2416   else
2417     ix86_expand_vector_move (TImode, operands);
2418   DONE;
2419 })
2420
2421 (define_insn "*movti_internal"
2422   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2423         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2424   "TARGET_SSE && !TARGET_64BIT
2425    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2426 {
2427   switch (which_alternative)
2428     {
2429     case 0:
2430       if (get_attr_mode (insn) == MODE_V4SF)
2431         return "xorps\t%0, %0";
2432       else
2433         return "pxor\t%0, %0";
2434     case 1:
2435     case 2:
2436       /* TDmode values are passed as TImode on the stack.  Moving them
2437          to stack may result in unaligned memory access.  */
2438       if (misaligned_operand (operands[0], TImode)
2439           || misaligned_operand (operands[1], TImode))
2440         { 
2441           if (get_attr_mode (insn) == MODE_V4SF)
2442             return "movups\t{%1, %0|%0, %1}";
2443          else
2444            return "movdqu\t{%1, %0|%0, %1}";
2445         }
2446       else
2447         { 
2448           if (get_attr_mode (insn) == MODE_V4SF)
2449             return "movaps\t{%1, %0|%0, %1}";
2450          else
2451            return "movdqa\t{%1, %0|%0, %1}";
2452         }
2453     default:
2454       gcc_unreachable ();
2455     }
2456 }
2457   [(set_attr "type" "sselog1,ssemov,ssemov")
2458    (set (attr "mode")
2459         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2460                     (ne (symbol_ref "optimize_size") (const_int 0)))
2461                  (const_string "V4SF")
2462                (and (eq_attr "alternative" "2")
2463                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2464                         (const_int 0)))
2465                  (const_string "V4SF")]
2466               (const_string "TI")))])
2467
2468 (define_insn "*movti_rex64"
2469   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2470         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2471   "TARGET_64BIT
2472    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2473 {
2474   switch (which_alternative)
2475     {
2476     case 0:
2477     case 1:
2478       return "#";
2479     case 2:
2480       if (get_attr_mode (insn) == MODE_V4SF)
2481         return "xorps\t%0, %0";
2482       else
2483         return "pxor\t%0, %0";
2484     case 3:
2485     case 4:
2486       /* TDmode values are passed as TImode on the stack.  Moving them
2487          to stack may result in unaligned memory access.  */
2488       if (misaligned_operand (operands[0], TImode)
2489           || misaligned_operand (operands[1], TImode))
2490         { 
2491           if (get_attr_mode (insn) == MODE_V4SF)
2492             return "movups\t{%1, %0|%0, %1}";
2493          else
2494            return "movdqu\t{%1, %0|%0, %1}";
2495         }
2496       else
2497         { 
2498           if (get_attr_mode (insn) == MODE_V4SF)
2499             return "movaps\t{%1, %0|%0, %1}";
2500          else
2501            return "movdqa\t{%1, %0|%0, %1}";
2502         }
2503     default:
2504       gcc_unreachable ();
2505     }
2506 }
2507   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2508    (set (attr "mode")
2509         (cond [(eq_attr "alternative" "2,3")
2510                  (if_then_else
2511                    (ne (symbol_ref "optimize_size")
2512                        (const_int 0))
2513                    (const_string "V4SF")
2514                    (const_string "TI"))
2515                (eq_attr "alternative" "4")
2516                  (if_then_else
2517                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2518                             (const_int 0))
2519                         (ne (symbol_ref "optimize_size")
2520                             (const_int 0)))
2521                    (const_string "V4SF")
2522                    (const_string "TI"))]
2523                (const_string "DI")))])
2524
2525 (define_split
2526   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2527         (match_operand:TI 1 "general_operand" ""))]
2528   "reload_completed && !SSE_REG_P (operands[0])
2529    && !SSE_REG_P (operands[1])"
2530   [(const_int 0)]
2531   "ix86_split_long_move (operands); DONE;")
2532
2533 ;; This expands to what emit_move_complex would generate if we didn't
2534 ;; have a movti pattern.  Having this avoids problems with reload on
2535 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2536 ;; to have around all the time.
2537 (define_expand "movcdi"
2538   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2539         (match_operand:CDI 1 "general_operand" ""))]
2540   ""
2541 {
2542   if (push_operand (operands[0], CDImode))
2543     emit_move_complex_push (CDImode, operands[0], operands[1]);
2544   else
2545     emit_move_complex_parts (operands[0], operands[1]);
2546   DONE;
2547 })
2548
2549 (define_expand "movsf"
2550   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2551         (match_operand:SF 1 "general_operand" ""))]
2552   ""
2553   "ix86_expand_move (SFmode, operands); DONE;")
2554
2555 (define_insn "*pushsf"
2556   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2557         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2558   "!TARGET_64BIT"
2559 {
2560   /* Anything else should be already split before reg-stack.  */
2561   gcc_assert (which_alternative == 1);
2562   return "push{l}\t%1";
2563 }
2564   [(set_attr "type" "multi,push,multi")
2565    (set_attr "unit" "i387,*,*")
2566    (set_attr "mode" "SF,SI,SF")])
2567
2568 (define_insn "*pushsf_rex64"
2569   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2570         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2571   "TARGET_64BIT"
2572 {
2573   /* Anything else should be already split before reg-stack.  */
2574   gcc_assert (which_alternative == 1);
2575   return "push{q}\t%q1";
2576 }
2577   [(set_attr "type" "multi,push,multi")
2578    (set_attr "unit" "i387,*,*")
2579    (set_attr "mode" "SF,DI,SF")])
2580
2581 (define_split
2582   [(set (match_operand:SF 0 "push_operand" "")
2583         (match_operand:SF 1 "memory_operand" ""))]
2584   "reload_completed
2585    && MEM_P (operands[1])
2586    && (operands[2] = find_constant_src (insn))"
2587   [(set (match_dup 0)
2588         (match_dup 2))])
2589
2590
2591 ;; %%% Kill this when call knows how to work this out.
2592 (define_split
2593   [(set (match_operand:SF 0 "push_operand" "")
2594         (match_operand:SF 1 "any_fp_register_operand" ""))]
2595   "!TARGET_64BIT"
2596   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2597    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2598
2599 (define_split
2600   [(set (match_operand:SF 0 "push_operand" "")
2601         (match_operand:SF 1 "any_fp_register_operand" ""))]
2602   "TARGET_64BIT"
2603   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2604    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2605
2606 (define_insn "*movsf_1"
2607   [(set (match_operand:SF 0 "nonimmediate_operand"
2608           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2609         (match_operand:SF 1 "general_operand"
2610           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2611   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2612    && (reload_in_progress || reload_completed
2613        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2614        || (!TARGET_SSE_MATH && optimize_size
2615            && standard_80387_constant_p (operands[1]))
2616        || GET_CODE (operands[1]) != CONST_DOUBLE
2617        || memory_operand (operands[0], SFmode))"
2618 {
2619   switch (which_alternative)
2620     {
2621     case 0:
2622     case 1:
2623       return output_387_reg_move (insn, operands);
2624
2625     case 2:
2626       return standard_80387_constant_opcode (operands[1]);
2627
2628     case 3:
2629     case 4:
2630       return "mov{l}\t{%1, %0|%0, %1}";
2631     case 5:
2632       if (get_attr_mode (insn) == MODE_TI)
2633         return "pxor\t%0, %0";
2634       else
2635         return "xorps\t%0, %0";
2636     case 6:
2637       if (get_attr_mode (insn) == MODE_V4SF)
2638         return "movaps\t{%1, %0|%0, %1}";
2639       else
2640         return "movss\t{%1, %0|%0, %1}";
2641     case 7: case 8:
2642       return "movss\t{%1, %0|%0, %1}";
2643
2644     case 9: case 10:
2645     case 12: case 13: case 14: case 15:
2646       return "movd\t{%1, %0|%0, %1}";
2647
2648     case 11:
2649       return "movq\t{%1, %0|%0, %1}";
2650
2651     default:
2652       gcc_unreachable ();
2653     }
2654 }
2655   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2656    (set (attr "mode")
2657         (cond [(eq_attr "alternative" "3,4,9,10")
2658                  (const_string "SI")
2659                (eq_attr "alternative" "5")
2660                  (if_then_else
2661                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2662                                  (const_int 0))
2663                              (ne (symbol_ref "TARGET_SSE2")
2664                                  (const_int 0)))
2665                         (eq (symbol_ref "optimize_size")
2666                             (const_int 0)))
2667                    (const_string "TI")
2668                    (const_string "V4SF"))
2669                /* For architectures resolving dependencies on
2670                   whole SSE registers use APS move to break dependency
2671                   chains, otherwise use short move to avoid extra work.
2672
2673                   Do the same for architectures resolving dependencies on
2674                   the parts.  While in DF mode it is better to always handle
2675                   just register parts, the SF mode is different due to lack
2676                   of instructions to load just part of the register.  It is
2677                   better to maintain the whole registers in single format
2678                   to avoid problems on using packed logical operations.  */
2679                (eq_attr "alternative" "6")
2680                  (if_then_else
2681                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2682                             (const_int 0))
2683                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2684                             (const_int 0)))
2685                    (const_string "V4SF")
2686                    (const_string "SF"))
2687                (eq_attr "alternative" "11")
2688                  (const_string "DI")]
2689                (const_string "SF")))])
2690
2691 (define_insn "*swapsf"
2692   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2693         (match_operand:SF 1 "fp_register_operand" "+f"))
2694    (set (match_dup 1)
2695         (match_dup 0))]
2696   "reload_completed || TARGET_80387"
2697 {
2698   if (STACK_TOP_P (operands[0]))
2699     return "fxch\t%1";
2700   else
2701     return "fxch\t%0";
2702 }
2703   [(set_attr "type" "fxch")
2704    (set_attr "mode" "SF")])
2705
2706 (define_expand "movdf"
2707   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2708         (match_operand:DF 1 "general_operand" ""))]
2709   ""
2710   "ix86_expand_move (DFmode, operands); DONE;")
2711
2712 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2713 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2714 ;; On the average, pushdf using integers can be still shorter.  Allow this
2715 ;; pattern for optimize_size too.
2716
2717 (define_insn "*pushdf_nointeger"
2718   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2719         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2720   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2721 {
2722   /* This insn should be already split before reg-stack.  */
2723   gcc_unreachable ();
2724 }
2725   [(set_attr "type" "multi")
2726    (set_attr "unit" "i387,*,*,*")
2727    (set_attr "mode" "DF,SI,SI,DF")])
2728
2729 (define_insn "*pushdf_integer"
2730   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2731         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2732   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2733 {
2734   /* This insn should be already split before reg-stack.  */
2735   gcc_unreachable ();
2736 }
2737   [(set_attr "type" "multi")
2738    (set_attr "unit" "i387,*,*")
2739    (set_attr "mode" "DF,SI,DF")])
2740
2741 ;; %%% Kill this when call knows how to work this out.
2742 (define_split
2743   [(set (match_operand:DF 0 "push_operand" "")
2744         (match_operand:DF 1 "any_fp_register_operand" ""))]
2745   "reload_completed"
2746   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2747    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2748   "")
2749
2750 (define_split
2751   [(set (match_operand:DF 0 "push_operand" "")
2752         (match_operand:DF 1 "general_operand" ""))]
2753   "reload_completed"
2754   [(const_int 0)]
2755   "ix86_split_long_move (operands); DONE;")
2756
2757 ;; Moving is usually shorter when only FP registers are used. This separate
2758 ;; movdf pattern avoids the use of integer registers for FP operations
2759 ;; when optimizing for size.
2760
2761 (define_insn "*movdf_nointeger"
2762   [(set (match_operand:DF 0 "nonimmediate_operand"
2763                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2764         (match_operand:DF 1 "general_operand"
2765                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2766   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2767    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2768    && (reload_in_progress || reload_completed
2769        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2770        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2771            && !memory_operand (operands[0], DFmode)
2772            && standard_80387_constant_p (operands[1]))
2773        || GET_CODE (operands[1]) != CONST_DOUBLE
2774        || ((optimize_size
2775             || !TARGET_MEMORY_MISMATCH_STALL
2776             || reload_in_progress || reload_completed)
2777            && memory_operand (operands[0], DFmode)))"
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782     case 1:
2783       return output_387_reg_move (insn, operands);
2784
2785     case 2:
2786       return standard_80387_constant_opcode (operands[1]);
2787
2788     case 3:
2789     case 4:
2790       return "#";
2791     case 5:
2792       switch (get_attr_mode (insn))
2793         {
2794         case MODE_V4SF:
2795           return "xorps\t%0, %0";
2796         case MODE_V2DF:
2797           return "xorpd\t%0, %0";
2798         case MODE_TI:
2799           return "pxor\t%0, %0";
2800         default:
2801           gcc_unreachable ();
2802         }
2803     case 6:
2804     case 7:
2805     case 8:
2806       switch (get_attr_mode (insn))
2807         {
2808         case MODE_V4SF:
2809           return "movaps\t{%1, %0|%0, %1}";
2810         case MODE_V2DF:
2811           return "movapd\t{%1, %0|%0, %1}";
2812         case MODE_TI:
2813           return "movdqa\t{%1, %0|%0, %1}";
2814         case MODE_DI:
2815           return "movq\t{%1, %0|%0, %1}";
2816         case MODE_DF:
2817           return "movsd\t{%1, %0|%0, %1}";
2818         case MODE_V1DF:
2819           return "movlpd\t{%1, %0|%0, %1}";
2820         case MODE_V2SF:
2821           return "movlps\t{%1, %0|%0, %1}";
2822         default:
2823           gcc_unreachable ();
2824         }
2825
2826     default:
2827       gcc_unreachable ();
2828     }
2829 }
2830   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2831    (set (attr "mode")
2832         (cond [(eq_attr "alternative" "0,1,2")
2833                  (const_string "DF")
2834                (eq_attr "alternative" "3,4")
2835                  (const_string "SI")
2836
2837                /* For SSE1, we have many fewer alternatives.  */
2838                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2839                  (cond [(eq_attr "alternative" "5,6")
2840                           (const_string "V4SF")
2841                        ]
2842                    (const_string "V2SF"))
2843
2844                /* xorps is one byte shorter.  */
2845                (eq_attr "alternative" "5")
2846                  (cond [(ne (symbol_ref "optimize_size")
2847                             (const_int 0))
2848                           (const_string "V4SF")
2849                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2850                             (const_int 0))
2851                           (const_string "TI")
2852                        ]
2853                        (const_string "V2DF"))
2854
2855                /* For architectures resolving dependencies on
2856                   whole SSE registers use APD move to break dependency
2857                   chains, otherwise use short move to avoid extra work.
2858
2859                   movaps encodes one byte shorter.  */
2860                (eq_attr "alternative" "6")
2861                  (cond
2862                    [(ne (symbol_ref "optimize_size")
2863                         (const_int 0))
2864                       (const_string "V4SF")
2865                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2866                         (const_int 0))
2867                       (const_string "V2DF")
2868                    ]
2869                    (const_string "DF"))
2870                /* For architectures resolving dependencies on register
2871                   parts we may avoid extra work to zero out upper part
2872                   of register.  */
2873                (eq_attr "alternative" "7")
2874                  (if_then_else
2875                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2876                        (const_int 0))
2877                    (const_string "V1DF")
2878                    (const_string "DF"))
2879               ]
2880               (const_string "DF")))])
2881
2882 (define_insn "*movdf_integer_rex64"
2883   [(set (match_operand:DF 0 "nonimmediate_operand"
2884                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2885         (match_operand:DF 1 "general_operand"
2886                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2887   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888    && (reload_in_progress || reload_completed
2889        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2890        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2891            && standard_80387_constant_p (operands[1]))
2892        || GET_CODE (operands[1]) != CONST_DOUBLE
2893        || memory_operand (operands[0], DFmode))"
2894 {
2895   switch (which_alternative)
2896     {
2897     case 0:
2898     case 1:
2899       return output_387_reg_move (insn, operands);
2900
2901     case 2:
2902       return standard_80387_constant_opcode (operands[1]);
2903
2904     case 3:
2905     case 4:
2906       return "#";
2907
2908     case 5:
2909       switch (get_attr_mode (insn))
2910         {
2911         case MODE_V4SF:
2912           return "xorps\t%0, %0";
2913         case MODE_V2DF:
2914           return "xorpd\t%0, %0";
2915         case MODE_TI:
2916           return "pxor\t%0, %0";
2917         default:
2918           gcc_unreachable ();
2919         }
2920     case 6:
2921     case 7:
2922     case 8:
2923       switch (get_attr_mode (insn))
2924         {
2925         case MODE_V4SF:
2926           return "movaps\t{%1, %0|%0, %1}";
2927         case MODE_V2DF:
2928           return "movapd\t{%1, %0|%0, %1}";
2929         case MODE_TI:
2930           return "movdqa\t{%1, %0|%0, %1}";
2931         case MODE_DI:
2932           return "movq\t{%1, %0|%0, %1}";
2933         case MODE_DF:
2934           return "movsd\t{%1, %0|%0, %1}";
2935         case MODE_V1DF:
2936           return "movlpd\t{%1, %0|%0, %1}";
2937         case MODE_V2SF:
2938           return "movlps\t{%1, %0|%0, %1}";
2939         default:
2940           gcc_unreachable ();
2941         }
2942
2943     case 9:
2944     case 10:
2945       return "movd\t{%1, %0|%0, %1}";
2946
2947     default:
2948       gcc_unreachable();
2949     }
2950 }
2951   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2952    (set (attr "mode")
2953         (cond [(eq_attr "alternative" "0,1,2")
2954                  (const_string "DF")
2955                (eq_attr "alternative" "3,4,9,10")
2956                  (const_string "DI")
2957
2958                /* For SSE1, we have many fewer alternatives.  */
2959                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2960                  (cond [(eq_attr "alternative" "5,6")
2961                           (const_string "V4SF")
2962                        ]
2963                    (const_string "V2SF"))
2964
2965                /* xorps is one byte shorter.  */
2966                (eq_attr "alternative" "5")
2967                  (cond [(ne (symbol_ref "optimize_size")
2968                             (const_int 0))
2969                           (const_string "V4SF")
2970                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2971                             (const_int 0))
2972                           (const_string "TI")
2973                        ]
2974                        (const_string "V2DF"))
2975
2976                /* For architectures resolving dependencies on
2977                   whole SSE registers use APD move to break dependency
2978                   chains, otherwise use short move to avoid extra work.
2979
2980                   movaps encodes one byte shorter.  */
2981                (eq_attr "alternative" "6")
2982                  (cond
2983                    [(ne (symbol_ref "optimize_size")
2984                         (const_int 0))
2985                       (const_string "V4SF")
2986                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2987                         (const_int 0))
2988                       (const_string "V2DF")
2989                    ]
2990                    (const_string "DF"))
2991                /* For architectures resolving dependencies on register
2992                   parts we may avoid extra work to zero out upper part
2993                   of register.  */
2994                (eq_attr "alternative" "7")
2995                  (if_then_else
2996                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2997                        (const_int 0))
2998                    (const_string "V1DF")
2999                    (const_string "DF"))
3000               ]
3001               (const_string "DF")))])
3002
3003 (define_insn "*movdf_integer"
3004   [(set (match_operand:DF 0 "nonimmediate_operand"
3005                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3006         (match_operand:DF 1 "general_operand"
3007                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3008   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3009    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3010    && (reload_in_progress || reload_completed
3011        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3012        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3013            && standard_80387_constant_p (operands[1]))
3014        || GET_CODE (operands[1]) != CONST_DOUBLE
3015        || memory_operand (operands[0], DFmode))"
3016 {
3017   switch (which_alternative)
3018     {
3019     case 0:
3020     case 1:
3021       return output_387_reg_move (insn, operands);
3022
3023     case 2:
3024       return standard_80387_constant_opcode (operands[1]);
3025
3026     case 3:
3027     case 4:
3028       return "#";
3029
3030     case 5:
3031       switch (get_attr_mode (insn))
3032         {
3033         case MODE_V4SF:
3034           return "xorps\t%0, %0";
3035         case MODE_V2DF:
3036           return "xorpd\t%0, %0";
3037         case MODE_TI:
3038           return "pxor\t%0, %0";
3039         default:
3040           gcc_unreachable ();
3041         }
3042     case 6:
3043     case 7:
3044     case 8:
3045       switch (get_attr_mode (insn))
3046         {
3047         case MODE_V4SF:
3048           return "movaps\t{%1, %0|%0, %1}";
3049         case MODE_V2DF:
3050           return "movapd\t{%1, %0|%0, %1}";
3051         case MODE_TI:
3052           return "movdqa\t{%1, %0|%0, %1}";
3053         case MODE_DI:
3054           return "movq\t{%1, %0|%0, %1}";
3055         case MODE_DF:
3056           return "movsd\t{%1, %0|%0, %1}";
3057         case MODE_V1DF:
3058           return "movlpd\t{%1, %0|%0, %1}";
3059         case MODE_V2SF:
3060           return "movlps\t{%1, %0|%0, %1}";
3061         default:
3062           gcc_unreachable ();
3063         }
3064
3065     default:
3066       gcc_unreachable();
3067     }
3068 }
3069   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3070    (set (attr "mode")
3071         (cond [(eq_attr "alternative" "0,1,2")
3072                  (const_string "DF")
3073                (eq_attr "alternative" "3,4")
3074                  (const_string "SI")
3075
3076                /* For SSE1, we have many fewer alternatives.  */
3077                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3078                  (cond [(eq_attr "alternative" "5,6")
3079                           (const_string "V4SF")
3080                        ]
3081                    (const_string "V2SF"))
3082
3083                /* xorps is one byte shorter.  */
3084                (eq_attr "alternative" "5")
3085                  (cond [(ne (symbol_ref "optimize_size")
3086                             (const_int 0))
3087                           (const_string "V4SF")
3088                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3089                             (const_int 0))
3090                           (const_string "TI")
3091                        ]
3092                        (const_string "V2DF"))
3093
3094                /* For architectures resolving dependencies on
3095                   whole SSE registers use APD move to break dependency
3096                   chains, otherwise use short move to avoid extra work.
3097
3098                   movaps encodes one byte shorter.  */
3099                (eq_attr "alternative" "6")
3100                  (cond
3101                    [(ne (symbol_ref "optimize_size")
3102                         (const_int 0))
3103                       (const_string "V4SF")
3104                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3105                         (const_int 0))
3106                       (const_string "V2DF")
3107                    ]
3108                    (const_string "DF"))
3109                /* For architectures resolving dependencies on register
3110                   parts we may avoid extra work to zero out upper part
3111                   of register.  */
3112                (eq_attr "alternative" "7")
3113                  (if_then_else
3114                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3115                        (const_int 0))
3116                    (const_string "V1DF")
3117                    (const_string "DF"))
3118               ]
3119               (const_string "DF")))])
3120
3121 (define_split
3122   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3123         (match_operand:DF 1 "general_operand" ""))]
3124   "reload_completed
3125    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3126    && ! (ANY_FP_REG_P (operands[0]) ||
3127          (GET_CODE (operands[0]) == SUBREG
3128           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3129    && ! (ANY_FP_REG_P (operands[1]) ||
3130          (GET_CODE (operands[1]) == SUBREG
3131           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3132   [(const_int 0)]
3133   "ix86_split_long_move (operands); DONE;")
3134
3135 (define_insn "*swapdf"
3136   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3137         (match_operand:DF 1 "fp_register_operand" "+f"))
3138    (set (match_dup 1)
3139         (match_dup 0))]
3140   "reload_completed || TARGET_80387"
3141 {
3142   if (STACK_TOP_P (operands[0]))
3143     return "fxch\t%1";
3144   else
3145     return "fxch\t%0";
3146 }
3147   [(set_attr "type" "fxch")
3148    (set_attr "mode" "DF")])
3149
3150 (define_expand "movxf"
3151   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3152         (match_operand:XF 1 "general_operand" ""))]
3153   ""
3154   "ix86_expand_move (XFmode, operands); DONE;")
3155
3156 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3157 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3158 ;; Pushing using integer instructions is longer except for constants
3159 ;; and direct memory references.
3160 ;; (assuming that any given constant is pushed only once, but this ought to be
3161 ;;  handled elsewhere).
3162
3163 (define_insn "*pushxf_nointeger"
3164   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3165         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3166   "optimize_size"
3167 {
3168   /* This insn should be already split before reg-stack.  */
3169   gcc_unreachable ();
3170 }
3171   [(set_attr "type" "multi")
3172    (set_attr "unit" "i387,*,*")
3173    (set_attr "mode" "XF,SI,SI")])
3174
3175 (define_insn "*pushxf_integer"
3176   [(set (match_operand:XF 0 "push_operand" "=<,<")
3177         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3178   "!optimize_size"
3179 {
3180   /* This insn should be already split before reg-stack.  */
3181   gcc_unreachable ();
3182 }
3183   [(set_attr "type" "multi")
3184    (set_attr "unit" "i387,*")
3185    (set_attr "mode" "XF,SI")])
3186
3187 (define_split
3188   [(set (match_operand 0 "push_operand" "")
3189         (match_operand 1 "general_operand" ""))]
3190   "reload_completed
3191    && (GET_MODE (operands[0]) == XFmode
3192        || GET_MODE (operands[0]) == DFmode)
3193    && !ANY_FP_REG_P (operands[1])"
3194   [(const_int 0)]
3195   "ix86_split_long_move (operands); DONE;")
3196
3197 (define_split
3198   [(set (match_operand:XF 0 "push_operand" "")
3199         (match_operand:XF 1 "any_fp_register_operand" ""))]
3200   ""
3201   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3202    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3203   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3204
3205 ;; Do not use integer registers when optimizing for size
3206 (define_insn "*movxf_nointeger"
3207   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3208         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3209   "optimize_size
3210    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3211    && (reload_in_progress || reload_completed
3212        || (optimize_size && standard_80387_constant_p (operands[1]))
3213        || GET_CODE (operands[1]) != CONST_DOUBLE
3214        || memory_operand (operands[0], XFmode))"
3215 {
3216   switch (which_alternative)
3217     {
3218     case 0:
3219     case 1:
3220       return output_387_reg_move (insn, operands);
3221
3222     case 2:
3223       return standard_80387_constant_opcode (operands[1]);
3224
3225     case 3: case 4:
3226       return "#";
3227     default:
3228       gcc_unreachable ();
3229     }
3230 }
3231   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3232    (set_attr "mode" "XF,XF,XF,SI,SI")])
3233
3234 (define_insn "*movxf_integer"
3235   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3236         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3237   "!optimize_size
3238    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3239    && (reload_in_progress || reload_completed
3240        || (optimize_size && standard_80387_constant_p (operands[1]))
3241        || GET_CODE (operands[1]) != CONST_DOUBLE
3242        || memory_operand (operands[0], XFmode))"
3243 {
3244   switch (which_alternative)
3245     {
3246     case 0:
3247     case 1:
3248       return output_387_reg_move (insn, operands);
3249
3250     case 2:
3251       return standard_80387_constant_opcode (operands[1]);
3252
3253     case 3: case 4:
3254       return "#";
3255
3256     default:
3257       gcc_unreachable ();
3258     }
3259 }
3260   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3261    (set_attr "mode" "XF,XF,XF,SI,SI")])
3262
3263 (define_expand "movtf"
3264   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3265         (match_operand:TF 1 "nonimmediate_operand" ""))]
3266   "TARGET_SSE2"
3267 {
3268   ix86_expand_move (TFmode, operands);
3269   DONE;
3270 })
3271
3272 (define_insn "*movtf_internal"
3273   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3274         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3275   "TARGET_SSE2
3276    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3277 {
3278   switch (which_alternative)
3279     {
3280     case 0:
3281     case 1:
3282       if (get_attr_mode (insn) == MODE_V4SF)
3283         return "movaps\t{%1, %0|%0, %1}";
3284       else
3285         return "movdqa\t{%1, %0|%0, %1}";
3286     case 2:
3287       if (get_attr_mode (insn) == MODE_V4SF)
3288         return "xorps\t%0, %0";
3289       else
3290         return "pxor\t%0, %0";
3291     case 3:
3292     case 4:
3293         return "#";
3294     default:
3295       gcc_unreachable ();
3296     }
3297 }
3298   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3299    (set (attr "mode")
3300         (cond [(eq_attr "alternative" "0,2")
3301                  (if_then_else
3302                    (ne (symbol_ref "optimize_size")
3303                        (const_int 0))
3304                    (const_string "V4SF")
3305                    (const_string "TI"))
3306                (eq_attr "alternative" "1")
3307                  (if_then_else
3308                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3309                             (const_int 0))
3310                         (ne (symbol_ref "optimize_size")
3311                             (const_int 0)))
3312                    (const_string "V4SF")
3313                    (const_string "TI"))]
3314                (const_string "DI")))])
3315
3316 (define_insn "*pushtf_sse"
3317   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3318         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3319   "TARGET_SSE2"
3320 {
3321   /* This insn should be already split before reg-stack.  */
3322   gcc_unreachable ();
3323 }
3324   [(set_attr "type" "multi")
3325    (set_attr "unit" "sse,*,*")
3326    (set_attr "mode" "TF,SI,SI")])
3327
3328 (define_split
3329   [(set (match_operand:TF 0 "push_operand" "")
3330         (match_operand:TF 1 "general_operand" ""))]
3331   "TARGET_SSE2 && reload_completed
3332    && !SSE_REG_P (operands[1])"
3333   [(const_int 0)]
3334   "ix86_split_long_move (operands); DONE;")
3335
3336 (define_split
3337   [(set (match_operand:TF 0 "push_operand" "")
3338         (match_operand:TF 1 "any_fp_register_operand" ""))]
3339   "TARGET_SSE2"
3340   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3341    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3342   "")
3343
3344 (define_split
3345   [(set (match_operand 0 "nonimmediate_operand" "")
3346         (match_operand 1 "general_operand" ""))]
3347   "reload_completed
3348    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3349    && GET_MODE (operands[0]) == XFmode
3350    && ! (ANY_FP_REG_P (operands[0]) ||
3351          (GET_CODE (operands[0]) == SUBREG
3352           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3353    && ! (ANY_FP_REG_P (operands[1]) ||
3354          (GET_CODE (operands[1]) == SUBREG
3355           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3356   [(const_int 0)]
3357   "ix86_split_long_move (operands); DONE;")
3358
3359 (define_split
3360   [(set (match_operand 0 "register_operand" "")
3361         (match_operand 1 "memory_operand" ""))]
3362   "reload_completed
3363    && MEM_P (operands[1])
3364    && (GET_MODE (operands[0]) == TFmode
3365        || GET_MODE (operands[0]) == XFmode
3366        || GET_MODE (operands[0]) == SFmode
3367        || GET_MODE (operands[0]) == DFmode)
3368    && (operands[2] = find_constant_src (insn))"
3369   [(set (match_dup 0) (match_dup 2))]
3370 {
3371   rtx c = operands[2];
3372   rtx r = operands[0];
3373
3374   if (GET_CODE (r) == SUBREG)
3375     r = SUBREG_REG (r);
3376
3377   if (SSE_REG_P (r))
3378     {
3379       if (!standard_sse_constant_p (c))
3380         FAIL;
3381     }
3382   else if (FP_REG_P (r))
3383     {
3384       if (!standard_80387_constant_p (c))
3385         FAIL;
3386     }
3387   else if (MMX_REG_P (r))
3388     FAIL;
3389 })
3390
3391 (define_split
3392   [(set (match_operand 0 "register_operand" "")
3393         (float_extend (match_operand 1 "memory_operand" "")))]
3394   "reload_completed
3395    && MEM_P (operands[1])
3396    && (GET_MODE (operands[0]) == TFmode
3397        || GET_MODE (operands[0]) == XFmode
3398        || GET_MODE (operands[0]) == SFmode
3399        || GET_MODE (operands[0]) == DFmode)
3400    && (operands[2] = find_constant_src (insn))"
3401   [(set (match_dup 0) (match_dup 2))]
3402 {
3403   rtx c = operands[2];
3404   rtx r = operands[0];
3405
3406   if (GET_CODE (r) == SUBREG)
3407     r = SUBREG_REG (r);
3408
3409   if (SSE_REG_P (r))
3410     {
3411       if (!standard_sse_constant_p (c))
3412         FAIL;
3413     }
3414   else if (FP_REG_P (r))
3415     {
3416       if (!standard_80387_constant_p (c))
3417         FAIL;
3418     }
3419   else if (MMX_REG_P (r))
3420     FAIL;
3421 })
3422
3423 (define_insn "swapxf"
3424   [(set (match_operand:XF 0 "register_operand" "+f")
3425         (match_operand:XF 1 "register_operand" "+f"))
3426    (set (match_dup 1)
3427         (match_dup 0))]
3428   "TARGET_80387"
3429 {
3430   if (STACK_TOP_P (operands[0]))
3431     return "fxch\t%1";
3432   else
3433     return "fxch\t%0";
3434 }
3435   [(set_attr "type" "fxch")
3436    (set_attr "mode" "XF")])
3437
3438 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3439 (define_split
3440   [(set (match_operand:X87MODEF 0 "register_operand" "")
3441         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3442   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3443    && (standard_80387_constant_p (operands[1]) == 8
3444        || standard_80387_constant_p (operands[1]) == 9)"
3445   [(set (match_dup 0)(match_dup 1))
3446    (set (match_dup 0)
3447         (neg:X87MODEF (match_dup 0)))]
3448 {
3449   REAL_VALUE_TYPE r;
3450
3451   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3452   if (real_isnegzero (&r))
3453     operands[1] = CONST0_RTX (<MODE>mode);
3454   else
3455     operands[1] = CONST1_RTX (<MODE>mode);
3456 })
3457
3458 (define_split
3459   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3460         (match_operand:TF 1 "general_operand" ""))]
3461   "reload_completed
3462    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3463   [(const_int 0)]
3464   "ix86_split_long_move (operands); DONE;")
3465 \f
3466 ;; Zero extension instructions
3467
3468 (define_expand "zero_extendhisi2"
3469   [(set (match_operand:SI 0 "register_operand" "")
3470      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3471   ""
3472 {
3473   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3474     {
3475       operands[1] = force_reg (HImode, operands[1]);
3476       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3477       DONE;
3478     }
3479 })
3480
3481 (define_insn "zero_extendhisi2_and"
3482   [(set (match_operand:SI 0 "register_operand" "=r")
3483      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3484    (clobber (reg:CC FLAGS_REG))]
3485   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3486   "#"
3487   [(set_attr "type" "alu1")
3488    (set_attr "mode" "SI")])
3489
3490 (define_split
3491   [(set (match_operand:SI 0 "register_operand" "")
3492         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3493    (clobber (reg:CC FLAGS_REG))]
3494   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3495   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3496               (clobber (reg:CC FLAGS_REG))])]
3497   "")
3498
3499 (define_insn "*zero_extendhisi2_movzwl"
3500   [(set (match_operand:SI 0 "register_operand" "=r")
3501      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3502   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3503   "movz{wl|x}\t{%1, %0|%0, %1}"
3504   [(set_attr "type" "imovx")
3505    (set_attr "mode" "SI")])
3506
3507 (define_expand "zero_extendqihi2"
3508   [(parallel
3509     [(set (match_operand:HI 0 "register_operand" "")
3510        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3511      (clobber (reg:CC FLAGS_REG))])]
3512   ""
3513   "")
3514
3515 (define_insn "*zero_extendqihi2_and"
3516   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3517      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3518    (clobber (reg:CC FLAGS_REG))]
3519   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3520   "#"
3521   [(set_attr "type" "alu1")
3522    (set_attr "mode" "HI")])
3523
3524 (define_insn "*zero_extendqihi2_movzbw_and"
3525   [(set (match_operand:HI 0 "register_operand" "=r,r")
3526      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527    (clobber (reg:CC FLAGS_REG))]
3528   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3529   "#"
3530   [(set_attr "type" "imovx,alu1")
3531    (set_attr "mode" "HI")])
3532
3533 ; zero extend to SImode here to avoid partial register stalls
3534 (define_insn "*zero_extendqihi2_movzbl"
3535   [(set (match_operand:HI 0 "register_operand" "=r")
3536      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3537   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3538   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3539   [(set_attr "type" "imovx")
3540    (set_attr "mode" "SI")])
3541
3542 ;; For the movzbw case strip only the clobber
3543 (define_split
3544   [(set (match_operand:HI 0 "register_operand" "")
3545         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3546    (clobber (reg:CC FLAGS_REG))]
3547   "reload_completed
3548    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3549    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3550   [(set (match_operand:HI 0 "register_operand" "")
3551         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3552
3553 ;; When source and destination does not overlap, clear destination
3554 ;; first and then do the movb
3555 (define_split
3556   [(set (match_operand:HI 0 "register_operand" "")
3557         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3558    (clobber (reg:CC FLAGS_REG))]
3559   "reload_completed
3560    && ANY_QI_REG_P (operands[0])
3561    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3562    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3563   [(set (match_dup 0) (const_int 0))
3564    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3565   "operands[2] = gen_lowpart (QImode, operands[0]);")
3566
3567 ;; Rest is handled by single and.
3568 (define_split
3569   [(set (match_operand:HI 0 "register_operand" "")
3570         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3571    (clobber (reg:CC FLAGS_REG))]
3572   "reload_completed
3573    && true_regnum (operands[0]) == true_regnum (operands[1])"
3574   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3575               (clobber (reg:CC FLAGS_REG))])]
3576   "")
3577
3578 (define_expand "zero_extendqisi2"
3579   [(parallel
3580     [(set (match_operand:SI 0 "register_operand" "")
3581        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3582      (clobber (reg:CC FLAGS_REG))])]
3583   ""
3584   "")
3585
3586 (define_insn "*zero_extendqisi2_and"
3587   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3588      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3589    (clobber (reg:CC FLAGS_REG))]
3590   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3591   "#"
3592   [(set_attr "type" "alu1")
3593    (set_attr "mode" "SI")])
3594
3595 (define_insn "*zero_extendqisi2_movzbw_and"
3596   [(set (match_operand:SI 0 "register_operand" "=r,r")
3597      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3598    (clobber (reg:CC FLAGS_REG))]
3599   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3600   "#"
3601   [(set_attr "type" "imovx,alu1")
3602    (set_attr "mode" "SI")])
3603
3604 (define_insn "*zero_extendqisi2_movzbw"
3605   [(set (match_operand:SI 0 "register_operand" "=r")
3606      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3607   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3608   "movz{bl|x}\t{%1, %0|%0, %1}"
3609   [(set_attr "type" "imovx")
3610    (set_attr "mode" "SI")])
3611
3612 ;; For the movzbl case strip only the clobber
3613 (define_split
3614   [(set (match_operand:SI 0 "register_operand" "")
3615         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3616    (clobber (reg:CC FLAGS_REG))]
3617   "reload_completed
3618    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3619    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3620   [(set (match_dup 0)
3621         (zero_extend:SI (match_dup 1)))])
3622
3623 ;; When source and destination does not overlap, clear destination
3624 ;; first and then do the movb
3625 (define_split
3626   [(set (match_operand:SI 0 "register_operand" "")
3627         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3628    (clobber (reg:CC FLAGS_REG))]
3629   "reload_completed
3630    && ANY_QI_REG_P (operands[0])
3631    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3632    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3633    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3634   [(set (match_dup 0) (const_int 0))
3635    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3636   "operands[2] = gen_lowpart (QImode, operands[0]);")
3637
3638 ;; Rest is handled by single and.
3639 (define_split
3640   [(set (match_operand:SI 0 "register_operand" "")
3641         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3642    (clobber (reg:CC FLAGS_REG))]
3643   "reload_completed
3644    && true_regnum (operands[0]) == true_regnum (operands[1])"
3645   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3646               (clobber (reg:CC FLAGS_REG))])]
3647   "")
3648
3649 ;; %%% Kill me once multi-word ops are sane.
3650 (define_expand "zero_extendsidi2"
3651   [(set (match_operand:DI 0 "register_operand" "")
3652      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3653   ""
3654 {
3655   if (!TARGET_64BIT)
3656     {
3657       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3658       DONE;
3659     }
3660 })
3661
3662 (define_insn "zero_extendsidi2_32"
3663   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3664         (zero_extend:DI
3665          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3666    (clobber (reg:CC FLAGS_REG))]
3667   "!TARGET_64BIT"
3668   "@
3669    #
3670    #
3671    #
3672    movd\t{%1, %0|%0, %1}
3673    movd\t{%1, %0|%0, %1}
3674    movd\t{%1, %0|%0, %1}
3675    movd\t{%1, %0|%0, %1}"
3676   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3677    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3678
3679 (define_insn "zero_extendsidi2_rex64"
3680   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3681      (zero_extend:DI
3682        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3683   "TARGET_64BIT"
3684   "@
3685    mov\t{%k1, %k0|%k0, %k1}
3686    #
3687    movd\t{%1, %0|%0, %1}
3688    movd\t{%1, %0|%0, %1}
3689    movd\t{%1, %0|%0, %1}
3690    movd\t{%1, %0|%0, %1}"
3691   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3692    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3693
3694 (define_split
3695   [(set (match_operand:DI 0 "memory_operand" "")
3696      (zero_extend:DI (match_dup 0)))]
3697   "TARGET_64BIT"
3698   [(set (match_dup 4) (const_int 0))]
3699   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3700
3701 (define_split
3702   [(set (match_operand:DI 0 "register_operand" "")
3703         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3704    (clobber (reg:CC FLAGS_REG))]
3705   "!TARGET_64BIT && reload_completed
3706    && true_regnum (operands[0]) == true_regnum (operands[1])"
3707   [(set (match_dup 4) (const_int 0))]
3708   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3709
3710 (define_split
3711   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3712         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3713    (clobber (reg:CC FLAGS_REG))]
3714   "!TARGET_64BIT && reload_completed
3715    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3716   [(set (match_dup 3) (match_dup 1))
3717    (set (match_dup 4) (const_int 0))]
3718   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3719
3720 (define_insn "zero_extendhidi2"
3721   [(set (match_operand:DI 0 "register_operand" "=r")
3722      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3723   "TARGET_64BIT"
3724   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3725   [(set_attr "type" "imovx")
3726    (set_attr "mode" "DI")])
3727
3728 (define_insn "zero_extendqidi2"
3729   [(set (match_operand:DI 0 "register_operand" "=r")
3730      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3731   "TARGET_64BIT"
3732   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3733   [(set_attr "type" "imovx")
3734    (set_attr "mode" "DI")])
3735 \f
3736 ;; Sign extension instructions
3737
3738 (define_expand "extendsidi2"
3739   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3740                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3741               (clobber (reg:CC FLAGS_REG))
3742               (clobber (match_scratch:SI 2 ""))])]
3743   ""
3744 {
3745   if (TARGET_64BIT)
3746     {
3747       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3748       DONE;
3749     }
3750 })
3751
3752 (define_insn "*extendsidi2_1"
3753   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3754         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3755    (clobber (reg:CC FLAGS_REG))
3756    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3757   "!TARGET_64BIT"
3758   "#")
3759
3760 (define_insn "extendsidi2_rex64"
3761   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3762         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3763   "TARGET_64BIT"
3764   "@
3765    {cltq|cdqe}
3766    movs{lq|x}\t{%1,%0|%0, %1}"
3767   [(set_attr "type" "imovx")
3768    (set_attr "mode" "DI")
3769    (set_attr "prefix_0f" "0")
3770    (set_attr "modrm" "0,1")])
3771
3772 (define_insn "extendhidi2"
3773   [(set (match_operand:DI 0 "register_operand" "=r")
3774         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3775   "TARGET_64BIT"
3776   "movs{wq|x}\t{%1,%0|%0, %1}"
3777   [(set_attr "type" "imovx")
3778    (set_attr "mode" "DI")])
3779
3780 (define_insn "extendqidi2"
3781   [(set (match_operand:DI 0 "register_operand" "=r")
3782         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3783   "TARGET_64BIT"
3784   "movs{bq|x}\t{%1,%0|%0, %1}"
3785    [(set_attr "type" "imovx")
3786     (set_attr "mode" "DI")])
3787
3788 ;; Extend to memory case when source register does die.
3789 (define_split
3790   [(set (match_operand:DI 0 "memory_operand" "")
3791         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3792    (clobber (reg:CC FLAGS_REG))
3793    (clobber (match_operand:SI 2 "register_operand" ""))]
3794   "(reload_completed
3795     && dead_or_set_p (insn, operands[1])
3796     && !reg_mentioned_p (operands[1], operands[0]))"
3797   [(set (match_dup 3) (match_dup 1))
3798    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3799               (clobber (reg:CC FLAGS_REG))])
3800    (set (match_dup 4) (match_dup 1))]
3801   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3802
3803 ;; Extend to memory case when source register does not die.
3804 (define_split
3805   [(set (match_operand:DI 0 "memory_operand" "")
3806         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807    (clobber (reg:CC FLAGS_REG))
3808    (clobber (match_operand:SI 2 "register_operand" ""))]
3809   "reload_completed"
3810   [(const_int 0)]
3811 {
3812   split_di (&operands[0], 1, &operands[3], &operands[4]);
3813
3814   emit_move_insn (operands[3], operands[1]);
3815
3816   /* Generate a cltd if possible and doing so it profitable.  */
3817   if ((optimize_size || TARGET_USE_CLTD)
3818       && true_regnum (operands[1]) == AX_REG
3819       && true_regnum (operands[2]) == DX_REG)
3820     {
3821       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3822     }
3823   else
3824     {
3825       emit_move_insn (operands[2], operands[1]);
3826       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3827     }
3828   emit_move_insn (operands[4], operands[2]);
3829   DONE;
3830 })
3831
3832 ;; Extend to register case.  Optimize case where source and destination
3833 ;; registers match and cases where we can use cltd.
3834 (define_split
3835   [(set (match_operand:DI 0 "register_operand" "")
3836         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3837    (clobber (reg:CC FLAGS_REG))
3838    (clobber (match_scratch:SI 2 ""))]
3839   "reload_completed"
3840   [(const_int 0)]
3841 {
3842   split_di (&operands[0], 1, &operands[3], &operands[4]);
3843
3844   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3845     emit_move_insn (operands[3], operands[1]);
3846
3847   /* Generate a cltd if possible and doing so it profitable.  */
3848   if ((optimize_size || TARGET_USE_CLTD)
3849       && true_regnum (operands[3]) == AX_REG)
3850     {
3851       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3852       DONE;
3853     }
3854
3855   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3856     emit_move_insn (operands[4], operands[1]);
3857
3858   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3859   DONE;
3860 })
3861
3862 (define_insn "extendhisi2"
3863   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3864         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3865   ""
3866 {
3867   switch (get_attr_prefix_0f (insn))
3868     {
3869     case 0:
3870       return "{cwtl|cwde}";
3871     default:
3872       return "movs{wl|x}\t{%1,%0|%0, %1}";
3873     }
3874 }
3875   [(set_attr "type" "imovx")
3876    (set_attr "mode" "SI")
3877    (set (attr "prefix_0f")
3878      ;; movsx is short decodable while cwtl is vector decoded.
3879      (if_then_else (and (eq_attr "cpu" "!k6")
3880                         (eq_attr "alternative" "0"))
3881         (const_string "0")
3882         (const_string "1")))
3883    (set (attr "modrm")
3884      (if_then_else (eq_attr "prefix_0f" "0")
3885         (const_string "0")
3886         (const_string "1")))])
3887
3888 (define_insn "*extendhisi2_zext"
3889   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3890         (zero_extend:DI
3891           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3892   "TARGET_64BIT"
3893 {
3894   switch (get_attr_prefix_0f (insn))
3895     {
3896     case 0:
3897       return "{cwtl|cwde}";
3898     default:
3899       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3900     }
3901 }
3902   [(set_attr "type" "imovx")
3903    (set_attr "mode" "SI")
3904    (set (attr "prefix_0f")
3905      ;; movsx is short decodable while cwtl is vector decoded.
3906      (if_then_else (and (eq_attr "cpu" "!k6")
3907                         (eq_attr "alternative" "0"))
3908         (const_string "0")
3909         (const_string "1")))
3910    (set (attr "modrm")
3911      (if_then_else (eq_attr "prefix_0f" "0")
3912         (const_string "0")
3913         (const_string "1")))])
3914
3915 (define_insn "extendqihi2"
3916   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3917         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3918   ""
3919 {
3920   switch (get_attr_prefix_0f (insn))
3921     {
3922     case 0:
3923       return "{cbtw|cbw}";
3924     default:
3925       return "movs{bw|x}\t{%1,%0|%0, %1}";
3926     }
3927 }
3928   [(set_attr "type" "imovx")
3929    (set_attr "mode" "HI")
3930    (set (attr "prefix_0f")
3931      ;; movsx is short decodable while cwtl is vector decoded.
3932      (if_then_else (and (eq_attr "cpu" "!k6")
3933                         (eq_attr "alternative" "0"))
3934         (const_string "0")
3935         (const_string "1")))
3936    (set (attr "modrm")
3937      (if_then_else (eq_attr "prefix_0f" "0")
3938         (const_string "0")
3939         (const_string "1")))])
3940
3941 (define_insn "extendqisi2"
3942   [(set (match_operand:SI 0 "register_operand" "=r")
3943         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3944   ""
3945   "movs{bl|x}\t{%1,%0|%0, %1}"
3946    [(set_attr "type" "imovx")
3947     (set_attr "mode" "SI")])
3948
3949 (define_insn "*extendqisi2_zext"
3950   [(set (match_operand:DI 0 "register_operand" "=r")
3951         (zero_extend:DI
3952           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3953   "TARGET_64BIT"
3954   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3955    [(set_attr "type" "imovx")
3956     (set_attr "mode" "SI")])
3957 \f
3958 ;; Conversions between float and double.
3959
3960 ;; These are all no-ops in the model used for the 80387.  So just
3961 ;; emit moves.
3962
3963 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3964 (define_insn "*dummy_extendsfdf2"
3965   [(set (match_operand:DF 0 "push_operand" "=<")
3966         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3967   "0"
3968   "#")
3969
3970 (define_split
3971   [(set (match_operand:DF 0 "push_operand" "")
3972         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3973   ""
3974   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3975    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3976
3977 (define_insn "*dummy_extendsfxf2"
3978   [(set (match_operand:XF 0 "push_operand" "=<")
3979         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3980   "0"
3981   "#")
3982
3983 (define_split
3984   [(set (match_operand:XF 0 "push_operand" "")
3985         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3986   ""
3987   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3988    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3989   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3990
3991 (define_split
3992   [(set (match_operand:XF 0 "push_operand" "")
3993         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3994   ""
3995   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3996    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3997   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3998
3999 (define_expand "extendsfdf2"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4003 {
4004   /* ??? Needed for compress_float_constant since all fp constants
4005      are LEGITIMATE_CONSTANT_P.  */
4006   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4007     {
4008       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009           && standard_80387_constant_p (operands[1]) > 0)
4010         {
4011           operands[1] = simplify_const_unary_operation
4012             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013           emit_move_insn_1 (operands[0], operands[1]);
4014           DONE;
4015         }
4016       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4017     }
4018 })
4019
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4021    cvtss2sd:
4022       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4023       cvtps2pd xmm2,xmm1
4024    We do the conversion post reload to avoid producing of 128bit spills
4025    that might lead to ICE on 32bit target.  The sequence unlikely combine
4026    anyway.  */
4027 (define_split
4028   [(set (match_operand:DF 0 "register_operand" "")
4029         (float_extend:DF
4030           (match_operand:SF 1 "nonimmediate_operand" "")))]
4031   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4032    && reload_completed && SSE_REG_P (operands[0])"
4033    [(set (match_dup 2)
4034          (float_extend:V2DF
4035            (vec_select:V2SF
4036              (match_dup 3)
4037              (parallel [(const_int 0) (const_int 1)]))))]
4038 {
4039   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4040   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4041   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4042      Try to avoid move when unpacking can be done in source.  */
4043   if (REG_P (operands[1]))
4044     {
4045       /* If it is unsafe to overwrite upper half of source, we need
4046          to move to destination and unpack there.  */
4047       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4048            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4049           && true_regnum (operands[0]) != true_regnum (operands[1]))
4050         {
4051           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4052           emit_move_insn (tmp, operands[1]);
4053         }
4054       else
4055         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4056       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4057     }
4058   else
4059     emit_insn (gen_vec_setv4sf_0 (operands[3],
4060                                   CONST0_RTX (V4SFmode), operands[1]));
4061 })
4062
4063 (define_insn "*extendsfdf2_mixed"
4064   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4065         (float_extend:DF
4066           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4067   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4068 {
4069   switch (which_alternative)
4070     {
4071     case 0:
4072     case 1:
4073       return output_387_reg_move (insn, operands);
4074
4075     case 2:
4076       return "cvtss2sd\t{%1, %0|%0, %1}";
4077
4078     default:
4079       gcc_unreachable ();
4080     }
4081 }
4082   [(set_attr "type" "fmov,fmov,ssecvt")
4083    (set_attr "mode" "SF,XF,DF")])
4084
4085 (define_insn "*extendsfdf2_sse"
4086   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4087         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4088   "TARGET_SSE2 && TARGET_SSE_MATH"
4089   "cvtss2sd\t{%1, %0|%0, %1}"
4090   [(set_attr "type" "ssecvt")
4091    (set_attr "mode" "DF")])
4092
4093 (define_insn "*extendsfdf2_i387"
4094   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4095         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4096   "TARGET_80387"
4097   "* return output_387_reg_move (insn, operands);"
4098   [(set_attr "type" "fmov")
4099    (set_attr "mode" "SF,XF")])
4100
4101 (define_expand "extend<mode>xf2"
4102   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4103         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4104   "TARGET_80387"
4105 {
4106   /* ??? Needed for compress_float_constant since all fp constants
4107      are LEGITIMATE_CONSTANT_P.  */
4108   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4109     {
4110       if (standard_80387_constant_p (operands[1]) > 0)
4111         {
4112           operands[1] = simplify_const_unary_operation
4113             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4114           emit_move_insn_1 (operands[0], operands[1]);
4115           DONE;
4116         }
4117       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4118     }
4119 })
4120
4121 (define_insn "*extend<mode>xf2_i387"
4122   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4123         (float_extend:XF
4124           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4125   "TARGET_80387"
4126   "* return output_387_reg_move (insn, operands);"
4127   [(set_attr "type" "fmov")
4128    (set_attr "mode" "<MODE>,XF")])
4129
4130 ;; %%% This seems bad bad news.
4131 ;; This cannot output into an f-reg because there is no way to be sure
4132 ;; of truncating in that case.  Otherwise this is just like a simple move
4133 ;; insn.  So we pretend we can output to a reg in order to get better
4134 ;; register preferencing, but we really use a stack slot.
4135
4136 ;; Conversion from DFmode to SFmode.
4137
4138 (define_expand "truncdfsf2"
4139   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4140         (float_truncate:SF
4141           (match_operand:DF 1 "nonimmediate_operand" "")))]
4142   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4143 {
4144   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4145     ;
4146   else if (flag_unsafe_math_optimizations)
4147     ;
4148   else
4149     {
4150       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4151       rtx temp = assign_386_stack_local (SFmode, slot);
4152       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4153       DONE;
4154     }
4155 })
4156
4157 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4158    cvtsd2ss:
4159       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4160       cvtpd2ps xmm2,xmm1
4161    We do the conversion post reload to avoid producing of 128bit spills
4162    that might lead to ICE on 32bit target.  The sequence unlikely combine
4163    anyway.  */
4164 (define_split
4165   [(set (match_operand:SF 0 "register_operand" "")
4166         (float_truncate:SF
4167           (match_operand:DF 1 "nonimmediate_operand" "")))]
4168   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4169    && reload_completed && SSE_REG_P (operands[0])"
4170    [(set (match_dup 2)
4171          (vec_concat:V4SF
4172            (float_truncate:V2SF
4173              (match_dup 4))
4174            (match_dup 3)))]
4175 {
4176   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177   operands[3] = CONST0_RTX (V2SFmode);
4178   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179   /* Use movsd for loading from memory, unpcklpd for registers.
4180      Try to avoid move when unpacking can be done in source, or SSE3
4181      movddup is available.  */
4182   if (REG_P (operands[1]))
4183     {
4184       if (!TARGET_SSE3
4185           && true_regnum (operands[0]) != true_regnum (operands[1])
4186           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4188         {
4189           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190           emit_move_insn (tmp, operands[1]);
4191           operands[1] = tmp;
4192         }
4193       else if (!TARGET_SSE3)
4194         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4196     }
4197   else
4198     emit_insn (gen_sse2_loadlpd (operands[4],
4199                                  CONST0_RTX (V2DFmode), operands[1]));
4200 })
4201
4202 (define_expand "truncdfsf2_with_temp"
4203   [(parallel [(set (match_operand:SF 0 "" "")
4204                    (float_truncate:SF (match_operand:DF 1 "" "")))
4205               (clobber (match_operand:SF 2 "" ""))])]
4206   "")
4207
4208 (define_insn "*truncdfsf_fast_mixed"
4209   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4210         (float_truncate:SF
4211           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4212   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4213 {
4214   switch (which_alternative)
4215     {
4216     case 0:
4217       return output_387_reg_move (insn, operands);
4218     case 1:
4219       return "cvtsd2ss\t{%1, %0|%0, %1}";
4220     default:
4221       gcc_unreachable ();
4222     }
4223 }
4224   [(set_attr "type" "fmov,ssecvt")
4225    (set_attr "mode" "SF")])
4226
4227 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4228 ;; because nothing we do here is unsafe.
4229 (define_insn "*truncdfsf_fast_sse"
4230   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4231         (float_truncate:SF
4232           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4233   "TARGET_SSE2 && TARGET_SSE_MATH"
4234   "cvtsd2ss\t{%1, %0|%0, %1}"
4235   [(set_attr "type" "ssecvt")
4236    (set_attr "mode" "SF")])
4237
4238 (define_insn "*truncdfsf_fast_i387"
4239   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4240         (float_truncate:SF
4241           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242   "TARGET_80387 && flag_unsafe_math_optimizations"
4243   "* return output_387_reg_move (insn, operands);"
4244   [(set_attr "type" "fmov")
4245    (set_attr "mode" "SF")])
4246
4247 (define_insn "*truncdfsf_mixed"
4248   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4249         (float_truncate:SF
4250           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4251    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4252   "TARGET_MIX_SSE_I387"
4253 {
4254   switch (which_alternative)
4255     {
4256     case 0:
4257       return output_387_reg_move (insn, operands);
4258
4259     case 1:
4260       return "#";
4261     case 2:
4262       return "cvtsd2ss\t{%1, %0|%0, %1}";
4263     default:
4264       gcc_unreachable ();
4265     }
4266 }
4267   [(set_attr "type" "fmov,multi,ssecvt")
4268    (set_attr "unit" "*,i387,*")
4269    (set_attr "mode" "SF")])
4270
4271 (define_insn "*truncdfsf_i387"
4272   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4273         (float_truncate:SF
4274           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4275    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4276   "TARGET_80387"
4277 {
4278   switch (which_alternative)
4279     {
4280     case 0:
4281       return output_387_reg_move (insn, operands);
4282
4283     case 1:
4284       return "#";
4285     default:
4286       gcc_unreachable ();
4287     }
4288 }
4289   [(set_attr "type" "fmov,multi")
4290    (set_attr "unit" "*,i387")
4291    (set_attr "mode" "SF")])
4292
4293 (define_insn "*truncdfsf2_i387_1"
4294   [(set (match_operand:SF 0 "memory_operand" "=m")
4295         (float_truncate:SF
4296           (match_operand:DF 1 "register_operand" "f")))]
4297   "TARGET_80387
4298    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299    && !TARGET_MIX_SSE_I387"
4300   "* return output_387_reg_move (insn, operands);"
4301   [(set_attr "type" "fmov")
4302    (set_attr "mode" "SF")])
4303
4304 (define_split
4305   [(set (match_operand:SF 0 "register_operand" "")
4306         (float_truncate:SF
4307          (match_operand:DF 1 "fp_register_operand" "")))
4308    (clobber (match_operand 2 "" ""))]
4309   "reload_completed"
4310   [(set (match_dup 2) (match_dup 1))
4311    (set (match_dup 0) (match_dup 2))]
4312 {
4313   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4314 })
4315
4316 ;; Conversion from XFmode to {SF,DF}mode
4317
4318 (define_expand "truncxf<mode>2"
4319   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4320                    (float_truncate:MODEF
4321                      (match_operand:XF 1 "register_operand" "")))
4322               (clobber (match_dup 2))])]
4323   "TARGET_80387"
4324 {
4325   if (flag_unsafe_math_optimizations)
4326     {
4327       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4328       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4329       if (reg != operands[0])
4330         emit_move_insn (operands[0], reg);
4331       DONE;
4332     }
4333   else
4334     {
4335       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4336       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4337     }
4338 })
4339
4340 (define_insn "*truncxfsf2_mixed"
4341   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4342         (float_truncate:SF
4343           (match_operand:XF 1 "register_operand" "f,f")))
4344    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4345   "TARGET_80387"
4346 {
4347   gcc_assert (!which_alternative);
4348   return output_387_reg_move (insn, operands);
4349 }
4350   [(set_attr "type" "fmov,multi")
4351    (set_attr "unit" "*,i387")
4352    (set_attr "mode" "SF")])
4353
4354 (define_insn "*truncxfdf2_mixed"
4355   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4356         (float_truncate:DF
4357           (match_operand:XF 1 "register_operand" "f,f")))
4358    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4359   "TARGET_80387"
4360 {
4361   gcc_assert (!which_alternative);
4362   return output_387_reg_move (insn, operands);
4363 }
4364   [(set_attr "type" "fmov,multi")
4365    (set_attr "unit" "*,i387")
4366    (set_attr "mode" "DF")])
4367
4368 (define_insn "truncxf<mode>2_i387_noop"
4369   [(set (match_operand:MODEF 0 "register_operand" "=f")
4370         (float_truncate:MODEF
4371           (match_operand:XF 1 "register_operand" "f")))]
4372   "TARGET_80387 && flag_unsafe_math_optimizations"
4373   "* return output_387_reg_move (insn, operands);"
4374   [(set_attr "type" "fmov")
4375    (set_attr "mode" "<MODE>")])
4376
4377 (define_insn "*truncxf<mode>2_i387"
4378   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379         (float_truncate:MODEF
4380           (match_operand:XF 1 "register_operand" "f")))]
4381   "TARGET_80387"
4382   "* return output_387_reg_move (insn, operands);"
4383   [(set_attr "type" "fmov")
4384    (set_attr "mode" "<MODE>")])
4385
4386 (define_split
4387   [(set (match_operand:MODEF 0 "register_operand" "")
4388         (float_truncate:MODEF
4389           (match_operand:XF 1 "register_operand" "")))
4390    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391   "TARGET_80387 && reload_completed"
4392   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393    (set (match_dup 0) (match_dup 2))]
4394   "")
4395
4396 (define_split
4397   [(set (match_operand:MODEF 0 "memory_operand" "")
4398         (float_truncate:MODEF
4399           (match_operand:XF 1 "register_operand" "")))
4400    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4401   "TARGET_80387"
4402   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4403   "")
4404 \f
4405 ;; Signed conversion to DImode.
4406
4407 (define_expand "fix_truncxfdi2"
4408   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4409                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4410               (clobber (reg:CC FLAGS_REG))])]
4411   "TARGET_80387"
4412 {
4413   if (TARGET_FISTTP)
4414    {
4415      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4416      DONE;
4417    }
4418 })
4419
4420 (define_expand "fix_trunc<mode>di2"
4421   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4423               (clobber (reg:CC FLAGS_REG))])]
4424   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4425 {
4426   if (TARGET_FISTTP
4427       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4428    {
4429      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4430      DONE;
4431    }
4432   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4433    {
4434      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436      if (out != operands[0])
4437         emit_move_insn (operands[0], out);
4438      DONE;
4439    }
4440 })
4441
4442 ;; Signed conversion to SImode.
4443
4444 (define_expand "fix_truncxfsi2"
4445   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4446                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4447               (clobber (reg:CC FLAGS_REG))])]
4448   "TARGET_80387"
4449 {
4450   if (TARGET_FISTTP)
4451    {
4452      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4453      DONE;
4454    }
4455 })
4456
4457 (define_expand "fix_trunc<mode>si2"
4458   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4460               (clobber (reg:CC FLAGS_REG))])]
4461   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4462 {
4463   if (TARGET_FISTTP
4464       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4465    {
4466      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4467      DONE;
4468    }
4469   if (SSE_FLOAT_MODE_P (<MODE>mode))
4470    {
4471      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473      if (out != operands[0])
4474         emit_move_insn (operands[0], out);
4475      DONE;
4476    }
4477 })
4478
4479 ;; Signed conversion to HImode.
4480
4481 (define_expand "fix_trunc<mode>hi2"
4482   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4483                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4484               (clobber (reg:CC FLAGS_REG))])]
4485   "TARGET_80387
4486    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4487 {
4488   if (TARGET_FISTTP)
4489    {
4490      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4491      DONE;
4492    }
4493 })
4494
4495 ;; Unsigned conversion to SImode.
4496
4497 (define_expand "fixuns_trunc<mode>si2"
4498   [(parallel
4499     [(set (match_operand:SI 0 "register_operand" "")
4500           (unsigned_fix:SI
4501             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4502      (use (match_dup 2))
4503      (clobber (match_scratch:<ssevecmode> 3 ""))
4504      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4505   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4506 {
4507   enum machine_mode mode = <MODE>mode;
4508   enum machine_mode vecmode = <ssevecmode>mode;
4509   REAL_VALUE_TYPE TWO31r;
4510   rtx two31;
4511
4512   real_ldexp (&TWO31r, &dconst1, 31);
4513   two31 = const_double_from_real_value (TWO31r, mode);
4514   two31 = ix86_build_const_vector (mode, true, two31);
4515   operands[2] = force_reg (vecmode, two31);
4516 })
4517
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4520         (unsigned_fix:SI
4521           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4523    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4526   "#"
4527   "&& reload_completed"
4528   [(const_int 0)]
4529 {
4530   ix86_split_convert_uns_si_sse (operands);
4531   DONE;
4532 })
4533
4534 ;; Unsigned conversion to HImode.
4535 ;; Without these patterns, we'll try the unsigned SI conversion which
4536 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4537
4538 (define_expand "fixuns_trunc<mode>hi2"
4539   [(set (match_dup 2)
4540         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4541    (set (match_operand:HI 0 "nonimmediate_operand" "")
4542         (subreg:HI (match_dup 2) 0))]
4543   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4544   "operands[2] = gen_reg_rtx (SImode);")
4545
4546 ;; When SSE is available, it is always faster to use it!
4547 (define_insn "fix_trunc<mode>di_sse"
4548   [(set (match_operand:DI 0 "register_operand" "=r,r")
4549         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4550   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4551    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4552   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4553   [(set_attr "type" "sseicvt")
4554    (set_attr "mode" "<MODE>")
4555    (set_attr "athlon_decode" "double,vector")
4556    (set_attr "amdfam10_decode" "double,double")])
4557
4558 (define_insn "fix_trunc<mode>si_sse"
4559   [(set (match_operand:SI 0 "register_operand" "=r,r")
4560         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4561   "SSE_FLOAT_MODE_P (<MODE>mode)
4562    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4563   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4564   [(set_attr "type" "sseicvt")
4565    (set_attr "mode" "<MODE>")
4566    (set_attr "athlon_decode" "double,vector")
4567    (set_attr "amdfam10_decode" "double,double")])
4568
4569 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4570 (define_peephole2
4571   [(set (match_operand:MODEF 0 "register_operand" "")
4572         (match_operand:MODEF 1 "memory_operand" ""))
4573    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4574         (fix:SSEMODEI24 (match_dup 0)))]
4575   "TARGET_SHORTEN_X87_SSE
4576    && peep2_reg_dead_p (2, operands[0])"
4577   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4578   "")
4579
4580 ;; Avoid vector decoded forms of the instruction.
4581 (define_peephole2
4582   [(match_scratch:DF 2 "Y2")
4583    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4584         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4585   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4586   [(set (match_dup 2) (match_dup 1))
4587    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4588   "")
4589
4590 (define_peephole2
4591   [(match_scratch:SF 2 "x")
4592    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4593         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4594   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4595   [(set (match_dup 2) (match_dup 1))
4596    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4597   "")
4598
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603    && TARGET_FISTTP
4604    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605          && (TARGET_64BIT || <MODE>mode != DImode))
4606         && TARGET_SSE_MATH)
4607    && !(reload_completed || reload_in_progress)"
4608   "#"
4609   "&& 1"
4610   [(const_int 0)]
4611 {
4612   if (memory_operand (operands[0], VOIDmode))
4613     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4614   else
4615     {
4616       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4618                                                             operands[1],
4619                                                             operands[2]));
4620     }
4621   DONE;
4622 }
4623   [(set_attr "type" "fisttp")
4624    (set_attr "mode" "<MODE>")])
4625
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629    (clobber (match_scratch:XF 2 "=&1f"))]
4630   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631    && TARGET_FISTTP
4632    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633          && (TARGET_64BIT || <MODE>mode != DImode))
4634         && TARGET_SSE_MATH)"
4635   "* return output_fix_trunc (insn, operands, 1);"
4636   [(set_attr "type" "fisttp")
4637    (set_attr "mode" "<MODE>")])
4638
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4645    && TARGET_FISTTP
4646    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647         && (TARGET_64BIT || <MODE>mode != DImode))
4648         && TARGET_SSE_MATH)"
4649   "#"
4650   [(set_attr "type" "fisttp")
4651    (set_attr "mode" "<MODE>")])
4652
4653 (define_split
4654   [(set (match_operand:X87MODEI 0 "register_operand" "")
4655         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657    (clobber (match_scratch 3 ""))]
4658   "reload_completed"
4659   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660               (clobber (match_dup 3))])
4661    (set (match_dup 0) (match_dup 2))]
4662   "")
4663
4664 (define_split
4665   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4666         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4667    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4668    (clobber (match_scratch 3 ""))]
4669   "reload_completed"
4670   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4671               (clobber (match_dup 3))])]
4672   "")
4673
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682    (clobber (reg:CC FLAGS_REG))]
4683   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4684    && !TARGET_FISTTP
4685    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686          && (TARGET_64BIT || <MODE>mode != DImode))
4687    && !(reload_completed || reload_in_progress)"
4688   "#"
4689   "&& 1"
4690   [(const_int 0)]
4691 {
4692   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4693
4694   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696   if (memory_operand (operands[0], VOIDmode))
4697     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698                                          operands[2], operands[3]));
4699   else
4700     {
4701       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703                                                      operands[2], operands[3],
4704                                                      operands[4]));
4705     }
4706   DONE;
4707 }
4708   [(set_attr "type" "fistp")
4709    (set_attr "i387_cw" "trunc")
4710    (set_attr "mode" "<MODE>")])
4711
4712 (define_insn "fix_truncdi_i387"
4713   [(set (match_operand:DI 0 "memory_operand" "=m")
4714         (fix:DI (match_operand 1 "register_operand" "f")))
4715    (use (match_operand:HI 2 "memory_operand" "m"))
4716    (use (match_operand:HI 3 "memory_operand" "m"))
4717    (clobber (match_scratch:XF 4 "=&1f"))]
4718   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4719    && !TARGET_FISTTP
4720    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721   "* return output_fix_trunc (insn, operands, 0);"
4722   [(set_attr "type" "fistp")
4723    (set_attr "i387_cw" "trunc")
4724    (set_attr "mode" "DI")])
4725
4726 (define_insn "fix_truncdi_i387_with_temp"
4727   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728         (fix:DI (match_operand 1 "register_operand" "f,f")))
4729    (use (match_operand:HI 2 "memory_operand" "m,m"))
4730    (use (match_operand:HI 3 "memory_operand" "m,m"))
4731    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4734    && !TARGET_FISTTP
4735    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4736   "#"
4737   [(set_attr "type" "fistp")
4738    (set_attr "i387_cw" "trunc")
4739    (set_attr "mode" "DI")])
4740
4741 (define_split
4742   [(set (match_operand:DI 0 "register_operand" "")
4743         (fix:DI (match_operand 1 "register_operand" "")))
4744    (use (match_operand:HI 2 "memory_operand" ""))
4745    (use (match_operand:HI 3 "memory_operand" ""))
4746    (clobber (match_operand:DI 4 "memory_operand" ""))
4747    (clobber (match_scratch 5 ""))]
4748   "reload_completed"
4749   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4750               (use (match_dup 2))
4751               (use (match_dup 3))
4752               (clobber (match_dup 5))])
4753    (set (match_dup 0) (match_dup 4))]
4754   "")
4755
4756 (define_split
4757   [(set (match_operand:DI 0 "memory_operand" "")
4758         (fix:DI (match_operand 1 "register_operand" "")))
4759    (use (match_operand:HI 2 "memory_operand" ""))
4760    (use (match_operand:HI 3 "memory_operand" ""))
4761    (clobber (match_operand:DI 4 "memory_operand" ""))
4762    (clobber (match_scratch 5 ""))]
4763   "reload_completed"
4764   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4765               (use (match_dup 2))
4766               (use (match_dup 3))
4767               (clobber (match_dup 5))])]
4768   "")
4769
4770 (define_insn "fix_trunc<mode>_i387"
4771   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4772         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4773    (use (match_operand:HI 2 "memory_operand" "m"))
4774    (use (match_operand:HI 3 "memory_operand" "m"))]
4775   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4776    && !TARGET_FISTTP
4777    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4778   "* return output_fix_trunc (insn, operands, 0);"
4779   [(set_attr "type" "fistp")
4780    (set_attr "i387_cw" "trunc")
4781    (set_attr "mode" "<MODE>")])
4782
4783 (define_insn "fix_trunc<mode>_i387_with_temp"
4784   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4785         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4786    (use (match_operand:HI 2 "memory_operand" "m,m"))
4787    (use (match_operand:HI 3 "memory_operand" "m,m"))
4788    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4789   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4790    && !TARGET_FISTTP
4791    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4792   "#"
4793   [(set_attr "type" "fistp")
4794    (set_attr "i387_cw" "trunc")
4795    (set_attr "mode" "<MODE>")])
4796
4797 (define_split
4798   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4799         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4800    (use (match_operand:HI 2 "memory_operand" ""))
4801    (use (match_operand:HI 3 "memory_operand" ""))
4802    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4803   "reload_completed"
4804   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4805               (use (match_dup 2))
4806               (use (match_dup 3))])
4807    (set (match_dup 0) (match_dup 4))]
4808   "")
4809
4810 (define_split
4811   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4812         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4813    (use (match_operand:HI 2 "memory_operand" ""))
4814    (use (match_operand:HI 3 "memory_operand" ""))
4815    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4816   "reload_completed"
4817   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4818               (use (match_dup 2))
4819               (use (match_dup 3))])]
4820   "")
4821
4822 (define_insn "x86_fnstcw_1"
4823   [(set (match_operand:HI 0 "memory_operand" "=m")
4824         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4825   "TARGET_80387"
4826   "fnstcw\t%0"
4827   [(set_attr "length" "2")
4828    (set_attr "mode" "HI")
4829    (set_attr "unit" "i387")])
4830
4831 (define_insn "x86_fldcw_1"
4832   [(set (reg:HI FPCR_REG)
4833         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4834   "TARGET_80387"
4835   "fldcw\t%0"
4836   [(set_attr "length" "2")
4837    (set_attr "mode" "HI")
4838    (set_attr "unit" "i387")
4839    (set_attr "athlon_decode" "vector")
4840    (set_attr "amdfam10_decode" "vector")])
4841 \f
4842 ;; Conversion between fixed point and floating point.
4843
4844 ;; Even though we only accept memory inputs, the backend _really_
4845 ;; wants to be able to do this between registers.
4846
4847 (define_expand "floathi<mode>2"
4848   [(set (match_operand:X87MODEF 0 "register_operand" "")
4849         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4850   "TARGET_80387
4851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4852        || TARGET_MIX_SSE_I387)"
4853   "")
4854
4855 ;; Pre-reload splitter to add memory clobber to the pattern.
4856 (define_insn_and_split "*floathi<mode>2_1"
4857   [(set (match_operand:X87MODEF 0 "register_operand" "")
4858         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4859   "TARGET_80387
4860    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4861        || TARGET_MIX_SSE_I387)
4862    && !(reload_completed || reload_in_progress)"
4863   "#"
4864   "&& 1"
4865   [(parallel [(set (match_dup 0)
4866               (float:X87MODEF (match_dup 1)))
4867    (clobber (match_dup 2))])]
4868   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4869
4870 (define_insn "*floathi<mode>2_i387_with_temp"
4871   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4872         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4873   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4874   "TARGET_80387
4875    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876        || TARGET_MIX_SSE_I387)"
4877   "#"
4878   [(set_attr "type" "fmov,multi")
4879    (set_attr "mode" "<MODE>")
4880    (set_attr "unit" "*,i387")
4881    (set_attr "fp_int_src" "true")])
4882
4883 (define_insn "*floathi<mode>2_i387"
4884   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4885         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4886   "TARGET_80387
4887    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4888        || TARGET_MIX_SSE_I387)"
4889   "fild%z1\t%1"
4890   [(set_attr "type" "fmov")
4891    (set_attr "mode" "<MODE>")
4892    (set_attr "fp_int_src" "true")])
4893
4894 (define_split
4895   [(set (match_operand:X87MODEF 0 "register_operand" "")
4896         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4897    (clobber (match_operand:HI 2 "memory_operand" ""))]
4898   "TARGET_80387
4899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900        || TARGET_MIX_SSE_I387)
4901    && reload_completed"
4902   [(set (match_dup 2) (match_dup 1))
4903    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4904   "")
4905
4906 (define_split
4907   [(set (match_operand:X87MODEF 0 "register_operand" "")
4908         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4909    (clobber (match_operand:HI 2 "memory_operand" ""))]
4910    "TARGET_80387
4911     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912         || TARGET_MIX_SSE_I387)
4913     && reload_completed"
4914   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4915   "")
4916
4917 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4918   [(set (match_operand:X87MODEF 0 "register_operand" "")
4919         (float:X87MODEF
4920           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4921   "TARGET_80387
4922    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4923        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4924   "")
4925
4926 ;; Pre-reload splitter to add memory clobber to the pattern.
4927 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4928   [(set (match_operand:X87MODEF 0 "register_operand" "")
4929         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4930   "((TARGET_80387
4931      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4932            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4933          || TARGET_MIX_SSE_I387))
4934     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4936         && ((<SSEMODEI24:MODE>mode == SImode
4937              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4938              && flag_trapping_math)
4939             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4940    && !(reload_completed || reload_in_progress)"
4941   "#"
4942   "&& 1"
4943   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4944               (clobber (match_dup 2))])]
4945 {
4946   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4947
4948   /* Avoid store forwarding (partial memory) stall penalty
4949      by passing DImode value through XMM registers.  */
4950   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT 
4951       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 
4952       && !optimize_size)
4953     {
4954       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4955                                                             operands[1],
4956                                                             operands[2]));
4957       DONE;
4958     }
4959 })
4960
4961 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4962   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4963         (float:MODEF
4964           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4965    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4966   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4967    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4968   "#"
4969   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4970    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4971    (set_attr "unit" "*,i387,*,*,*")
4972    (set_attr "athlon_decode" "*,*,double,direct,double")
4973    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4974    (set_attr "fp_int_src" "true")])
4975
4976 (define_insn "*floatsi<mode>2_vector_mixed"
4977   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4978         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4979   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4980    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4981   "@
4982    fild%z1\t%1
4983    #"
4984   [(set_attr "type" "fmov,sseicvt")
4985    (set_attr "mode" "<MODE>,<ssevecmode>")
4986    (set_attr "unit" "i387,*")
4987    (set_attr "athlon_decode" "*,direct")
4988    (set_attr "amdfam10_decode" "*,double")
4989    (set_attr "fp_int_src" "true")])
4990
4991 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4992   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4993         (float:MODEF
4994           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4995   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4996   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4997    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4998   "#"
4999   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5000    (set_attr "mode" "<MODEF:MODE>")
5001    (set_attr "unit" "*,i387,*,*")
5002    (set_attr "athlon_decode" "*,*,double,direct")
5003    (set_attr "amdfam10_decode" "*,*,vector,double")
5004    (set_attr "fp_int_src" "true")])
5005
5006 (define_split
5007   [(set (match_operand:MODEF 0 "register_operand" "")
5008         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5009    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5010   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5011    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5012    && TARGET_INTER_UNIT_CONVERSIONS
5013    && reload_completed
5014    && (SSE_REG_P (operands[0])
5015        || (GET_CODE (operands[0]) == SUBREG
5016            && SSE_REG_P (operands[0])))"
5017   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5018   "")
5019
5020 (define_split
5021   [(set (match_operand:MODEF 0 "register_operand" "")
5022         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5023    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5024   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5026    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5027    && reload_completed
5028    && (SSE_REG_P (operands[0])
5029        || (GET_CODE (operands[0]) == SUBREG
5030            && SSE_REG_P (operands[0])))"
5031   [(set (match_dup 2) (match_dup 1))
5032    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5033   "")
5034
5035 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5036   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5037         (float:MODEF
5038           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5039   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5042   "@
5043    fild%z1\t%1
5044    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5045    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5046   [(set_attr "type" "fmov,sseicvt,sseicvt")
5047    (set_attr "mode" "<MODEF:MODE>")
5048    (set_attr "unit" "i387,*,*")
5049    (set_attr "athlon_decode" "*,double,direct")
5050    (set_attr "amdfam10_decode" "*,vector,double")
5051    (set_attr "fp_int_src" "true")])
5052
5053 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5054   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5055         (float:MODEF
5056           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5057   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5058    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5059    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5060   "@
5061    fild%z1\t%1
5062    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5063   [(set_attr "type" "fmov,sseicvt")
5064    (set_attr "mode" "<MODEF:MODE>")
5065    (set_attr "athlon_decode" "*,direct")
5066    (set_attr "amdfam10_decode" "*,double")
5067    (set_attr "fp_int_src" "true")])
5068
5069 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5070   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5071         (float:MODEF
5072           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5073    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5074   "TARGET_SSE2 && TARGET_SSE_MATH
5075    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5076   "#"
5077   [(set_attr "type" "sseicvt")
5078    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5079    (set_attr "athlon_decode" "double,direct,double")
5080    (set_attr "amdfam10_decode" "vector,double,double")
5081    (set_attr "fp_int_src" "true")])
5082
5083 (define_insn "*floatsi<mode>2_vector_sse"
5084   [(set (match_operand:MODEF 0 "register_operand" "=x")
5085         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5086   "TARGET_SSE2 && TARGET_SSE_MATH
5087    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5088   "#"
5089   [(set_attr "type" "sseicvt")
5090    (set_attr "mode" "<MODE>")
5091    (set_attr "athlon_decode" "direct")
5092    (set_attr "amdfam10_decode" "double")
5093    (set_attr "fp_int_src" "true")])
5094
5095 (define_split
5096   [(set (match_operand:MODEF 0 "register_operand" "")
5097         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5098    (clobber (match_operand:SI 2 "memory_operand" ""))]
5099   "TARGET_SSE2 && TARGET_SSE_MATH
5100    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5101    && reload_completed
5102    && (SSE_REG_P (operands[0])
5103        || (GET_CODE (operands[0]) == SUBREG
5104            && SSE_REG_P (operands[0])))"
5105   [(const_int 0)]
5106 {
5107   rtx op1 = operands[1];
5108
5109   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5110                                      <MODE>mode, 0);
5111   if (GET_CODE (op1) == SUBREG)
5112     op1 = SUBREG_REG (op1);
5113
5114   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5115     {
5116       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5117       emit_insn (gen_sse2_loadld (operands[4],
5118                                   CONST0_RTX (V4SImode), operands[1]));
5119     }
5120   /* We can ignore possible trapping value in the
5121      high part of SSE register for non-trapping math. */
5122   else if (SSE_REG_P (op1) && !flag_trapping_math)
5123     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5124   else
5125     {
5126       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5127       emit_move_insn (operands[2], operands[1]);
5128       emit_insn (gen_sse2_loadld (operands[4],
5129                                   CONST0_RTX (V4SImode), operands[2]));
5130     }
5131   emit_insn
5132     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5133   DONE;
5134 })
5135
5136 (define_split
5137   [(set (match_operand:MODEF 0 "register_operand" "")
5138         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5139    (clobber (match_operand:SI 2 "memory_operand" ""))]
5140   "TARGET_SSE2 && TARGET_SSE_MATH
5141    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5142    && reload_completed
5143    && (SSE_REG_P (operands[0])
5144        || (GET_CODE (operands[0]) == SUBREG
5145            && SSE_REG_P (operands[0])))"
5146   [(const_int 0)]
5147 {
5148   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5149                                      <MODE>mode, 0);
5150   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5151
5152   emit_insn (gen_sse2_loadld (operands[4],
5153                               CONST0_RTX (V4SImode), operands[1]));
5154   emit_insn
5155     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5156   DONE;
5157 })
5158
5159 (define_split
5160   [(set (match_operand:MODEF 0 "register_operand" "")
5161         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5162   "TARGET_SSE2 && TARGET_SSE_MATH
5163    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5164    && reload_completed
5165    && (SSE_REG_P (operands[0])
5166        || (GET_CODE (operands[0]) == SUBREG
5167            && SSE_REG_P (operands[0])))"
5168   [(const_int 0)]
5169 {
5170   rtx op1 = operands[1];
5171
5172   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5173                                      <MODE>mode, 0);
5174   if (GET_CODE (op1) == SUBREG)
5175     op1 = SUBREG_REG (op1);
5176
5177   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5178     {
5179       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5180       emit_insn (gen_sse2_loadld (operands[4],
5181                                   CONST0_RTX (V4SImode), operands[1]));
5182     }
5183   /* We can ignore possible trapping value in the
5184      high part of SSE register for non-trapping math. */
5185   else if (SSE_REG_P (op1) && !flag_trapping_math)
5186     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5187   else
5188     gcc_unreachable ();
5189 })
5190
5191 (define_split
5192   [(set (match_operand:MODEF 0 "register_operand" "")
5193         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5194   "TARGET_SSE2 && TARGET_SSE_MATH
5195    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5196    && reload_completed
5197    && (SSE_REG_P (operands[0])
5198        || (GET_CODE (operands[0]) == SUBREG
5199            && SSE_REG_P (operands[0])))"
5200   [(const_int 0)]
5201 {
5202   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5203                                      <MODE>mode, 0);
5204   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5205
5206   emit_insn (gen_sse2_loadld (operands[4],
5207                               CONST0_RTX (V4SImode), operands[1]));
5208   emit_insn
5209     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5210   DONE;
5211 })
5212
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5214   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5215         (float:MODEF
5216           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5217   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5218   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5220   "#"
5221   [(set_attr "type" "sseicvt")
5222    (set_attr "mode" "<MODEF:MODE>")
5223    (set_attr "athlon_decode" "double,direct")
5224    (set_attr "amdfam10_decode" "vector,double")
5225    (set_attr "fp_int_src" "true")])
5226
5227 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5228   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5229         (float:MODEF
5230           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5231   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5233    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5234   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5235   [(set_attr "type" "sseicvt")
5236    (set_attr "mode" "<MODEF:MODE>")
5237    (set_attr "athlon_decode" "double,direct")
5238    (set_attr "amdfam10_decode" "vector,double")
5239    (set_attr "fp_int_src" "true")])
5240
5241 (define_split
5242   [(set (match_operand:MODEF 0 "register_operand" "")
5243         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5244    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5245   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5246    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5247    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5248    && reload_completed
5249    && (SSE_REG_P (operands[0])
5250        || (GET_CODE (operands[0]) == SUBREG
5251            && SSE_REG_P (operands[0])))"
5252   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5253   "")
5254
5255 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5256   [(set (match_operand:MODEF 0 "register_operand" "=x")
5257         (float:MODEF
5258           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5259   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5261    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5262   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5263   [(set_attr "type" "sseicvt")
5264    (set_attr "mode" "<MODEF:MODE>")
5265    (set_attr "athlon_decode" "direct")
5266    (set_attr "amdfam10_decode" "double")
5267    (set_attr "fp_int_src" "true")])
5268
5269 (define_split
5270   [(set (match_operand:MODEF 0 "register_operand" "")
5271         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5272    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5273   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5274    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5275    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5276    && reload_completed
5277    && (SSE_REG_P (operands[0])
5278        || (GET_CODE (operands[0]) == SUBREG
5279            && SSE_REG_P (operands[0])))"
5280   [(set (match_dup 2) (match_dup 1))
5281    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5282   "")
5283
5284 (define_split
5285   [(set (match_operand:MODEF 0 "register_operand" "")
5286         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5287    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5288   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5289    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5290    && reload_completed
5291    && (SSE_REG_P (operands[0])
5292        || (GET_CODE (operands[0]) == SUBREG
5293            && SSE_REG_P (operands[0])))"
5294   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5295   "")
5296
5297 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5298   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5299         (float:X87MODEF
5300           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5301   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5302   "TARGET_80387"
5303   "@
5304    fild%z1\t%1
5305    #"
5306   [(set_attr "type" "fmov,multi")
5307    (set_attr "mode" "<X87MODEF:MODE>")
5308    (set_attr "unit" "*,i387")
5309    (set_attr "fp_int_src" "true")])
5310
5311 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5312   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5313         (float:X87MODEF
5314           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5315   "TARGET_80387"
5316   "fild%z1\t%1"
5317   [(set_attr "type" "fmov")
5318    (set_attr "mode" "<X87MODEF:MODE>")
5319    (set_attr "fp_int_src" "true")])
5320
5321 (define_split
5322   [(set (match_operand:X87MODEF 0 "register_operand" "")
5323         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5324    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5325   "TARGET_80387
5326    && reload_completed
5327    && FP_REG_P (operands[0])"
5328   [(set (match_dup 2) (match_dup 1))
5329    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5330   "")
5331
5332 (define_split
5333   [(set (match_operand:X87MODEF 0 "register_operand" "")
5334         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5335    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5336   "TARGET_80387
5337    && reload_completed
5338    && FP_REG_P (operands[0])"
5339   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5340   "")
5341
5342 ;; Avoid store forwarding (partial memory) stall penalty
5343 ;; by passing DImode value through XMM registers.  */
5344
5345 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5346   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5347         (float:X87MODEF
5348           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5349    (clobber (match_scratch:V4SI 3 "=X,x"))
5350    (clobber (match_scratch:V4SI 4 "=X,x"))
5351    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5352   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353    && !TARGET_64BIT && !optimize_size"
5354   "#"
5355   [(set_attr "type" "multi")
5356    (set_attr "mode" "<X87MODEF:MODE>")
5357    (set_attr "unit" "i387")
5358    (set_attr "fp_int_src" "true")])
5359
5360 (define_split
5361   [(set (match_operand:X87MODEF 0 "register_operand" "")
5362         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5363    (clobber (match_scratch:V4SI 3 ""))
5364    (clobber (match_scratch:V4SI 4 ""))
5365    (clobber (match_operand:DI 2 "memory_operand" ""))]
5366   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5367    && !TARGET_64BIT && !optimize_size
5368    && reload_completed
5369    && FP_REG_P (operands[0])"
5370   [(set (match_dup 2) (match_dup 3))
5371    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5372 {
5373   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5374      Assemble the 64-bit DImode value in an xmm register.  */
5375   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5376                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5377   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5378                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5379   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5380
5381   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5382 })
5383
5384 (define_split
5385   [(set (match_operand:X87MODEF 0 "register_operand" "")
5386         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5387    (clobber (match_scratch:V4SI 3 ""))
5388    (clobber (match_scratch:V4SI 4 ""))
5389    (clobber (match_operand:DI 2 "memory_operand" ""))]
5390   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5391    && !TARGET_64BIT && !optimize_size
5392    && reload_completed
5393    && FP_REG_P (operands[0])"
5394   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5395   "")
5396
5397 ;; Avoid store forwarding (partial memory) stall penalty by extending
5398 ;; SImode value to DImode through XMM register instead of pushing two
5399 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5400 ;; targets benefit from this optimization. Also note that fild
5401 ;; loads from memory only.
5402
5403 (define_insn "*floatunssi<mode>2_1"
5404   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5405         (unsigned_float:X87MODEF
5406           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5407    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5408    (clobber (match_scratch:SI 3 "=X,x"))]
5409   "!TARGET_64BIT
5410    && TARGET_80387 && TARGET_SSE"
5411   "#"
5412   [(set_attr "type" "multi")
5413    (set_attr "mode" "<MODE>")])
5414
5415 (define_split
5416   [(set (match_operand:X87MODEF 0 "register_operand" "")
5417         (unsigned_float:X87MODEF
5418           (match_operand:SI 1 "register_operand" "")))
5419    (clobber (match_operand:DI 2 "memory_operand" ""))
5420    (clobber (match_scratch:SI 3 ""))]
5421   "!TARGET_64BIT
5422    && TARGET_80387 && TARGET_SSE
5423    && reload_completed"
5424   [(set (match_dup 2) (match_dup 1))
5425    (set (match_dup 0)
5426         (float:X87MODEF (match_dup 2)))]
5427   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5428
5429 (define_split
5430   [(set (match_operand:X87MODEF 0 "register_operand" "")
5431         (unsigned_float:X87MODEF
5432           (match_operand:SI 1 "memory_operand" "")))
5433    (clobber (match_operand:DI 2 "memory_operand" ""))
5434    (clobber (match_scratch:SI 3 ""))]
5435   "!TARGET_64BIT
5436    && TARGET_80387 && TARGET_SSE
5437    && reload_completed"
5438   [(set (match_dup 2) (match_dup 3))
5439    (set (match_dup 0)
5440         (float:X87MODEF (match_dup 2)))]
5441 {
5442   emit_move_insn (operands[3], operands[1]);
5443   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5444 })
5445
5446 (define_expand "floatunssi<mode>2"
5447   [(parallel
5448      [(set (match_operand:X87MODEF 0 "register_operand" "")
5449            (unsigned_float:X87MODEF
5450              (match_operand:SI 1 "nonimmediate_operand" "")))
5451       (clobber (match_dup 2))
5452       (clobber (match_scratch:SI 3 ""))])]
5453   "!TARGET_64BIT
5454    && ((TARGET_80387 && TARGET_SSE)
5455        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5456 {
5457   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5458     {
5459       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5460       DONE;
5461     }
5462   else
5463     {
5464       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5465       operands[2] = assign_386_stack_local (DImode, slot);
5466     }
5467 })
5468
5469 (define_expand "floatunsdisf2"
5470   [(use (match_operand:SF 0 "register_operand" ""))
5471    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5472   "TARGET_64BIT && TARGET_SSE_MATH"
5473   "x86_emit_floatuns (operands); DONE;")
5474
5475 (define_expand "floatunsdidf2"
5476   [(use (match_operand:DF 0 "register_operand" ""))
5477    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5478   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5479    && TARGET_SSE2 && TARGET_SSE_MATH"
5480 {
5481   if (TARGET_64BIT)
5482     x86_emit_floatuns (operands);
5483   else
5484     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5485   DONE;
5486 })
5487 \f
5488 ;; Add instructions
5489
5490 ;; %%% splits for addditi3
5491
5492 (define_expand "addti3"
5493   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5494         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5495                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5496   "TARGET_64BIT"
5497   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5498
5499 (define_insn "*addti3_1"
5500   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5501         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5502                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5503    (clobber (reg:CC FLAGS_REG))]
5504   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5505   "#")
5506
5507 (define_split
5508   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5509         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5510                  (match_operand:TI 2 "x86_64_general_operand" "")))
5511    (clobber (reg:CC FLAGS_REG))]
5512   "TARGET_64BIT && reload_completed"
5513   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5514                                           UNSPEC_ADD_CARRY))
5515               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5516    (parallel [(set (match_dup 3)
5517                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5518                                      (match_dup 4))
5519                             (match_dup 5)))
5520               (clobber (reg:CC FLAGS_REG))])]
5521   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5522
5523 ;; %%% splits for addsidi3
5524 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5525 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5526 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5527
5528 (define_expand "adddi3"
5529   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5530         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5531                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5532   ""
5533   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5534
5535 (define_insn "*adddi3_1"
5536   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5537         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5538                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5539    (clobber (reg:CC FLAGS_REG))]
5540   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5541   "#")
5542
5543 (define_split
5544   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5545         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5546                  (match_operand:DI 2 "general_operand" "")))
5547    (clobber (reg:CC FLAGS_REG))]
5548   "!TARGET_64BIT && reload_completed"
5549   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5550                                           UNSPEC_ADD_CARRY))
5551               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5552    (parallel [(set (match_dup 3)
5553                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5554                                      (match_dup 4))
5555                             (match_dup 5)))
5556               (clobber (reg:CC FLAGS_REG))])]
5557   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5558
5559 (define_insn "adddi3_carry_rex64"
5560   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5561           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5562                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5563                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5564    (clobber (reg:CC FLAGS_REG))]
5565   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5566   "adc{q}\t{%2, %0|%0, %2}"
5567   [(set_attr "type" "alu")
5568    (set_attr "pent_pair" "pu")
5569    (set_attr "mode" "DI")])
5570
5571 (define_insn "*adddi3_cc_rex64"
5572   [(set (reg:CC FLAGS_REG)
5573         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5574                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5575                    UNSPEC_ADD_CARRY))
5576    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5577         (plus:DI (match_dup 1) (match_dup 2)))]
5578   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5579   "add{q}\t{%2, %0|%0, %2}"
5580   [(set_attr "type" "alu")
5581    (set_attr "mode" "DI")])
5582
5583 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5584   [(set (reg:CCC FLAGS_REG)
5585         (compare:CCC
5586             (plusminus:SWI
5587                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5588                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5589             (match_dup 1)))
5590    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5591         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5592   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5593   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5594   [(set_attr "type" "alu")
5595    (set_attr "mode" "<MODE>")])
5596
5597 (define_insn "*add<mode>3_cconly_overflow"
5598   [(set (reg:CCC FLAGS_REG)
5599         (compare:CCC
5600                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5601                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5602                 (match_dup 1)))
5603    (clobber (match_scratch:SWI 0 "=<r>"))]
5604   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5605   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5606   [(set_attr "type" "alu")
5607    (set_attr "mode" "<MODE>")])
5608
5609 (define_insn "*sub<mode>3_cconly_overflow"
5610   [(set (reg:CCC FLAGS_REG)
5611         (compare:CCC
5612              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5613                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5614              (match_dup 0)))]
5615   ""
5616   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5617   [(set_attr "type" "icmp")
5618    (set_attr "mode" "<MODE>")])
5619
5620 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5621   [(set (reg:CCC FLAGS_REG)
5622         (compare:CCC
5623             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5624                           (match_operand:SI 2 "general_operand" "g"))
5625             (match_dup 1)))
5626    (set (match_operand:DI 0 "register_operand" "=r")
5627         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5628   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5629   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5630   [(set_attr "type" "alu")
5631    (set_attr "mode" "SI")])
5632
5633 (define_insn "addqi3_carry"
5634   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5635           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5636                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5637                    (match_operand:QI 2 "general_operand" "qn,qm")))
5638    (clobber (reg:CC FLAGS_REG))]
5639   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5640   "adc{b}\t{%2, %0|%0, %2}"
5641   [(set_attr "type" "alu")
5642    (set_attr "pent_pair" "pu")
5643    (set_attr "mode" "QI")])
5644
5645 (define_insn "addhi3_carry"
5646   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5647           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5648                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5649                    (match_operand:HI 2 "general_operand" "rn,rm")))
5650    (clobber (reg:CC FLAGS_REG))]
5651   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5652   "adc{w}\t{%2, %0|%0, %2}"
5653   [(set_attr "type" "alu")
5654    (set_attr "pent_pair" "pu")
5655    (set_attr "mode" "HI")])
5656
5657 (define_insn "addsi3_carry"
5658   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5659           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5660                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5661                    (match_operand:SI 2 "general_operand" "ri,rm")))
5662    (clobber (reg:CC FLAGS_REG))]
5663   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5664   "adc{l}\t{%2, %0|%0, %2}"
5665   [(set_attr "type" "alu")
5666    (set_attr "pent_pair" "pu")
5667    (set_attr "mode" "SI")])
5668
5669 (define_insn "*addsi3_carry_zext"
5670   [(set (match_operand:DI 0 "register_operand" "=r")
5671           (zero_extend:DI
5672             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5673                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5674                      (match_operand:SI 2 "general_operand" "g"))))
5675    (clobber (reg:CC FLAGS_REG))]
5676   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5677   "adc{l}\t{%2, %k0|%k0, %2}"
5678   [(set_attr "type" "alu")
5679    (set_attr "pent_pair" "pu")
5680    (set_attr "mode" "SI")])
5681
5682 (define_insn "*addsi3_cc"
5683   [(set (reg:CC FLAGS_REG)
5684         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5685                     (match_operand:SI 2 "general_operand" "ri,rm")]
5686                    UNSPEC_ADD_CARRY))
5687    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5688         (plus:SI (match_dup 1) (match_dup 2)))]
5689   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5690   "add{l}\t{%2, %0|%0, %2}"
5691   [(set_attr "type" "alu")
5692    (set_attr "mode" "SI")])
5693
5694 (define_insn "addqi3_cc"
5695   [(set (reg:CC FLAGS_REG)
5696         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5697                     (match_operand:QI 2 "general_operand" "qn,qm")]
5698                    UNSPEC_ADD_CARRY))
5699    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5700         (plus:QI (match_dup 1) (match_dup 2)))]
5701   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5702   "add{b}\t{%2, %0|%0, %2}"
5703   [(set_attr "type" "alu")
5704    (set_attr "mode" "QI")])
5705
5706 (define_expand "addsi3"
5707   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5708         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5709                  (match_operand:SI 2 "general_operand" "")))]
5710   ""
5711   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5712
5713 (define_insn "*lea_1"
5714   [(set (match_operand:SI 0 "register_operand" "=r")
5715         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5716   "!TARGET_64BIT"
5717   "lea{l}\t{%a1, %0|%0, %a1}"
5718   [(set_attr "type" "lea")
5719    (set_attr "mode" "SI")])
5720
5721 (define_insn "*lea_1_rex64"
5722   [(set (match_operand:SI 0 "register_operand" "=r")
5723         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5724   "TARGET_64BIT"
5725   "lea{l}\t{%a1, %0|%0, %a1}"
5726   [(set_attr "type" "lea")
5727    (set_attr "mode" "SI")])
5728
5729 (define_insn "*lea_1_zext"
5730   [(set (match_operand:DI 0 "register_operand" "=r")
5731         (zero_extend:DI
5732          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5733   "TARGET_64BIT"
5734   "lea{l}\t{%a1, %k0|%k0, %a1}"
5735   [(set_attr "type" "lea")
5736    (set_attr "mode" "SI")])
5737
5738 (define_insn "*lea_2_rex64"
5739   [(set (match_operand:DI 0 "register_operand" "=r")
5740         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5741   "TARGET_64BIT"
5742   "lea{q}\t{%a1, %0|%0, %a1}"
5743   [(set_attr "type" "lea")
5744    (set_attr "mode" "DI")])
5745
5746 ;; The lea patterns for non-Pmodes needs to be matched by several
5747 ;; insns converted to real lea by splitters.
5748
5749 (define_insn_and_split "*lea_general_1"
5750   [(set (match_operand 0 "register_operand" "=r")
5751         (plus (plus (match_operand 1 "index_register_operand" "l")
5752                     (match_operand 2 "register_operand" "r"))
5753               (match_operand 3 "immediate_operand" "i")))]
5754   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5755     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5756    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5757    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5758    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5759    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5760        || GET_MODE (operands[3]) == VOIDmode)"
5761   "#"
5762   "&& reload_completed"
5763   [(const_int 0)]
5764 {
5765   rtx pat;
5766   operands[0] = gen_lowpart (SImode, operands[0]);
5767   operands[1] = gen_lowpart (Pmode, operands[1]);
5768   operands[2] = gen_lowpart (Pmode, operands[2]);
5769   operands[3] = gen_lowpart (Pmode, operands[3]);
5770   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5771                       operands[3]);
5772   if (Pmode != SImode)
5773     pat = gen_rtx_SUBREG (SImode, pat, 0);
5774   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5775   DONE;
5776 }
5777   [(set_attr "type" "lea")
5778    (set_attr "mode" "SI")])
5779
5780 (define_insn_and_split "*lea_general_1_zext"
5781   [(set (match_operand:DI 0 "register_operand" "=r")
5782         (zero_extend:DI
5783           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5784                             (match_operand:SI 2 "register_operand" "r"))
5785                    (match_operand:SI 3 "immediate_operand" "i"))))]
5786   "TARGET_64BIT"
5787   "#"
5788   "&& reload_completed"
5789   [(set (match_dup 0)
5790         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5791                                                      (match_dup 2))
5792                                             (match_dup 3)) 0)))]
5793 {
5794   operands[1] = gen_lowpart (Pmode, operands[1]);
5795   operands[2] = gen_lowpart (Pmode, operands[2]);
5796   operands[3] = gen_lowpart (Pmode, operands[3]);
5797 }
5798   [(set_attr "type" "lea")
5799    (set_attr "mode" "SI")])
5800
5801 (define_insn_and_split "*lea_general_2"
5802   [(set (match_operand 0 "register_operand" "=r")
5803         (plus (mult (match_operand 1 "index_register_operand" "l")
5804                     (match_operand 2 "const248_operand" "i"))
5805               (match_operand 3 "nonmemory_operand" "ri")))]
5806   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5807     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5808    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5809    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5810    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5811        || GET_MODE (operands[3]) == VOIDmode)"
5812   "#"
5813   "&& reload_completed"
5814   [(const_int 0)]
5815 {
5816   rtx pat;
5817   operands[0] = gen_lowpart (SImode, operands[0]);
5818   operands[1] = gen_lowpart (Pmode, operands[1]);
5819   operands[3] = gen_lowpart (Pmode, operands[3]);
5820   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5821                       operands[3]);
5822   if (Pmode != SImode)
5823     pat = gen_rtx_SUBREG (SImode, pat, 0);
5824   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5825   DONE;
5826 }
5827   [(set_attr "type" "lea")
5828    (set_attr "mode" "SI")])
5829
5830 (define_insn_and_split "*lea_general_2_zext"
5831   [(set (match_operand:DI 0 "register_operand" "=r")
5832         (zero_extend:DI
5833           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5834                             (match_operand:SI 2 "const248_operand" "n"))
5835                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5836   "TARGET_64BIT"
5837   "#"
5838   "&& reload_completed"
5839   [(set (match_dup 0)
5840         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5841                                                      (match_dup 2))
5842                                             (match_dup 3)) 0)))]
5843 {
5844   operands[1] = gen_lowpart (Pmode, operands[1]);
5845   operands[3] = gen_lowpart (Pmode, operands[3]);
5846 }
5847   [(set_attr "type" "lea")
5848    (set_attr "mode" "SI")])
5849
5850 (define_insn_and_split "*lea_general_3"
5851   [(set (match_operand 0 "register_operand" "=r")
5852         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5853                           (match_operand 2 "const248_operand" "i"))
5854                     (match_operand 3 "register_operand" "r"))
5855               (match_operand 4 "immediate_operand" "i")))]
5856   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5857     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5858    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5859    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5860    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5861   "#"
5862   "&& reload_completed"
5863   [(const_int 0)]
5864 {
5865   rtx pat;
5866   operands[0] = gen_lowpart (SImode, operands[0]);
5867   operands[1] = gen_lowpart (Pmode, operands[1]);
5868   operands[3] = gen_lowpart (Pmode, operands[3]);
5869   operands[4] = gen_lowpart (Pmode, operands[4]);
5870   pat = gen_rtx_PLUS (Pmode,
5871                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5872                                                          operands[2]),
5873                                     operands[3]),
5874                       operands[4]);
5875   if (Pmode != SImode)
5876     pat = gen_rtx_SUBREG (SImode, pat, 0);
5877   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5878   DONE;
5879 }
5880   [(set_attr "type" "lea")
5881    (set_attr "mode" "SI")])
5882
5883 (define_insn_and_split "*lea_general_3_zext"
5884   [(set (match_operand:DI 0 "register_operand" "=r")
5885         (zero_extend:DI
5886           (plus:SI (plus:SI (mult:SI
5887                               (match_operand:SI 1 "index_register_operand" "l")
5888                               (match_operand:SI 2 "const248_operand" "n"))
5889                             (match_operand:SI 3 "register_operand" "r"))
5890                    (match_operand:SI 4 "immediate_operand" "i"))))]
5891   "TARGET_64BIT"
5892   "#"
5893   "&& reload_completed"
5894   [(set (match_dup 0)
5895         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5896                                                               (match_dup 2))
5897                                                      (match_dup 3))
5898                                             (match_dup 4)) 0)))]
5899 {
5900   operands[1] = gen_lowpart (Pmode, operands[1]);
5901   operands[3] = gen_lowpart (Pmode, operands[3]);
5902   operands[4] = gen_lowpart (Pmode, operands[4]);
5903 }
5904   [(set_attr "type" "lea")
5905    (set_attr "mode" "SI")])
5906
5907 (define_insn "*adddi_1_rex64"
5908   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5909         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5910                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5911    (clobber (reg:CC FLAGS_REG))]
5912   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5913 {
5914   switch (get_attr_type (insn))
5915     {
5916     case TYPE_LEA:
5917       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5918       return "lea{q}\t{%a2, %0|%0, %a2}";
5919
5920     case TYPE_INCDEC:
5921       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5922       if (operands[2] == const1_rtx)
5923         return "inc{q}\t%0";
5924       else
5925         {
5926           gcc_assert (operands[2] == constm1_rtx);
5927           return "dec{q}\t%0";
5928         }
5929
5930     default:
5931       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5932
5933       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5935       if (CONST_INT_P (operands[2])
5936           /* Avoid overflows.  */
5937           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5938           && (INTVAL (operands[2]) == 128
5939               || (INTVAL (operands[2]) < 0
5940                   && INTVAL (operands[2]) != -128)))
5941         {
5942           operands[2] = GEN_INT (-INTVAL (operands[2]));
5943           return "sub{q}\t{%2, %0|%0, %2}";
5944         }
5945       return "add{q}\t{%2, %0|%0, %2}";
5946     }
5947 }
5948   [(set (attr "type")
5949      (cond [(eq_attr "alternative" "2")
5950               (const_string "lea")
5951             ; Current assemblers are broken and do not allow @GOTOFF in
5952             ; ought but a memory context.
5953             (match_operand:DI 2 "pic_symbolic_operand" "")
5954               (const_string "lea")
5955             (match_operand:DI 2 "incdec_operand" "")
5956               (const_string "incdec")
5957            ]
5958            (const_string "alu")))
5959    (set_attr "mode" "DI")])
5960
5961 ;; Convert lea to the lea pattern to avoid flags dependency.
5962 (define_split
5963   [(set (match_operand:DI 0 "register_operand" "")
5964         (plus:DI (match_operand:DI 1 "register_operand" "")
5965                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5966    (clobber (reg:CC FLAGS_REG))]
5967   "TARGET_64BIT && reload_completed
5968    && true_regnum (operands[0]) != true_regnum (operands[1])"
5969   [(set (match_dup 0)
5970         (plus:DI (match_dup 1)
5971                  (match_dup 2)))]
5972   "")
5973
5974 (define_insn "*adddi_2_rex64"
5975   [(set (reg FLAGS_REG)
5976         (compare
5977           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5978                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5979           (const_int 0)))
5980    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5981         (plus:DI (match_dup 1) (match_dup 2)))]
5982   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5983    && ix86_binary_operator_ok (PLUS, DImode, operands)
5984    /* Current assemblers are broken and do not allow @GOTOFF in
5985       ought but a memory context.  */
5986    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5987 {
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_INCDEC:
5991       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5992       if (operands[2] == const1_rtx)
5993         return "inc{q}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{q}\t%0";
5998         }
5999
6000     default:
6001       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002       /* ???? We ought to handle there the 32bit case too
6003          - do we need new constraint?  */
6004       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6005          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6006       if (CONST_INT_P (operands[2])
6007           /* Avoid overflows.  */
6008           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6009           && (INTVAL (operands[2]) == 128
6010               || (INTVAL (operands[2]) < 0
6011                   && INTVAL (operands[2]) != -128)))
6012         {
6013           operands[2] = GEN_INT (-INTVAL (operands[2]));
6014           return "sub{q}\t{%2, %0|%0, %2}";
6015         }
6016       return "add{q}\t{%2, %0|%0, %2}";
6017     }
6018 }
6019   [(set (attr "type")
6020      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6021         (const_string "incdec")
6022         (const_string "alu")))
6023    (set_attr "mode" "DI")])
6024
6025 (define_insn "*adddi_3_rex64"
6026   [(set (reg FLAGS_REG)
6027         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6028                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6029    (clobber (match_scratch:DI 0 "=r"))]
6030   "TARGET_64BIT
6031    && ix86_match_ccmode (insn, CCZmode)
6032    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6033    /* Current assemblers are broken and do not allow @GOTOFF in
6034       ought but a memory context.  */
6035    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6036 {
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6041       if (operands[2] == const1_rtx)
6042         return "inc{q}\t%0";
6043       else
6044         {
6045           gcc_assert (operands[2] == constm1_rtx);
6046           return "dec{q}\t%0";
6047         }
6048
6049     default:
6050       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6051       /* ???? We ought to handle there the 32bit case too
6052          - do we need new constraint?  */
6053       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6055       if (CONST_INT_P (operands[2])
6056           /* Avoid overflows.  */
6057           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6058           && (INTVAL (operands[2]) == 128
6059               || (INTVAL (operands[2]) < 0
6060                   && INTVAL (operands[2]) != -128)))
6061         {
6062           operands[2] = GEN_INT (-INTVAL (operands[2]));
6063           return "sub{q}\t{%2, %0|%0, %2}";
6064         }
6065       return "add{q}\t{%2, %0|%0, %2}";
6066     }
6067 }
6068   [(set (attr "type")
6069      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6070         (const_string "incdec")
6071         (const_string "alu")))
6072    (set_attr "mode" "DI")])
6073
6074 ; For comparisons against 1, -1 and 128, we may generate better code
6075 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6076 ; is matched then.  We can't accept general immediate, because for
6077 ; case of overflows,  the result is messed up.
6078 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6079 ; when negated.
6080 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6081 ; only for comparisons not depending on it.
6082 (define_insn "*adddi_4_rex64"
6083   [(set (reg FLAGS_REG)
6084         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6085                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6086    (clobber (match_scratch:DI 0 "=rm"))]
6087   "TARGET_64BIT
6088    &&  ix86_match_ccmode (insn, CCGCmode)"
6089 {
6090   switch (get_attr_type (insn))
6091     {
6092     case TYPE_INCDEC:
6093       if (operands[2] == constm1_rtx)
6094         return "inc{q}\t%0";
6095       else
6096         {
6097           gcc_assert (operands[2] == const1_rtx);
6098           return "dec{q}\t%0";
6099         }
6100
6101     default:
6102       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6103       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6104          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6105       if ((INTVAL (operands[2]) == -128
6106            || (INTVAL (operands[2]) > 0
6107                && INTVAL (operands[2]) != 128))
6108           /* Avoid overflows.  */
6109           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6110         return "sub{q}\t{%2, %0|%0, %2}";
6111       operands[2] = GEN_INT (-INTVAL (operands[2]));
6112       return "add{q}\t{%2, %0|%0, %2}";
6113     }
6114 }
6115   [(set (attr "type")
6116      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6117         (const_string "incdec")
6118         (const_string "alu")))
6119    (set_attr "mode" "DI")])
6120
6121 (define_insn "*adddi_5_rex64"
6122   [(set (reg FLAGS_REG)
6123         (compare
6124           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6125                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6126           (const_int 0)))
6127    (clobber (match_scratch:DI 0 "=r"))]
6128   "TARGET_64BIT
6129    && ix86_match_ccmode (insn, CCGOCmode)
6130    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6131    /* Current assemblers are broken and do not allow @GOTOFF in
6132       ought but a memory context.  */
6133    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6134 {
6135   switch (get_attr_type (insn))
6136     {
6137     case TYPE_INCDEC:
6138       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6139       if (operands[2] == const1_rtx)
6140         return "inc{q}\t%0";
6141       else
6142         {
6143           gcc_assert (operands[2] == constm1_rtx);
6144           return "dec{q}\t%0";
6145         }
6146
6147     default:
6148       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6149       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6150          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6151       if (CONST_INT_P (operands[2])
6152           /* Avoid overflows.  */
6153           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6154           && (INTVAL (operands[2]) == 128
6155               || (INTVAL (operands[2]) < 0
6156                   && INTVAL (operands[2]) != -128)))
6157         {
6158           operands[2] = GEN_INT (-INTVAL (operands[2]));
6159           return "sub{q}\t{%2, %0|%0, %2}";
6160         }
6161       return "add{q}\t{%2, %0|%0, %2}";
6162     }
6163 }
6164   [(set (attr "type")
6165      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6166         (const_string "incdec")
6167         (const_string "alu")))
6168    (set_attr "mode" "DI")])
6169
6170
6171 (define_insn "*addsi_1"
6172   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6173         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6174                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6175    (clobber (reg:CC FLAGS_REG))]
6176   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6177 {
6178   switch (get_attr_type (insn))
6179     {
6180     case TYPE_LEA:
6181       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6182       return "lea{l}\t{%a2, %0|%0, %a2}";
6183
6184     case TYPE_INCDEC:
6185       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6186       if (operands[2] == const1_rtx)
6187         return "inc{l}\t%0";
6188       else
6189         {
6190           gcc_assert (operands[2] == constm1_rtx);
6191           return "dec{l}\t%0";
6192         }
6193
6194     default:
6195       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6196
6197       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6198          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6199       if (CONST_INT_P (operands[2])
6200           && (INTVAL (operands[2]) == 128
6201               || (INTVAL (operands[2]) < 0
6202                   && INTVAL (operands[2]) != -128)))
6203         {
6204           operands[2] = GEN_INT (-INTVAL (operands[2]));
6205           return "sub{l}\t{%2, %0|%0, %2}";
6206         }
6207       return "add{l}\t{%2, %0|%0, %2}";
6208     }
6209 }
6210   [(set (attr "type")
6211      (cond [(eq_attr "alternative" "2")
6212               (const_string "lea")
6213             ; Current assemblers are broken and do not allow @GOTOFF in
6214             ; ought but a memory context.
6215             (match_operand:SI 2 "pic_symbolic_operand" "")
6216               (const_string "lea")
6217             (match_operand:SI 2 "incdec_operand" "")
6218               (const_string "incdec")
6219            ]
6220            (const_string "alu")))
6221    (set_attr "mode" "SI")])
6222
6223 ;; Convert lea to the lea pattern to avoid flags dependency.
6224 (define_split
6225   [(set (match_operand 0 "register_operand" "")
6226         (plus (match_operand 1 "register_operand" "")
6227               (match_operand 2 "nonmemory_operand" "")))
6228    (clobber (reg:CC FLAGS_REG))]
6229   "reload_completed
6230    && true_regnum (operands[0]) != true_regnum (operands[1])"
6231   [(const_int 0)]
6232 {
6233   rtx pat;
6234   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6235      may confuse gen_lowpart.  */
6236   if (GET_MODE (operands[0]) != Pmode)
6237     {
6238       operands[1] = gen_lowpart (Pmode, operands[1]);
6239       operands[2] = gen_lowpart (Pmode, operands[2]);
6240     }
6241   operands[0] = gen_lowpart (SImode, operands[0]);
6242   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6243   if (Pmode != SImode)
6244     pat = gen_rtx_SUBREG (SImode, pat, 0);
6245   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6246   DONE;
6247 })
6248
6249 ;; It may seem that nonimmediate operand is proper one for operand 1.
6250 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6251 ;; we take care in ix86_binary_operator_ok to not allow two memory
6252 ;; operands so proper swapping will be done in reload.  This allow
6253 ;; patterns constructed from addsi_1 to match.
6254 (define_insn "addsi_1_zext"
6255   [(set (match_operand:DI 0 "register_operand" "=r,r")
6256         (zero_extend:DI
6257           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6258                    (match_operand:SI 2 "general_operand" "g,li"))))
6259    (clobber (reg:CC FLAGS_REG))]
6260   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6261 {
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_LEA:
6265       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6266       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6267
6268     case TYPE_INCDEC:
6269       if (operands[2] == const1_rtx)
6270         return "inc{l}\t%k0";
6271       else
6272         {
6273           gcc_assert (operands[2] == constm1_rtx);
6274           return "dec{l}\t%k0";
6275         }
6276
6277     default:
6278       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6279          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6280       if (CONST_INT_P (operands[2])
6281           && (INTVAL (operands[2]) == 128
6282               || (INTVAL (operands[2]) < 0
6283                   && INTVAL (operands[2]) != -128)))
6284         {
6285           operands[2] = GEN_INT (-INTVAL (operands[2]));
6286           return "sub{l}\t{%2, %k0|%k0, %2}";
6287         }
6288       return "add{l}\t{%2, %k0|%k0, %2}";
6289     }
6290 }
6291   [(set (attr "type")
6292      (cond [(eq_attr "alternative" "1")
6293               (const_string "lea")
6294             ; Current assemblers are broken and do not allow @GOTOFF in
6295             ; ought but a memory context.
6296             (match_operand:SI 2 "pic_symbolic_operand" "")
6297               (const_string "lea")
6298             (match_operand:SI 2 "incdec_operand" "")
6299               (const_string "incdec")
6300            ]
6301            (const_string "alu")))
6302    (set_attr "mode" "SI")])
6303
6304 ;; Convert lea to the lea pattern to avoid flags dependency.
6305 (define_split
6306   [(set (match_operand:DI 0 "register_operand" "")
6307         (zero_extend:DI
6308           (plus:SI (match_operand:SI 1 "register_operand" "")
6309                    (match_operand:SI 2 "nonmemory_operand" ""))))
6310    (clobber (reg:CC FLAGS_REG))]
6311   "TARGET_64BIT && reload_completed
6312    && true_regnum (operands[0]) != true_regnum (operands[1])"
6313   [(set (match_dup 0)
6314         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6315 {
6316   operands[1] = gen_lowpart (Pmode, operands[1]);
6317   operands[2] = gen_lowpart (Pmode, operands[2]);
6318 })
6319
6320 (define_insn "*addsi_2"
6321   [(set (reg FLAGS_REG)
6322         (compare
6323           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6324                    (match_operand:SI 2 "general_operand" "g,ri"))
6325           (const_int 0)))
6326    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6327         (plus:SI (match_dup 1) (match_dup 2)))]
6328   "ix86_match_ccmode (insn, CCGOCmode)
6329    && ix86_binary_operator_ok (PLUS, SImode, operands)
6330    /* Current assemblers are broken and do not allow @GOTOFF in
6331       ought but a memory context.  */
6332    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6333 {
6334   switch (get_attr_type (insn))
6335     {
6336     case TYPE_INCDEC:
6337       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6338       if (operands[2] == const1_rtx)
6339         return "inc{l}\t%0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx);
6343           return "dec{l}\t%0";
6344         }
6345
6346     default:
6347       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6348       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6349          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6350       if (CONST_INT_P (operands[2])
6351           && (INTVAL (operands[2]) == 128
6352               || (INTVAL (operands[2]) < 0
6353                   && INTVAL (operands[2]) != -128)))
6354         {
6355           operands[2] = GEN_INT (-INTVAL (operands[2]));
6356           return "sub{l}\t{%2, %0|%0, %2}";
6357         }
6358       return "add{l}\t{%2, %0|%0, %2}";
6359     }
6360 }
6361   [(set (attr "type")
6362      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6363         (const_string "incdec")
6364         (const_string "alu")))
6365    (set_attr "mode" "SI")])
6366
6367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6368 (define_insn "*addsi_2_zext"
6369   [(set (reg FLAGS_REG)
6370         (compare
6371           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6372                    (match_operand:SI 2 "general_operand" "g"))
6373           (const_int 0)))
6374    (set (match_operand:DI 0 "register_operand" "=r")
6375         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6376   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6377    && ix86_binary_operator_ok (PLUS, SImode, operands)
6378    /* Current assemblers are broken and do not allow @GOTOFF in
6379       ought but a memory context.  */
6380    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6381 {
6382   switch (get_attr_type (insn))
6383     {
6384     case TYPE_INCDEC:
6385       if (operands[2] == const1_rtx)
6386         return "inc{l}\t%k0";
6387       else
6388         {
6389           gcc_assert (operands[2] == constm1_rtx);
6390           return "dec{l}\t%k0";
6391         }
6392
6393     default:
6394       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6395          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6396       if (CONST_INT_P (operands[2])
6397           && (INTVAL (operands[2]) == 128
6398               || (INTVAL (operands[2]) < 0
6399                   && INTVAL (operands[2]) != -128)))
6400         {
6401           operands[2] = GEN_INT (-INTVAL (operands[2]));
6402           return "sub{l}\t{%2, %k0|%k0, %2}";
6403         }
6404       return "add{l}\t{%2, %k0|%k0, %2}";
6405     }
6406 }
6407   [(set (attr "type")
6408      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6409         (const_string "incdec")
6410         (const_string "alu")))
6411    (set_attr "mode" "SI")])
6412
6413 (define_insn "*addsi_3"
6414   [(set (reg FLAGS_REG)
6415         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6416                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6417    (clobber (match_scratch:SI 0 "=r"))]
6418   "ix86_match_ccmode (insn, CCZmode)
6419    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6420    /* Current assemblers are broken and do not allow @GOTOFF in
6421       ought but a memory context.  */
6422    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6423 {
6424   switch (get_attr_type (insn))
6425     {
6426     case TYPE_INCDEC:
6427       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6428       if (operands[2] == const1_rtx)
6429         return "inc{l}\t%0";
6430       else
6431         {
6432           gcc_assert (operands[2] == constm1_rtx);
6433           return "dec{l}\t%0";
6434         }
6435
6436     default:
6437       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6438       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6439          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6440       if (CONST_INT_P (operands[2])
6441           && (INTVAL (operands[2]) == 128
6442               || (INTVAL (operands[2]) < 0
6443                   && INTVAL (operands[2]) != -128)))
6444         {
6445           operands[2] = GEN_INT (-INTVAL (operands[2]));
6446           return "sub{l}\t{%2, %0|%0, %2}";
6447         }
6448       return "add{l}\t{%2, %0|%0, %2}";
6449     }
6450 }
6451   [(set (attr "type")
6452      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6453         (const_string "incdec")
6454         (const_string "alu")))
6455    (set_attr "mode" "SI")])
6456
6457 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6458 (define_insn "*addsi_3_zext"
6459   [(set (reg FLAGS_REG)
6460         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6461                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6462    (set (match_operand:DI 0 "register_operand" "=r")
6463         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6464   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6465    && ix86_binary_operator_ok (PLUS, SImode, operands)
6466    /* Current assemblers are broken and do not allow @GOTOFF in
6467       ought but a memory context.  */
6468    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6469 {
6470   switch (get_attr_type (insn))
6471     {
6472     case TYPE_INCDEC:
6473       if (operands[2] == const1_rtx)
6474         return "inc{l}\t%k0";
6475       else
6476         {
6477           gcc_assert (operands[2] == constm1_rtx);
6478           return "dec{l}\t%k0";
6479         }
6480
6481     default:
6482       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6483          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6484       if (CONST_INT_P (operands[2])
6485           && (INTVAL (operands[2]) == 128
6486               || (INTVAL (operands[2]) < 0
6487                   && INTVAL (operands[2]) != -128)))
6488         {
6489           operands[2] = GEN_INT (-INTVAL (operands[2]));
6490           return "sub{l}\t{%2, %k0|%k0, %2}";
6491         }
6492       return "add{l}\t{%2, %k0|%k0, %2}";
6493     }
6494 }
6495   [(set (attr "type")
6496      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6497         (const_string "incdec")
6498         (const_string "alu")))
6499    (set_attr "mode" "SI")])
6500
6501 ; For comparisons against 1, -1 and 128, we may generate better code
6502 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6503 ; is matched then.  We can't accept general immediate, because for
6504 ; case of overflows,  the result is messed up.
6505 ; This pattern also don't hold of 0x80000000, since the value overflows
6506 ; when negated.
6507 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6508 ; only for comparisons not depending on it.
6509 (define_insn "*addsi_4"
6510   [(set (reg FLAGS_REG)
6511         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6512                  (match_operand:SI 2 "const_int_operand" "n")))
6513    (clobber (match_scratch:SI 0 "=rm"))]
6514   "ix86_match_ccmode (insn, CCGCmode)
6515    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6516 {
6517   switch (get_attr_type (insn))
6518     {
6519     case TYPE_INCDEC:
6520       if (operands[2] == constm1_rtx)
6521         return "inc{l}\t%0";
6522       else
6523         {
6524           gcc_assert (operands[2] == const1_rtx);
6525           return "dec{l}\t%0";
6526         }
6527
6528     default:
6529       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6530       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6531          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6532       if ((INTVAL (operands[2]) == -128
6533            || (INTVAL (operands[2]) > 0
6534                && INTVAL (operands[2]) != 128)))
6535         return "sub{l}\t{%2, %0|%0, %2}";
6536       operands[2] = GEN_INT (-INTVAL (operands[2]));
6537       return "add{l}\t{%2, %0|%0, %2}";
6538     }
6539 }
6540   [(set (attr "type")
6541      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6542         (const_string "incdec")
6543         (const_string "alu")))
6544    (set_attr "mode" "SI")])
6545
6546 (define_insn "*addsi_5"
6547   [(set (reg FLAGS_REG)
6548         (compare
6549           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6550                    (match_operand:SI 2 "general_operand" "g"))
6551           (const_int 0)))
6552    (clobber (match_scratch:SI 0 "=r"))]
6553   "ix86_match_ccmode (insn, CCGOCmode)
6554    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6555    /* Current assemblers are broken and do not allow @GOTOFF in
6556       ought but a memory context.  */
6557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6558 {
6559   switch (get_attr_type (insn))
6560     {
6561     case TYPE_INCDEC:
6562       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6563       if (operands[2] == const1_rtx)
6564         return "inc{l}\t%0";
6565       else
6566         {
6567           gcc_assert (operands[2] == constm1_rtx);
6568           return "dec{l}\t%0";
6569         }
6570
6571     default:
6572       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6575       if (CONST_INT_P (operands[2])
6576           && (INTVAL (operands[2]) == 128
6577               || (INTVAL (operands[2]) < 0
6578                   && INTVAL (operands[2]) != -128)))
6579         {
6580           operands[2] = GEN_INT (-INTVAL (operands[2]));
6581           return "sub{l}\t{%2, %0|%0, %2}";
6582         }
6583       return "add{l}\t{%2, %0|%0, %2}";
6584     }
6585 }
6586   [(set (attr "type")
6587      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6588         (const_string "incdec")
6589         (const_string "alu")))
6590    (set_attr "mode" "SI")])
6591
6592 (define_expand "addhi3"
6593   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6594         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6595                  (match_operand:HI 2 "general_operand" "")))]
6596   "TARGET_HIMODE_MATH"
6597   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6598
6599 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6600 ;; type optimizations enabled by define-splits.  This is not important
6601 ;; for PII, and in fact harmful because of partial register stalls.
6602
6603 (define_insn "*addhi_1_lea"
6604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6605         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6606                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6607    (clobber (reg:CC FLAGS_REG))]
6608   "!TARGET_PARTIAL_REG_STALL
6609    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6610 {
6611   switch (get_attr_type (insn))
6612     {
6613     case TYPE_LEA:
6614       return "#";
6615     case TYPE_INCDEC:
6616       if (operands[2] == const1_rtx)
6617         return "inc{w}\t%0";
6618       else
6619         {
6620           gcc_assert (operands[2] == constm1_rtx);
6621           return "dec{w}\t%0";
6622         }
6623
6624     default:
6625       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6626          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6627       if (CONST_INT_P (operands[2])
6628           && (INTVAL (operands[2]) == 128
6629               || (INTVAL (operands[2]) < 0
6630                   && INTVAL (operands[2]) != -128)))
6631         {
6632           operands[2] = GEN_INT (-INTVAL (operands[2]));
6633           return "sub{w}\t{%2, %0|%0, %2}";
6634         }
6635       return "add{w}\t{%2, %0|%0, %2}";
6636     }
6637 }
6638   [(set (attr "type")
6639      (if_then_else (eq_attr "alternative" "2")
6640         (const_string "lea")
6641         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6642            (const_string "incdec")
6643            (const_string "alu"))))
6644    (set_attr "mode" "HI,HI,SI")])
6645
6646 (define_insn "*addhi_1"
6647   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6648         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6649                  (match_operand:HI 2 "general_operand" "rn,rm")))
6650    (clobber (reg:CC FLAGS_REG))]
6651   "TARGET_PARTIAL_REG_STALL
6652    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6653 {
6654   switch (get_attr_type (insn))
6655     {
6656     case TYPE_INCDEC:
6657       if (operands[2] == const1_rtx)
6658         return "inc{w}\t%0";
6659       else
6660         {
6661           gcc_assert (operands[2] == constm1_rtx);
6662           return "dec{w}\t%0";
6663         }
6664
6665     default:
6666       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6667          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6668       if (CONST_INT_P (operands[2])
6669           && (INTVAL (operands[2]) == 128
6670               || (INTVAL (operands[2]) < 0
6671                   && INTVAL (operands[2]) != -128)))
6672         {
6673           operands[2] = GEN_INT (-INTVAL (operands[2]));
6674           return "sub{w}\t{%2, %0|%0, %2}";
6675         }
6676       return "add{w}\t{%2, %0|%0, %2}";
6677     }
6678 }
6679   [(set (attr "type")
6680      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6681         (const_string "incdec")
6682         (const_string "alu")))
6683    (set_attr "mode" "HI")])
6684
6685 (define_insn "*addhi_2"
6686   [(set (reg FLAGS_REG)
6687         (compare
6688           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6689                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6690           (const_int 0)))
6691    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6692         (plus:HI (match_dup 1) (match_dup 2)))]
6693   "ix86_match_ccmode (insn, CCGOCmode)
6694    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6695 {
6696   switch (get_attr_type (insn))
6697     {
6698     case TYPE_INCDEC:
6699       if (operands[2] == const1_rtx)
6700         return "inc{w}\t%0";
6701       else
6702         {
6703           gcc_assert (operands[2] == constm1_rtx);
6704           return "dec{w}\t%0";
6705         }
6706
6707     default:
6708       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6709          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6710       if (CONST_INT_P (operands[2])
6711           && (INTVAL (operands[2]) == 128
6712               || (INTVAL (operands[2]) < 0
6713                   && INTVAL (operands[2]) != -128)))
6714         {
6715           operands[2] = GEN_INT (-INTVAL (operands[2]));
6716           return "sub{w}\t{%2, %0|%0, %2}";
6717         }
6718       return "add{w}\t{%2, %0|%0, %2}";
6719     }
6720 }
6721   [(set (attr "type")
6722      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6723         (const_string "incdec")
6724         (const_string "alu")))
6725    (set_attr "mode" "HI")])
6726
6727 (define_insn "*addhi_3"
6728   [(set (reg FLAGS_REG)
6729         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6730                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6731    (clobber (match_scratch:HI 0 "=r"))]
6732   "ix86_match_ccmode (insn, CCZmode)
6733    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6734 {
6735   switch (get_attr_type (insn))
6736     {
6737     case TYPE_INCDEC:
6738       if (operands[2] == const1_rtx)
6739         return "inc{w}\t%0";
6740       else
6741         {
6742           gcc_assert (operands[2] == constm1_rtx);
6743           return "dec{w}\t%0";
6744         }
6745
6746     default:
6747       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6748          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6749       if (CONST_INT_P (operands[2])
6750           && (INTVAL (operands[2]) == 128
6751               || (INTVAL (operands[2]) < 0
6752                   && INTVAL (operands[2]) != -128)))
6753         {
6754           operands[2] = GEN_INT (-INTVAL (operands[2]));
6755           return "sub{w}\t{%2, %0|%0, %2}";
6756         }
6757       return "add{w}\t{%2, %0|%0, %2}";
6758     }
6759 }
6760   [(set (attr "type")
6761      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6762         (const_string "incdec")
6763         (const_string "alu")))
6764    (set_attr "mode" "HI")])
6765
6766 ; See comments above addsi_4 for details.
6767 (define_insn "*addhi_4"
6768   [(set (reg FLAGS_REG)
6769         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6770                  (match_operand:HI 2 "const_int_operand" "n")))
6771    (clobber (match_scratch:HI 0 "=rm"))]
6772   "ix86_match_ccmode (insn, CCGCmode)
6773    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6774 {
6775   switch (get_attr_type (insn))
6776     {
6777     case TYPE_INCDEC:
6778       if (operands[2] == constm1_rtx)
6779         return "inc{w}\t%0";
6780       else
6781         {
6782           gcc_assert (operands[2] == const1_rtx);
6783           return "dec{w}\t%0";
6784         }
6785
6786     default:
6787       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6788       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6789          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6790       if ((INTVAL (operands[2]) == -128
6791            || (INTVAL (operands[2]) > 0
6792                && INTVAL (operands[2]) != 128)))
6793         return "sub{w}\t{%2, %0|%0, %2}";
6794       operands[2] = GEN_INT (-INTVAL (operands[2]));
6795       return "add{w}\t{%2, %0|%0, %2}";
6796     }
6797 }
6798   [(set (attr "type")
6799      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6800         (const_string "incdec")
6801         (const_string "alu")))
6802    (set_attr "mode" "SI")])
6803
6804
6805 (define_insn "*addhi_5"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6809                    (match_operand:HI 2 "general_operand" "rmn"))
6810           (const_int 0)))
6811    (clobber (match_scratch:HI 0 "=r"))]
6812   "ix86_match_ccmode (insn, CCGOCmode)
6813    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6814 {
6815   switch (get_attr_type (insn))
6816     {
6817     case TYPE_INCDEC:
6818       if (operands[2] == const1_rtx)
6819         return "inc{w}\t%0";
6820       else
6821         {
6822           gcc_assert (operands[2] == constm1_rtx);
6823           return "dec{w}\t%0";
6824         }
6825
6826     default:
6827       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6828          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6829       if (CONST_INT_P (operands[2])
6830           && (INTVAL (operands[2]) == 128
6831               || (INTVAL (operands[2]) < 0
6832                   && INTVAL (operands[2]) != -128)))
6833         {
6834           operands[2] = GEN_INT (-INTVAL (operands[2]));
6835           return "sub{w}\t{%2, %0|%0, %2}";
6836         }
6837       return "add{w}\t{%2, %0|%0, %2}";
6838     }
6839 }
6840   [(set (attr "type")
6841      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6842         (const_string "incdec")
6843         (const_string "alu")))
6844    (set_attr "mode" "HI")])
6845
6846 (define_expand "addqi3"
6847   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6848         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6849                  (match_operand:QI 2 "general_operand" "")))]
6850   "TARGET_QIMODE_MATH"
6851   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6852
6853 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6854 (define_insn "*addqi_1_lea"
6855   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6856         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6857                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "!TARGET_PARTIAL_REG_STALL
6860    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6861 {
6862   int widen = (which_alternative == 2);
6863   switch (get_attr_type (insn))
6864     {
6865     case TYPE_LEA:
6866       return "#";
6867     case TYPE_INCDEC:
6868       if (operands[2] == const1_rtx)
6869         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6870       else
6871         {
6872           gcc_assert (operands[2] == constm1_rtx);
6873           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6874         }
6875
6876     default:
6877       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6878          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6879       if (CONST_INT_P (operands[2])
6880           && (INTVAL (operands[2]) == 128
6881               || (INTVAL (operands[2]) < 0
6882                   && INTVAL (operands[2]) != -128)))
6883         {
6884           operands[2] = GEN_INT (-INTVAL (operands[2]));
6885           if (widen)
6886             return "sub{l}\t{%2, %k0|%k0, %2}";
6887           else
6888             return "sub{b}\t{%2, %0|%0, %2}";
6889         }
6890       if (widen)
6891         return "add{l}\t{%k2, %k0|%k0, %k2}";
6892       else
6893         return "add{b}\t{%2, %0|%0, %2}";
6894     }
6895 }
6896   [(set (attr "type")
6897      (if_then_else (eq_attr "alternative" "3")
6898         (const_string "lea")
6899         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6900            (const_string "incdec")
6901            (const_string "alu"))))
6902    (set_attr "mode" "QI,QI,SI,SI")])
6903
6904 (define_insn "*addqi_1"
6905   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6906         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6907                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6908    (clobber (reg:CC FLAGS_REG))]
6909   "TARGET_PARTIAL_REG_STALL
6910    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6911 {
6912   int widen = (which_alternative == 2);
6913   switch (get_attr_type (insn))
6914     {
6915     case TYPE_INCDEC:
6916       if (operands[2] == const1_rtx)
6917         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6918       else
6919         {
6920           gcc_assert (operands[2] == constm1_rtx);
6921           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6922         }
6923
6924     default:
6925       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6926          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6927       if (CONST_INT_P (operands[2])
6928           && (INTVAL (operands[2]) == 128
6929               || (INTVAL (operands[2]) < 0
6930                   && INTVAL (operands[2]) != -128)))
6931         {
6932           operands[2] = GEN_INT (-INTVAL (operands[2]));
6933           if (widen)
6934             return "sub{l}\t{%2, %k0|%k0, %2}";
6935           else
6936             return "sub{b}\t{%2, %0|%0, %2}";
6937         }
6938       if (widen)
6939         return "add{l}\t{%k2, %k0|%k0, %k2}";
6940       else
6941         return "add{b}\t{%2, %0|%0, %2}";
6942     }
6943 }
6944   [(set (attr "type")
6945      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6946         (const_string "incdec")
6947         (const_string "alu")))
6948    (set_attr "mode" "QI,QI,SI")])
6949
6950 (define_insn "*addqi_1_slp"
6951   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6952         (plus:QI (match_dup 0)
6953                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6954    (clobber (reg:CC FLAGS_REG))]
6955   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6956    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6957 {
6958   switch (get_attr_type (insn))
6959     {
6960     case TYPE_INCDEC:
6961       if (operands[1] == const1_rtx)
6962         return "inc{b}\t%0";
6963       else
6964         {
6965           gcc_assert (operands[1] == constm1_rtx);
6966           return "dec{b}\t%0";
6967         }
6968
6969     default:
6970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6971       if (CONST_INT_P (operands[1])
6972           && INTVAL (operands[1]) < 0)
6973         {
6974           operands[1] = GEN_INT (-INTVAL (operands[1]));
6975           return "sub{b}\t{%1, %0|%0, %1}";
6976         }
6977       return "add{b}\t{%1, %0|%0, %1}";
6978     }
6979 }
6980   [(set (attr "type")
6981      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6982         (const_string "incdec")
6983         (const_string "alu1")))
6984    (set (attr "memory")
6985      (if_then_else (match_operand 1 "memory_operand" "")
6986         (const_string "load")
6987         (const_string "none")))
6988    (set_attr "mode" "QI")])
6989
6990 (define_insn "*addqi_2"
6991   [(set (reg FLAGS_REG)
6992         (compare
6993           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6994                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6995           (const_int 0)))
6996    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6997         (plus:QI (match_dup 1) (match_dup 2)))]
6998   "ix86_match_ccmode (insn, CCGOCmode)
6999    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7000 {
7001   switch (get_attr_type (insn))
7002     {
7003     case TYPE_INCDEC:
7004       if (operands[2] == const1_rtx)
7005         return "inc{b}\t%0";
7006       else
7007         {
7008           gcc_assert (operands[2] == constm1_rtx
7009                       || (CONST_INT_P (operands[2])
7010                           && INTVAL (operands[2]) == 255));
7011           return "dec{b}\t%0";
7012         }
7013
7014     default:
7015       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7016       if (CONST_INT_P (operands[2])
7017           && INTVAL (operands[2]) < 0)
7018         {
7019           operands[2] = GEN_INT (-INTVAL (operands[2]));
7020           return "sub{b}\t{%2, %0|%0, %2}";
7021         }
7022       return "add{b}\t{%2, %0|%0, %2}";
7023     }
7024 }
7025   [(set (attr "type")
7026      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7027         (const_string "incdec")
7028         (const_string "alu")))
7029    (set_attr "mode" "QI")])
7030
7031 (define_insn "*addqi_3"
7032   [(set (reg FLAGS_REG)
7033         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7034                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7035    (clobber (match_scratch:QI 0 "=q"))]
7036   "ix86_match_ccmode (insn, CCZmode)
7037    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7038 {
7039   switch (get_attr_type (insn))
7040     {
7041     case TYPE_INCDEC:
7042       if (operands[2] == const1_rtx)
7043         return "inc{b}\t%0";
7044       else
7045         {
7046           gcc_assert (operands[2] == constm1_rtx
7047                       || (CONST_INT_P (operands[2])
7048                           && INTVAL (operands[2]) == 255));
7049           return "dec{b}\t%0";
7050         }
7051
7052     default:
7053       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7054       if (CONST_INT_P (operands[2])
7055           && INTVAL (operands[2]) < 0)
7056         {
7057           operands[2] = GEN_INT (-INTVAL (operands[2]));
7058           return "sub{b}\t{%2, %0|%0, %2}";
7059         }
7060       return "add{b}\t{%2, %0|%0, %2}";
7061     }
7062 }
7063   [(set (attr "type")
7064      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7065         (const_string "incdec")
7066         (const_string "alu")))
7067    (set_attr "mode" "QI")])
7068
7069 ; See comments above addsi_4 for details.
7070 (define_insn "*addqi_4"
7071   [(set (reg FLAGS_REG)
7072         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7073                  (match_operand:QI 2 "const_int_operand" "n")))
7074    (clobber (match_scratch:QI 0 "=qm"))]
7075   "ix86_match_ccmode (insn, CCGCmode)
7076    && (INTVAL (operands[2]) & 0xff) != 0x80"
7077 {
7078   switch (get_attr_type (insn))
7079     {
7080     case TYPE_INCDEC:
7081       if (operands[2] == constm1_rtx
7082           || (CONST_INT_P (operands[2])
7083               && INTVAL (operands[2]) == 255))
7084         return "inc{b}\t%0";
7085       else
7086         {
7087           gcc_assert (operands[2] == const1_rtx);
7088           return "dec{b}\t%0";
7089         }
7090
7091     default:
7092       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7093       if (INTVAL (operands[2]) < 0)
7094         {
7095           operands[2] = GEN_INT (-INTVAL (operands[2]));
7096           return "add{b}\t{%2, %0|%0, %2}";
7097         }
7098       return "sub{b}\t{%2, %0|%0, %2}";
7099     }
7100 }
7101   [(set (attr "type")
7102      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7103         (const_string "incdec")
7104         (const_string "alu")))
7105    (set_attr "mode" "QI")])
7106
7107
7108 (define_insn "*addqi_5"
7109   [(set (reg FLAGS_REG)
7110         (compare
7111           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7112                    (match_operand:QI 2 "general_operand" "qmn"))
7113           (const_int 0)))
7114    (clobber (match_scratch:QI 0 "=q"))]
7115   "ix86_match_ccmode (insn, CCGOCmode)
7116    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7117 {
7118   switch (get_attr_type (insn))
7119     {
7120     case TYPE_INCDEC:
7121       if (operands[2] == const1_rtx)
7122         return "inc{b}\t%0";
7123       else
7124         {
7125           gcc_assert (operands[2] == constm1_rtx
7126                       || (CONST_INT_P (operands[2])
7127                           && INTVAL (operands[2]) == 255));
7128           return "dec{b}\t%0";
7129         }
7130
7131     default:
7132       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7133       if (CONST_INT_P (operands[2])
7134           && INTVAL (operands[2]) < 0)
7135         {
7136           operands[2] = GEN_INT (-INTVAL (operands[2]));
7137           return "sub{b}\t{%2, %0|%0, %2}";
7138         }
7139       return "add{b}\t{%2, %0|%0, %2}";
7140     }
7141 }
7142   [(set (attr "type")
7143      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7144         (const_string "incdec")
7145         (const_string "alu")))
7146    (set_attr "mode" "QI")])
7147
7148
7149 (define_insn "addqi_ext_1"
7150   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7151                          (const_int 8)
7152                          (const_int 8))
7153         (plus:SI
7154           (zero_extract:SI
7155             (match_operand 1 "ext_register_operand" "0")
7156             (const_int 8)
7157             (const_int 8))
7158           (match_operand:QI 2 "general_operand" "Qmn")))
7159    (clobber (reg:CC FLAGS_REG))]
7160   "!TARGET_64BIT"
7161 {
7162   switch (get_attr_type (insn))
7163     {
7164     case TYPE_INCDEC:
7165       if (operands[2] == const1_rtx)
7166         return "inc{b}\t%h0";
7167       else
7168         {
7169           gcc_assert (operands[2] == constm1_rtx
7170                       || (CONST_INT_P (operands[2])
7171                           && INTVAL (operands[2]) == 255));
7172           return "dec{b}\t%h0";
7173         }
7174
7175     default:
7176       return "add{b}\t{%2, %h0|%h0, %2}";
7177     }
7178 }
7179   [(set (attr "type")
7180      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7181         (const_string "incdec")
7182         (const_string "alu")))
7183    (set_attr "mode" "QI")])
7184
7185 (define_insn "*addqi_ext_1_rex64"
7186   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7187                          (const_int 8)
7188                          (const_int 8))
7189         (plus:SI
7190           (zero_extract:SI
7191             (match_operand 1 "ext_register_operand" "0")
7192             (const_int 8)
7193             (const_int 8))
7194           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7195    (clobber (reg:CC FLAGS_REG))]
7196   "TARGET_64BIT"
7197 {
7198   switch (get_attr_type (insn))
7199     {
7200     case TYPE_INCDEC:
7201       if (operands[2] == const1_rtx)
7202         return "inc{b}\t%h0";
7203       else
7204         {
7205           gcc_assert (operands[2] == constm1_rtx
7206                       || (CONST_INT_P (operands[2])
7207                           && INTVAL (operands[2]) == 255));
7208           return "dec{b}\t%h0";
7209         }
7210
7211     default:
7212       return "add{b}\t{%2, %h0|%h0, %2}";
7213     }
7214 }
7215   [(set (attr "type")
7216      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7217         (const_string "incdec")
7218         (const_string "alu")))
7219    (set_attr "mode" "QI")])
7220
7221 (define_insn "*addqi_ext_2"
7222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7223                          (const_int 8)
7224                          (const_int 8))
7225         (plus:SI
7226           (zero_extract:SI
7227             (match_operand 1 "ext_register_operand" "%0")
7228             (const_int 8)
7229             (const_int 8))
7230           (zero_extract:SI
7231             (match_operand 2 "ext_register_operand" "Q")
7232             (const_int 8)
7233             (const_int 8))))
7234    (clobber (reg:CC FLAGS_REG))]
7235   ""
7236   "add{b}\t{%h2, %h0|%h0, %h2}"
7237   [(set_attr "type" "alu")
7238    (set_attr "mode" "QI")])
7239
7240 ;; The patterns that match these are at the end of this file.
7241
7242 (define_expand "addxf3"
7243   [(set (match_operand:XF 0 "register_operand" "")
7244         (plus:XF (match_operand:XF 1 "register_operand" "")
7245                  (match_operand:XF 2 "register_operand" "")))]
7246   "TARGET_80387"
7247   "")
7248
7249 (define_expand "add<mode>3"
7250   [(set (match_operand:MODEF 0 "register_operand" "")
7251         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7252                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7253   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7254   "")
7255 \f
7256 ;; Subtract instructions
7257
7258 ;; %%% splits for subditi3
7259
7260 (define_expand "subti3"
7261   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7262         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7263                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7264   "TARGET_64BIT"
7265   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7266
7267 (define_insn "*subti3_1"
7268   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7269         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7270                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7271    (clobber (reg:CC FLAGS_REG))]
7272   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7273   "#")
7274
7275 (define_split
7276   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7277         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7278                   (match_operand:TI 2 "x86_64_general_operand" "")))
7279    (clobber (reg:CC FLAGS_REG))]
7280   "TARGET_64BIT && reload_completed"
7281   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7282               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7283    (parallel [(set (match_dup 3)
7284                    (minus:DI (match_dup 4)
7285                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7286                                       (match_dup 5))))
7287               (clobber (reg:CC FLAGS_REG))])]
7288   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7289
7290 ;; %%% splits for subsidi3
7291
7292 (define_expand "subdi3"
7293   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7294         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7295                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7296   ""
7297   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7298
7299 (define_insn "*subdi3_1"
7300   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7301         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7302                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7305   "#")
7306
7307 (define_split
7308   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7309         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7310                   (match_operand:DI 2 "general_operand" "")))
7311    (clobber (reg:CC FLAGS_REG))]
7312   "!TARGET_64BIT && reload_completed"
7313   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7314               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7315    (parallel [(set (match_dup 3)
7316                    (minus:SI (match_dup 4)
7317                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7318                                       (match_dup 5))))
7319               (clobber (reg:CC FLAGS_REG))])]
7320   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7321
7322 (define_insn "subdi3_carry_rex64"
7323   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7324           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7325             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7326                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7327    (clobber (reg:CC FLAGS_REG))]
7328   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7329   "sbb{q}\t{%2, %0|%0, %2}"
7330   [(set_attr "type" "alu")
7331    (set_attr "pent_pair" "pu")
7332    (set_attr "mode" "DI")])
7333
7334 (define_insn "*subdi_1_rex64"
7335   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7336         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7337                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7340   "sub{q}\t{%2, %0|%0, %2}"
7341   [(set_attr "type" "alu")
7342    (set_attr "mode" "DI")])
7343
7344 (define_insn "*subdi_2_rex64"
7345   [(set (reg FLAGS_REG)
7346         (compare
7347           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7348                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7349           (const_int 0)))
7350    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7351         (minus:DI (match_dup 1) (match_dup 2)))]
7352   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7353    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7354   "sub{q}\t{%2, %0|%0, %2}"
7355   [(set_attr "type" "alu")
7356    (set_attr "mode" "DI")])
7357
7358 (define_insn "*subdi_3_rex63"
7359   [(set (reg FLAGS_REG)
7360         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7361                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7362    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7363         (minus:DI (match_dup 1) (match_dup 2)))]
7364   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7365    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7366   "sub{q}\t{%2, %0|%0, %2}"
7367   [(set_attr "type" "alu")
7368    (set_attr "mode" "DI")])
7369
7370 (define_insn "subqi3_carry"
7371   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7372           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7373             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7374                (match_operand:QI 2 "general_operand" "qn,qm"))))
7375    (clobber (reg:CC FLAGS_REG))]
7376   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7377   "sbb{b}\t{%2, %0|%0, %2}"
7378   [(set_attr "type" "alu")
7379    (set_attr "pent_pair" "pu")
7380    (set_attr "mode" "QI")])
7381
7382 (define_insn "subhi3_carry"
7383   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7384           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7385             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7386                (match_operand:HI 2 "general_operand" "rn,rm"))))
7387    (clobber (reg:CC FLAGS_REG))]
7388   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7389   "sbb{w}\t{%2, %0|%0, %2}"
7390   [(set_attr "type" "alu")
7391    (set_attr "pent_pair" "pu")
7392    (set_attr "mode" "HI")])
7393
7394 (define_insn "subsi3_carry"
7395   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7396           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7397             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7398                (match_operand:SI 2 "general_operand" "ri,rm"))))
7399    (clobber (reg:CC FLAGS_REG))]
7400   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7401   "sbb{l}\t{%2, %0|%0, %2}"
7402   [(set_attr "type" "alu")
7403    (set_attr "pent_pair" "pu")
7404    (set_attr "mode" "SI")])
7405
7406 (define_insn "subsi3_carry_zext"
7407   [(set (match_operand:DI 0 "register_operand" "=r")
7408           (zero_extend:DI
7409             (minus:SI (match_operand:SI 1 "register_operand" "0")
7410               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7411                  (match_operand:SI 2 "general_operand" "g")))))
7412    (clobber (reg:CC FLAGS_REG))]
7413   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7414   "sbb{l}\t{%2, %k0|%k0, %2}"
7415   [(set_attr "type" "alu")
7416    (set_attr "pent_pair" "pu")
7417    (set_attr "mode" "SI")])
7418
7419 (define_expand "subsi3"
7420   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7421         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7422                   (match_operand:SI 2 "general_operand" "")))]
7423   ""
7424   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7425
7426 (define_insn "*subsi_1"
7427   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7428         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7429                   (match_operand:SI 2 "general_operand" "ri,rm")))
7430    (clobber (reg:CC FLAGS_REG))]
7431   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7432   "sub{l}\t{%2, %0|%0, %2}"
7433   [(set_attr "type" "alu")
7434    (set_attr "mode" "SI")])
7435
7436 (define_insn "*subsi_1_zext"
7437   [(set (match_operand:DI 0 "register_operand" "=r")
7438         (zero_extend:DI
7439           (minus:SI (match_operand:SI 1 "register_operand" "0")
7440                     (match_operand:SI 2 "general_operand" "g"))))
7441    (clobber (reg:CC FLAGS_REG))]
7442   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7443   "sub{l}\t{%2, %k0|%k0, %2}"
7444   [(set_attr "type" "alu")
7445    (set_attr "mode" "SI")])
7446
7447 (define_insn "*subsi_2"
7448   [(set (reg FLAGS_REG)
7449         (compare
7450           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7451                     (match_operand:SI 2 "general_operand" "ri,rm"))
7452           (const_int 0)))
7453    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7454         (minus:SI (match_dup 1) (match_dup 2)))]
7455   "ix86_match_ccmode (insn, CCGOCmode)
7456    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7457   "sub{l}\t{%2, %0|%0, %2}"
7458   [(set_attr "type" "alu")
7459    (set_attr "mode" "SI")])
7460
7461 (define_insn "*subsi_2_zext"
7462   [(set (reg FLAGS_REG)
7463         (compare
7464           (minus:SI (match_operand:SI 1 "register_operand" "0")
7465                     (match_operand:SI 2 "general_operand" "g"))
7466           (const_int 0)))
7467    (set (match_operand:DI 0 "register_operand" "=r")
7468         (zero_extend:DI
7469           (minus:SI (match_dup 1)
7470                     (match_dup 2))))]
7471   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7472    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7473   "sub{l}\t{%2, %k0|%k0, %2}"
7474   [(set_attr "type" "alu")
7475    (set_attr "mode" "SI")])
7476
7477 (define_insn "*subsi_3"
7478   [(set (reg FLAGS_REG)
7479         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7480                  (match_operand:SI 2 "general_operand" "ri,rm")))
7481    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7482         (minus:SI (match_dup 1) (match_dup 2)))]
7483   "ix86_match_ccmode (insn, CCmode)
7484    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7485   "sub{l}\t{%2, %0|%0, %2}"
7486   [(set_attr "type" "alu")
7487    (set_attr "mode" "SI")])
7488
7489 (define_insn "*subsi_3_zext"
7490   [(set (reg FLAGS_REG)
7491         (compare (match_operand:SI 1 "register_operand" "0")
7492                  (match_operand:SI 2 "general_operand" "g")))
7493    (set (match_operand:DI 0 "register_operand" "=r")
7494         (zero_extend:DI
7495           (minus:SI (match_dup 1)
7496                     (match_dup 2))))]
7497   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7498    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7499   "sub{l}\t{%2, %1|%1, %2}"
7500   [(set_attr "type" "alu")
7501    (set_attr "mode" "DI")])
7502
7503 (define_expand "subhi3"
7504   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7505         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7506                   (match_operand:HI 2 "general_operand" "")))]
7507   "TARGET_HIMODE_MATH"
7508   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7509
7510 (define_insn "*subhi_1"
7511   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7512         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7513                   (match_operand:HI 2 "general_operand" "rn,rm")))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7516   "sub{w}\t{%2, %0|%0, %2}"
7517   [(set_attr "type" "alu")
7518    (set_attr "mode" "HI")])
7519
7520 (define_insn "*subhi_2"
7521   [(set (reg FLAGS_REG)
7522         (compare
7523           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7524                     (match_operand:HI 2 "general_operand" "rn,rm"))
7525           (const_int 0)))
7526    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7527         (minus:HI (match_dup 1) (match_dup 2)))]
7528   "ix86_match_ccmode (insn, CCGOCmode)
7529    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7530   "sub{w}\t{%2, %0|%0, %2}"
7531   [(set_attr "type" "alu")
7532    (set_attr "mode" "HI")])
7533
7534 (define_insn "*subhi_3"
7535   [(set (reg FLAGS_REG)
7536         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7537                  (match_operand:HI 2 "general_operand" "rn,rm")))
7538    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7539         (minus:HI (match_dup 1) (match_dup 2)))]
7540   "ix86_match_ccmode (insn, CCmode)
7541    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7542   "sub{w}\t{%2, %0|%0, %2}"
7543   [(set_attr "type" "alu")
7544    (set_attr "mode" "HI")])
7545
7546 (define_expand "subqi3"
7547   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7548         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7549                   (match_operand:QI 2 "general_operand" "")))]
7550   "TARGET_QIMODE_MATH"
7551   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7552
7553 (define_insn "*subqi_1"
7554   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7555         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7556                   (match_operand:QI 2 "general_operand" "qn,qm")))
7557    (clobber (reg:CC FLAGS_REG))]
7558   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7559   "sub{b}\t{%2, %0|%0, %2}"
7560   [(set_attr "type" "alu")
7561    (set_attr "mode" "QI")])
7562
7563 (define_insn "*subqi_1_slp"
7564   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7565         (minus:QI (match_dup 0)
7566                   (match_operand:QI 1 "general_operand" "qn,qm")))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7569    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7570   "sub{b}\t{%1, %0|%0, %1}"
7571   [(set_attr "type" "alu1")
7572    (set_attr "mode" "QI")])
7573
7574 (define_insn "*subqi_2"
7575   [(set (reg FLAGS_REG)
7576         (compare
7577           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7578                     (match_operand:QI 2 "general_operand" "qn,qm"))
7579           (const_int 0)))
7580    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7581         (minus:QI (match_dup 1) (match_dup 2)))]
7582   "ix86_match_ccmode (insn, CCGOCmode)
7583    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7584   "sub{b}\t{%2, %0|%0, %2}"
7585   [(set_attr "type" "alu")
7586    (set_attr "mode" "QI")])
7587
7588 (define_insn "*subqi_3"
7589   [(set (reg FLAGS_REG)
7590         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7591                  (match_operand:QI 2 "general_operand" "qn,qm")))
7592    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7593         (minus:QI (match_dup 1) (match_dup 2)))]
7594   "ix86_match_ccmode (insn, CCmode)
7595    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7596   "sub{b}\t{%2, %0|%0, %2}"
7597   [(set_attr "type" "alu")
7598    (set_attr "mode" "QI")])
7599
7600 ;; The patterns that match these are at the end of this file.
7601
7602 (define_expand "subxf3"
7603   [(set (match_operand:XF 0 "register_operand" "")
7604         (minus:XF (match_operand:XF 1 "register_operand" "")
7605                   (match_operand:XF 2 "register_operand" "")))]
7606   "TARGET_80387"
7607   "")
7608
7609 (define_expand "sub<mode>3"
7610   [(set (match_operand:MODEF 0 "register_operand" "")
7611         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7612                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7613   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7614   "")
7615 \f
7616 ;; Multiply instructions
7617
7618 (define_expand "muldi3"
7619   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7620                    (mult:DI (match_operand:DI 1 "register_operand" "")
7621                             (match_operand:DI 2 "x86_64_general_operand" "")))
7622               (clobber (reg:CC FLAGS_REG))])]
7623   "TARGET_64BIT"
7624   "")
7625
7626 ;; On AMDFAM10
7627 ;; IMUL reg64, reg64, imm8      Direct
7628 ;; IMUL reg64, mem64, imm8      VectorPath
7629 ;; IMUL reg64, reg64, imm32     Direct
7630 ;; IMUL reg64, mem64, imm32     VectorPath
7631 ;; IMUL reg64, reg64            Direct
7632 ;; IMUL reg64, mem64            Direct
7633
7634 (define_insn "*muldi3_1_rex64"
7635   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7636         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7637                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7638    (clobber (reg:CC FLAGS_REG))]
7639   "TARGET_64BIT
7640    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7641   "@
7642    imul{q}\t{%2, %1, %0|%0, %1, %2}
7643    imul{q}\t{%2, %1, %0|%0, %1, %2}
7644    imul{q}\t{%2, %0|%0, %2}"
7645   [(set_attr "type" "imul")
7646    (set_attr "prefix_0f" "0,0,1")
7647    (set (attr "athlon_decode")
7648         (cond [(eq_attr "cpu" "athlon")
7649                   (const_string "vector")
7650                (eq_attr "alternative" "1")
7651                   (const_string "vector")
7652                (and (eq_attr "alternative" "2")
7653                     (match_operand 1 "memory_operand" ""))
7654                   (const_string "vector")]
7655               (const_string "direct")))
7656    (set (attr "amdfam10_decode")
7657         (cond [(and (eq_attr "alternative" "0,1")
7658                     (match_operand 1 "memory_operand" ""))
7659                   (const_string "vector")]
7660               (const_string "direct")))
7661    (set_attr "mode" "DI")])
7662
7663 (define_expand "mulsi3"
7664   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7665                    (mult:SI (match_operand:SI 1 "register_operand" "")
7666                             (match_operand:SI 2 "general_operand" "")))
7667               (clobber (reg:CC FLAGS_REG))])]
7668   ""
7669   "")
7670
7671 ;; On AMDFAM10
7672 ;; IMUL reg32, reg32, imm8      Direct
7673 ;; IMUL reg32, mem32, imm8      VectorPath
7674 ;; IMUL reg32, reg32, imm32     Direct
7675 ;; IMUL reg32, mem32, imm32     VectorPath
7676 ;; IMUL reg32, reg32            Direct
7677 ;; IMUL reg32, mem32            Direct
7678
7679 (define_insn "*mulsi3_1"
7680   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7681         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7682                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7683    (clobber (reg:CC FLAGS_REG))]
7684   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7685   "@
7686    imul{l}\t{%2, %1, %0|%0, %1, %2}
7687    imul{l}\t{%2, %1, %0|%0, %1, %2}
7688    imul{l}\t{%2, %0|%0, %2}"
7689   [(set_attr "type" "imul")
7690    (set_attr "prefix_0f" "0,0,1")
7691    (set (attr "athlon_decode")
7692         (cond [(eq_attr "cpu" "athlon")
7693                   (const_string "vector")
7694                (eq_attr "alternative" "1")
7695                   (const_string "vector")
7696                (and (eq_attr "alternative" "2")
7697                     (match_operand 1 "memory_operand" ""))
7698                   (const_string "vector")]
7699               (const_string "direct")))
7700    (set (attr "amdfam10_decode")
7701         (cond [(and (eq_attr "alternative" "0,1")
7702                     (match_operand 1 "memory_operand" ""))
7703                   (const_string "vector")]
7704               (const_string "direct")))
7705    (set_attr "mode" "SI")])
7706
7707 (define_insn "*mulsi3_1_zext"
7708   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7709         (zero_extend:DI
7710           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7711                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7712    (clobber (reg:CC FLAGS_REG))]
7713   "TARGET_64BIT
7714    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7715   "@
7716    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7717    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7718    imul{l}\t{%2, %k0|%k0, %2}"
7719   [(set_attr "type" "imul")
7720    (set_attr "prefix_0f" "0,0,1")
7721    (set (attr "athlon_decode")
7722         (cond [(eq_attr "cpu" "athlon")
7723                   (const_string "vector")
7724                (eq_attr "alternative" "1")
7725                   (const_string "vector")
7726                (and (eq_attr "alternative" "2")
7727                     (match_operand 1 "memory_operand" ""))
7728                   (const_string "vector")]
7729               (const_string "direct")))
7730    (set (attr "amdfam10_decode")
7731         (cond [(and (eq_attr "alternative" "0,1")
7732                     (match_operand 1 "memory_operand" ""))
7733                   (const_string "vector")]
7734               (const_string "direct")))
7735    (set_attr "mode" "SI")])
7736
7737 (define_expand "mulhi3"
7738   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7739                    (mult:HI (match_operand:HI 1 "register_operand" "")
7740                             (match_operand:HI 2 "general_operand" "")))
7741               (clobber (reg:CC FLAGS_REG))])]
7742   "TARGET_HIMODE_MATH"
7743   "")
7744
7745 ;; On AMDFAM10
7746 ;; IMUL reg16, reg16, imm8      VectorPath
7747 ;; IMUL reg16, mem16, imm8      VectorPath
7748 ;; IMUL reg16, reg16, imm16     VectorPath
7749 ;; IMUL reg16, mem16, imm16     VectorPath
7750 ;; IMUL reg16, reg16            Direct
7751 ;; IMUL reg16, mem16            Direct
7752 (define_insn "*mulhi3_1"
7753   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7754         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7755                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7756    (clobber (reg:CC FLAGS_REG))]
7757   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7758   "@
7759    imul{w}\t{%2, %1, %0|%0, %1, %2}
7760    imul{w}\t{%2, %1, %0|%0, %1, %2}
7761    imul{w}\t{%2, %0|%0, %2}"
7762   [(set_attr "type" "imul")
7763    (set_attr "prefix_0f" "0,0,1")
7764    (set (attr "athlon_decode")
7765         (cond [(eq_attr "cpu" "athlon")
7766                   (const_string "vector")
7767                (eq_attr "alternative" "1,2")
7768                   (const_string "vector")]
7769               (const_string "direct")))
7770    (set (attr "amdfam10_decode")
7771         (cond [(eq_attr "alternative" "0,1")
7772                   (const_string "vector")]
7773               (const_string "direct")))
7774    (set_attr "mode" "HI")])
7775
7776 (define_expand "mulqi3"
7777   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7778                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7779                             (match_operand:QI 2 "register_operand" "")))
7780               (clobber (reg:CC FLAGS_REG))])]
7781   "TARGET_QIMODE_MATH"
7782   "")
7783
7784 ;;On AMDFAM10
7785 ;; MUL reg8     Direct
7786 ;; MUL mem8     Direct
7787
7788 (define_insn "*mulqi3_1"
7789   [(set (match_operand:QI 0 "register_operand" "=a")
7790         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7791                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7792    (clobber (reg:CC FLAGS_REG))]
7793   "TARGET_QIMODE_MATH
7794    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7795   "mul{b}\t%2"
7796   [(set_attr "type" "imul")
7797    (set_attr "length_immediate" "0")
7798    (set (attr "athlon_decode")
7799      (if_then_else (eq_attr "cpu" "athlon")
7800         (const_string "vector")
7801         (const_string "direct")))
7802    (set_attr "amdfam10_decode" "direct")
7803    (set_attr "mode" "QI")])
7804
7805 (define_expand "umulqihi3"
7806   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7807                    (mult:HI (zero_extend:HI
7808                               (match_operand:QI 1 "nonimmediate_operand" ""))
7809                             (zero_extend:HI
7810                               (match_operand:QI 2 "register_operand" ""))))
7811               (clobber (reg:CC FLAGS_REG))])]
7812   "TARGET_QIMODE_MATH"
7813   "")
7814
7815 (define_insn "*umulqihi3_1"
7816   [(set (match_operand:HI 0 "register_operand" "=a")
7817         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7818                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7819    (clobber (reg:CC FLAGS_REG))]
7820   "TARGET_QIMODE_MATH
7821    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7822   "mul{b}\t%2"
7823   [(set_attr "type" "imul")
7824    (set_attr "length_immediate" "0")
7825    (set (attr "athlon_decode")
7826      (if_then_else (eq_attr "cpu" "athlon")
7827         (const_string "vector")
7828         (const_string "direct")))
7829    (set_attr "amdfam10_decode" "direct")
7830    (set_attr "mode" "QI")])
7831
7832 (define_expand "mulqihi3"
7833   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7834                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7835                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7836               (clobber (reg:CC FLAGS_REG))])]
7837   "TARGET_QIMODE_MATH"
7838   "")
7839
7840 (define_insn "*mulqihi3_insn"
7841   [(set (match_operand:HI 0 "register_operand" "=a")
7842         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7843                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7844    (clobber (reg:CC FLAGS_REG))]
7845   "TARGET_QIMODE_MATH
7846    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7847   "imul{b}\t%2"
7848   [(set_attr "type" "imul")
7849    (set_attr "length_immediate" "0")
7850    (set (attr "athlon_decode")
7851      (if_then_else (eq_attr "cpu" "athlon")
7852         (const_string "vector")
7853         (const_string "direct")))
7854    (set_attr "amdfam10_decode" "direct")
7855    (set_attr "mode" "QI")])
7856
7857 (define_expand "umulditi3"
7858   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7859                    (mult:TI (zero_extend:TI
7860                               (match_operand:DI 1 "nonimmediate_operand" ""))
7861                             (zero_extend:TI
7862                               (match_operand:DI 2 "register_operand" ""))))
7863               (clobber (reg:CC FLAGS_REG))])]
7864   "TARGET_64BIT"
7865   "")
7866
7867 (define_insn "*umulditi3_insn"
7868   [(set (match_operand:TI 0 "register_operand" "=A")
7869         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7870                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7871    (clobber (reg:CC FLAGS_REG))]
7872   "TARGET_64BIT
7873    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7874   "mul{q}\t%2"
7875   [(set_attr "type" "imul")
7876    (set_attr "length_immediate" "0")
7877    (set (attr "athlon_decode")
7878      (if_then_else (eq_attr "cpu" "athlon")
7879         (const_string "vector")
7880         (const_string "double")))
7881    (set_attr "amdfam10_decode" "double")
7882    (set_attr "mode" "DI")])
7883
7884 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7885 (define_expand "umulsidi3"
7886   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7887                    (mult:DI (zero_extend:DI
7888                               (match_operand:SI 1 "nonimmediate_operand" ""))
7889                             (zero_extend:DI
7890                               (match_operand:SI 2 "register_operand" ""))))
7891               (clobber (reg:CC FLAGS_REG))])]
7892   "!TARGET_64BIT"
7893   "")
7894
7895 (define_insn "*umulsidi3_insn"
7896   [(set (match_operand:DI 0 "register_operand" "=A")
7897         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7898                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7899    (clobber (reg:CC FLAGS_REG))]
7900   "!TARGET_64BIT
7901    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7902   "mul{l}\t%2"
7903   [(set_attr "type" "imul")
7904    (set_attr "length_immediate" "0")
7905    (set (attr "athlon_decode")
7906      (if_then_else (eq_attr "cpu" "athlon")
7907         (const_string "vector")
7908         (const_string "double")))
7909    (set_attr "amdfam10_decode" "double")
7910    (set_attr "mode" "SI")])
7911
7912 (define_expand "mulditi3"
7913   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7914                    (mult:TI (sign_extend:TI
7915                               (match_operand:DI 1 "nonimmediate_operand" ""))
7916                             (sign_extend:TI
7917                               (match_operand:DI 2 "register_operand" ""))))
7918               (clobber (reg:CC FLAGS_REG))])]
7919   "TARGET_64BIT"
7920   "")
7921
7922 (define_insn "*mulditi3_insn"
7923   [(set (match_operand:TI 0 "register_operand" "=A")
7924         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7925                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7926    (clobber (reg:CC FLAGS_REG))]
7927   "TARGET_64BIT
7928    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7929   "imul{q}\t%2"
7930   [(set_attr "type" "imul")
7931    (set_attr "length_immediate" "0")
7932    (set (attr "athlon_decode")
7933      (if_then_else (eq_attr "cpu" "athlon")
7934         (const_string "vector")
7935         (const_string "double")))
7936    (set_attr "amdfam10_decode" "double")
7937    (set_attr "mode" "DI")])
7938
7939 (define_expand "mulsidi3"
7940   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7941                    (mult:DI (sign_extend:DI
7942                               (match_operand:SI 1 "nonimmediate_operand" ""))
7943                             (sign_extend:DI
7944                               (match_operand:SI 2 "register_operand" ""))))
7945               (clobber (reg:CC FLAGS_REG))])]
7946   "!TARGET_64BIT"
7947   "")
7948
7949 (define_insn "*mulsidi3_insn"
7950   [(set (match_operand:DI 0 "register_operand" "=A")
7951         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7952                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7953    (clobber (reg:CC FLAGS_REG))]
7954   "!TARGET_64BIT
7955    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7956   "imul{l}\t%2"
7957   [(set_attr "type" "imul")
7958    (set_attr "length_immediate" "0")
7959    (set (attr "athlon_decode")
7960      (if_then_else (eq_attr "cpu" "athlon")
7961         (const_string "vector")
7962         (const_string "double")))
7963    (set_attr "amdfam10_decode" "double")
7964    (set_attr "mode" "SI")])
7965
7966 (define_expand "umuldi3_highpart"
7967   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7968                    (truncate:DI
7969                      (lshiftrt:TI
7970                        (mult:TI (zero_extend:TI
7971                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7972                                 (zero_extend:TI
7973                                   (match_operand:DI 2 "register_operand" "")))
7974                        (const_int 64))))
7975               (clobber (match_scratch:DI 3 ""))
7976               (clobber (reg:CC FLAGS_REG))])]
7977   "TARGET_64BIT"
7978   "")
7979
7980 (define_insn "*umuldi3_highpart_rex64"
7981   [(set (match_operand:DI 0 "register_operand" "=d")
7982         (truncate:DI
7983           (lshiftrt:TI
7984             (mult:TI (zero_extend:TI
7985                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7986                      (zero_extend:TI
7987                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7988             (const_int 64))))
7989    (clobber (match_scratch:DI 3 "=1"))
7990    (clobber (reg:CC FLAGS_REG))]
7991   "TARGET_64BIT
7992    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7993   "mul{q}\t%2"
7994   [(set_attr "type" "imul")
7995    (set_attr "length_immediate" "0")
7996    (set (attr "athlon_decode")
7997      (if_then_else (eq_attr "cpu" "athlon")
7998         (const_string "vector")
7999         (const_string "double")))
8000    (set_attr "amdfam10_decode" "double")
8001    (set_attr "mode" "DI")])
8002
8003 (define_expand "umulsi3_highpart"
8004   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8005                    (truncate:SI
8006                      (lshiftrt:DI
8007                        (mult:DI (zero_extend:DI
8008                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8009                                 (zero_extend:DI
8010                                   (match_operand:SI 2 "register_operand" "")))
8011                        (const_int 32))))
8012               (clobber (match_scratch:SI 3 ""))
8013               (clobber (reg:CC FLAGS_REG))])]
8014   ""
8015   "")
8016
8017 (define_insn "*umulsi3_highpart_insn"
8018   [(set (match_operand:SI 0 "register_operand" "=d")
8019         (truncate:SI
8020           (lshiftrt:DI
8021             (mult:DI (zero_extend:DI
8022                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8023                      (zero_extend:DI
8024                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8025             (const_int 32))))
8026    (clobber (match_scratch:SI 3 "=1"))
8027    (clobber (reg:CC FLAGS_REG))]
8028   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8029   "mul{l}\t%2"
8030   [(set_attr "type" "imul")
8031    (set_attr "length_immediate" "0")
8032    (set (attr "athlon_decode")
8033      (if_then_else (eq_attr "cpu" "athlon")
8034         (const_string "vector")
8035         (const_string "double")))
8036    (set_attr "amdfam10_decode" "double")
8037    (set_attr "mode" "SI")])
8038
8039 (define_insn "*umulsi3_highpart_zext"
8040   [(set (match_operand:DI 0 "register_operand" "=d")
8041         (zero_extend:DI (truncate:SI
8042           (lshiftrt:DI
8043             (mult:DI (zero_extend:DI
8044                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8045                      (zero_extend:DI
8046                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8047             (const_int 32)))))
8048    (clobber (match_scratch:SI 3 "=1"))
8049    (clobber (reg:CC FLAGS_REG))]
8050   "TARGET_64BIT
8051    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8052   "mul{l}\t%2"
8053   [(set_attr "type" "imul")
8054    (set_attr "length_immediate" "0")
8055    (set (attr "athlon_decode")
8056      (if_then_else (eq_attr "cpu" "athlon")
8057         (const_string "vector")
8058         (const_string "double")))
8059    (set_attr "amdfam10_decode" "double")
8060    (set_attr "mode" "SI")])
8061
8062 (define_expand "smuldi3_highpart"
8063   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8064                    (truncate:DI
8065                      (lshiftrt:TI
8066                        (mult:TI (sign_extend:TI
8067                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8068                                 (sign_extend:TI
8069                                   (match_operand:DI 2 "register_operand" "")))
8070                        (const_int 64))))
8071               (clobber (match_scratch:DI 3 ""))
8072               (clobber (reg:CC FLAGS_REG))])]
8073   "TARGET_64BIT"
8074   "")
8075
8076 (define_insn "*smuldi3_highpart_rex64"
8077   [(set (match_operand:DI 0 "register_operand" "=d")
8078         (truncate:DI
8079           (lshiftrt:TI
8080             (mult:TI (sign_extend:TI
8081                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8082                      (sign_extend:TI
8083                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8084             (const_int 64))))
8085    (clobber (match_scratch:DI 3 "=1"))
8086    (clobber (reg:CC FLAGS_REG))]
8087   "TARGET_64BIT
8088    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8089   "imul{q}\t%2"
8090   [(set_attr "type" "imul")
8091    (set (attr "athlon_decode")
8092      (if_then_else (eq_attr "cpu" "athlon")
8093         (const_string "vector")
8094         (const_string "double")))
8095    (set_attr "amdfam10_decode" "double")
8096    (set_attr "mode" "DI")])
8097
8098 (define_expand "smulsi3_highpart"
8099   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8100                    (truncate:SI
8101                      (lshiftrt:DI
8102                        (mult:DI (sign_extend:DI
8103                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8104                                 (sign_extend:DI
8105                                   (match_operand:SI 2 "register_operand" "")))
8106                        (const_int 32))))
8107               (clobber (match_scratch:SI 3 ""))
8108               (clobber (reg:CC FLAGS_REG))])]
8109   ""
8110   "")
8111
8112 (define_insn "*smulsi3_highpart_insn"
8113   [(set (match_operand:SI 0 "register_operand" "=d")
8114         (truncate:SI
8115           (lshiftrt:DI
8116             (mult:DI (sign_extend:DI
8117                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8118                      (sign_extend:DI
8119                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8120             (const_int 32))))
8121    (clobber (match_scratch:SI 3 "=1"))
8122    (clobber (reg:CC FLAGS_REG))]
8123   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8124   "imul{l}\t%2"
8125   [(set_attr "type" "imul")
8126    (set (attr "athlon_decode")
8127      (if_then_else (eq_attr "cpu" "athlon")
8128         (const_string "vector")
8129         (const_string "double")))
8130    (set_attr "amdfam10_decode" "double")
8131    (set_attr "mode" "SI")])
8132
8133 (define_insn "*smulsi3_highpart_zext"
8134   [(set (match_operand:DI 0 "register_operand" "=d")
8135         (zero_extend:DI (truncate:SI
8136           (lshiftrt:DI
8137             (mult:DI (sign_extend:DI
8138                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8139                      (sign_extend:DI
8140                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8141             (const_int 32)))))
8142    (clobber (match_scratch:SI 3 "=1"))
8143    (clobber (reg:CC FLAGS_REG))]
8144   "TARGET_64BIT
8145    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8146   "imul{l}\t%2"
8147   [(set_attr "type" "imul")
8148    (set (attr "athlon_decode")
8149      (if_then_else (eq_attr "cpu" "athlon")
8150         (const_string "vector")
8151         (const_string "double")))
8152    (set_attr "amdfam10_decode" "double")
8153    (set_attr "mode" "SI")])
8154
8155 ;; The patterns that match these are at the end of this file.
8156
8157 (define_expand "mulxf3"
8158   [(set (match_operand:XF 0 "register_operand" "")
8159         (mult:XF (match_operand:XF 1 "register_operand" "")
8160                  (match_operand:XF 2 "register_operand" "")))]
8161   "TARGET_80387"
8162   "")
8163
8164 (define_expand "mul<mode>3"
8165   [(set (match_operand:MODEF 0 "register_operand" "")
8166         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8167                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8168   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8169   "")
8170
8171 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8172
8173 \f
8174 ;; Divide instructions
8175
8176 (define_insn "divqi3"
8177   [(set (match_operand:QI 0 "register_operand" "=a")
8178         (div:QI (match_operand:HI 1 "register_operand" "0")
8179                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8180    (clobber (reg:CC FLAGS_REG))]
8181   "TARGET_QIMODE_MATH"
8182   "idiv{b}\t%2"
8183   [(set_attr "type" "idiv")
8184    (set_attr "mode" "QI")])
8185
8186 (define_insn "udivqi3"
8187   [(set (match_operand:QI 0 "register_operand" "=a")
8188         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8189                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "TARGET_QIMODE_MATH"
8192   "div{b}\t%2"
8193   [(set_attr "type" "idiv")
8194    (set_attr "mode" "QI")])
8195
8196 ;; The patterns that match these are at the end of this file.
8197
8198 (define_expand "divxf3"
8199   [(set (match_operand:XF 0 "register_operand" "")
8200         (div:XF (match_operand:XF 1 "register_operand" "")
8201                 (match_operand:XF 2 "register_operand" "")))]
8202   "TARGET_80387"
8203   "")
8204
8205 (define_expand "divdf3"
8206   [(set (match_operand:DF 0 "register_operand" "")
8207         (div:DF (match_operand:DF 1 "register_operand" "")
8208                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8209    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8210    "")
8211
8212 (define_expand "divsf3"
8213   [(set (match_operand:SF 0 "register_operand" "")
8214         (div:SF (match_operand:SF 1 "register_operand" "")
8215                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8216   "TARGET_80387 || TARGET_SSE_MATH"
8217 {
8218   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8219       && flag_finite_math_only && !flag_trapping_math
8220       && flag_unsafe_math_optimizations)
8221     {
8222       ix86_emit_swdivsf (operands[0], operands[1],
8223                          operands[2], SFmode);
8224       DONE;
8225     }
8226 })
8227 \f
8228 ;; Remainder instructions.
8229
8230 (define_expand "divmoddi4"
8231   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8232                    (div:DI (match_operand:DI 1 "register_operand" "")
8233                            (match_operand:DI 2 "nonimmediate_operand" "")))
8234               (set (match_operand:DI 3 "register_operand" "")
8235                    (mod:DI (match_dup 1) (match_dup 2)))
8236               (clobber (reg:CC FLAGS_REG))])]
8237   "TARGET_64BIT"
8238   "")
8239
8240 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8241 ;; Penalize eax case slightly because it results in worse scheduling
8242 ;; of code.
8243 (define_insn "*divmoddi4_nocltd_rex64"
8244   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8245         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8246                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8247    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8248         (mod:DI (match_dup 2) (match_dup 3)))
8249    (clobber (reg:CC FLAGS_REG))]
8250   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8251   "#"
8252   [(set_attr "type" "multi")])
8253
8254 (define_insn "*divmoddi4_cltd_rex64"
8255   [(set (match_operand:DI 0 "register_operand" "=a")
8256         (div:DI (match_operand:DI 2 "register_operand" "a")
8257                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8258    (set (match_operand:DI 1 "register_operand" "=&d")
8259         (mod:DI (match_dup 2) (match_dup 3)))
8260    (clobber (reg:CC FLAGS_REG))]
8261   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8262   "#"
8263   [(set_attr "type" "multi")])
8264
8265 (define_insn "*divmoddi_noext_rex64"
8266   [(set (match_operand:DI 0 "register_operand" "=a")
8267         (div:DI (match_operand:DI 1 "register_operand" "0")
8268                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8269    (set (match_operand:DI 3 "register_operand" "=d")
8270         (mod:DI (match_dup 1) (match_dup 2)))
8271    (use (match_operand:DI 4 "register_operand" "3"))
8272    (clobber (reg:CC FLAGS_REG))]
8273   "TARGET_64BIT"
8274   "idiv{q}\t%2"
8275   [(set_attr "type" "idiv")
8276    (set_attr "mode" "DI")])
8277
8278 (define_split
8279   [(set (match_operand:DI 0 "register_operand" "")
8280         (div:DI (match_operand:DI 1 "register_operand" "")
8281                 (match_operand:DI 2 "nonimmediate_operand" "")))
8282    (set (match_operand:DI 3 "register_operand" "")
8283         (mod:DI (match_dup 1) (match_dup 2)))
8284    (clobber (reg:CC FLAGS_REG))]
8285   "TARGET_64BIT && reload_completed"
8286   [(parallel [(set (match_dup 3)
8287                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8288               (clobber (reg:CC FLAGS_REG))])
8289    (parallel [(set (match_dup 0)
8290                    (div:DI (reg:DI 0) (match_dup 2)))
8291               (set (match_dup 3)
8292                    (mod:DI (reg:DI 0) (match_dup 2)))
8293               (use (match_dup 3))
8294               (clobber (reg:CC FLAGS_REG))])]
8295 {
8296   /* Avoid use of cltd in favor of a mov+shift.  */
8297   if (!TARGET_USE_CLTD && !optimize_size)
8298     {
8299       if (true_regnum (operands[1]))
8300         emit_move_insn (operands[0], operands[1]);
8301       else
8302         emit_move_insn (operands[3], operands[1]);
8303       operands[4] = operands[3];
8304     }
8305   else
8306     {
8307       gcc_assert (!true_regnum (operands[1]));
8308       operands[4] = operands[1];
8309     }
8310 })
8311
8312
8313 (define_expand "divmodsi4"
8314   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8315                    (div:SI (match_operand:SI 1 "register_operand" "")
8316                            (match_operand:SI 2 "nonimmediate_operand" "")))
8317               (set (match_operand:SI 3 "register_operand" "")
8318                    (mod:SI (match_dup 1) (match_dup 2)))
8319               (clobber (reg:CC FLAGS_REG))])]
8320   ""
8321   "")
8322
8323 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8324 ;; Penalize eax case slightly because it results in worse scheduling
8325 ;; of code.
8326 (define_insn "*divmodsi4_nocltd"
8327   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8328         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8329                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8330    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8331         (mod:SI (match_dup 2) (match_dup 3)))
8332    (clobber (reg:CC FLAGS_REG))]
8333   "!optimize_size && !TARGET_USE_CLTD"
8334   "#"
8335   [(set_attr "type" "multi")])
8336
8337 (define_insn "*divmodsi4_cltd"
8338   [(set (match_operand:SI 0 "register_operand" "=a")
8339         (div:SI (match_operand:SI 2 "register_operand" "a")
8340                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8341    (set (match_operand:SI 1 "register_operand" "=&d")
8342         (mod:SI (match_dup 2) (match_dup 3)))
8343    (clobber (reg:CC FLAGS_REG))]
8344   "optimize_size || TARGET_USE_CLTD"
8345   "#"
8346   [(set_attr "type" "multi")])
8347
8348 (define_insn "*divmodsi_noext"
8349   [(set (match_operand:SI 0 "register_operand" "=a")
8350         (div:SI (match_operand:SI 1 "register_operand" "0")
8351                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8352    (set (match_operand:SI 3 "register_operand" "=d")
8353         (mod:SI (match_dup 1) (match_dup 2)))
8354    (use (match_operand:SI 4 "register_operand" "3"))
8355    (clobber (reg:CC FLAGS_REG))]
8356   ""
8357   "idiv{l}\t%2"
8358   [(set_attr "type" "idiv")
8359    (set_attr "mode" "SI")])
8360
8361 (define_split
8362   [(set (match_operand:SI 0 "register_operand" "")
8363         (div:SI (match_operand:SI 1 "register_operand" "")
8364                 (match_operand:SI 2 "nonimmediate_operand" "")))
8365    (set (match_operand:SI 3 "register_operand" "")
8366         (mod:SI (match_dup 1) (match_dup 2)))
8367    (clobber (reg:CC FLAGS_REG))]
8368   "reload_completed"
8369   [(parallel [(set (match_dup 3)
8370                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8371               (clobber (reg:CC FLAGS_REG))])
8372    (parallel [(set (match_dup 0)
8373                    (div:SI (reg:SI 0) (match_dup 2)))
8374               (set (match_dup 3)
8375                    (mod:SI (reg:SI 0) (match_dup 2)))
8376               (use (match_dup 3))
8377               (clobber (reg:CC FLAGS_REG))])]
8378 {
8379   /* Avoid use of cltd in favor of a mov+shift.  */
8380   if (!TARGET_USE_CLTD && !optimize_size)
8381     {
8382       if (true_regnum (operands[1]))
8383         emit_move_insn (operands[0], operands[1]);
8384       else
8385         emit_move_insn (operands[3], operands[1]);
8386       operands[4] = operands[3];
8387     }
8388   else
8389     {
8390       gcc_assert (!true_regnum (operands[1]));
8391       operands[4] = operands[1];
8392     }
8393 })
8394 ;; %%% Split me.
8395 (define_insn "divmodhi4"
8396   [(set (match_operand:HI 0 "register_operand" "=a")
8397         (div:HI (match_operand:HI 1 "register_operand" "0")
8398                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8399    (set (match_operand:HI 3 "register_operand" "=&d")
8400         (mod:HI (match_dup 1) (match_dup 2)))
8401    (clobber (reg:CC FLAGS_REG))]
8402   "TARGET_HIMODE_MATH"
8403   "cwtd\;idiv{w}\t%2"
8404   [(set_attr "type" "multi")
8405    (set_attr "length_immediate" "0")
8406    (set_attr "mode" "SI")])
8407
8408 (define_insn "udivmoddi4"
8409   [(set (match_operand:DI 0 "register_operand" "=a")
8410         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8411                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8412    (set (match_operand:DI 3 "register_operand" "=&d")
8413         (umod:DI (match_dup 1) (match_dup 2)))
8414    (clobber (reg:CC FLAGS_REG))]
8415   "TARGET_64BIT"
8416   "xor{q}\t%3, %3\;div{q}\t%2"
8417   [(set_attr "type" "multi")
8418    (set_attr "length_immediate" "0")
8419    (set_attr "mode" "DI")])
8420
8421 (define_insn "*udivmoddi4_noext"
8422   [(set (match_operand:DI 0 "register_operand" "=a")
8423         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8424                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8425    (set (match_operand:DI 3 "register_operand" "=d")
8426         (umod:DI (match_dup 1) (match_dup 2)))
8427    (use (match_dup 3))
8428    (clobber (reg:CC FLAGS_REG))]
8429   "TARGET_64BIT"
8430   "div{q}\t%2"
8431   [(set_attr "type" "idiv")
8432    (set_attr "mode" "DI")])
8433
8434 (define_split
8435   [(set (match_operand:DI 0 "register_operand" "")
8436         (udiv:DI (match_operand:DI 1 "register_operand" "")
8437                  (match_operand:DI 2 "nonimmediate_operand" "")))
8438    (set (match_operand:DI 3 "register_operand" "")
8439         (umod:DI (match_dup 1) (match_dup 2)))
8440    (clobber (reg:CC FLAGS_REG))]
8441   "TARGET_64BIT && reload_completed"
8442   [(set (match_dup 3) (const_int 0))
8443    (parallel [(set (match_dup 0)
8444                    (udiv:DI (match_dup 1) (match_dup 2)))
8445               (set (match_dup 3)
8446                    (umod:DI (match_dup 1) (match_dup 2)))
8447               (use (match_dup 3))
8448               (clobber (reg:CC FLAGS_REG))])]
8449   "")
8450
8451 (define_insn "udivmodsi4"
8452   [(set (match_operand:SI 0 "register_operand" "=a")
8453         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8454                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8455    (set (match_operand:SI 3 "register_operand" "=&d")
8456         (umod:SI (match_dup 1) (match_dup 2)))
8457    (clobber (reg:CC FLAGS_REG))]
8458   ""
8459   "xor{l}\t%3, %3\;div{l}\t%2"
8460   [(set_attr "type" "multi")
8461    (set_attr "length_immediate" "0")
8462    (set_attr "mode" "SI")])
8463
8464 (define_insn "*udivmodsi4_noext"
8465   [(set (match_operand:SI 0 "register_operand" "=a")
8466         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8467                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8468    (set (match_operand:SI 3 "register_operand" "=d")
8469         (umod:SI (match_dup 1) (match_dup 2)))
8470    (use (match_dup 3))
8471    (clobber (reg:CC FLAGS_REG))]
8472   ""
8473   "div{l}\t%2"
8474   [(set_attr "type" "idiv")
8475    (set_attr "mode" "SI")])
8476
8477 (define_split
8478   [(set (match_operand:SI 0 "register_operand" "")
8479         (udiv:SI (match_operand:SI 1 "register_operand" "")
8480                  (match_operand:SI 2 "nonimmediate_operand" "")))
8481    (set (match_operand:SI 3 "register_operand" "")
8482         (umod:SI (match_dup 1) (match_dup 2)))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "reload_completed"
8485   [(set (match_dup 3) (const_int 0))
8486    (parallel [(set (match_dup 0)
8487                    (udiv:SI (match_dup 1) (match_dup 2)))
8488               (set (match_dup 3)
8489                    (umod:SI (match_dup 1) (match_dup 2)))
8490               (use (match_dup 3))
8491               (clobber (reg:CC FLAGS_REG))])]
8492   "")
8493
8494 (define_expand "udivmodhi4"
8495   [(set (match_dup 4) (const_int 0))
8496    (parallel [(set (match_operand:HI 0 "register_operand" "")
8497                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8498                             (match_operand:HI 2 "nonimmediate_operand" "")))
8499               (set (match_operand:HI 3 "register_operand" "")
8500                    (umod:HI (match_dup 1) (match_dup 2)))
8501               (use (match_dup 4))
8502               (clobber (reg:CC FLAGS_REG))])]
8503   "TARGET_HIMODE_MATH"
8504   "operands[4] = gen_reg_rtx (HImode);")
8505
8506 (define_insn "*udivmodhi_noext"
8507   [(set (match_operand:HI 0 "register_operand" "=a")
8508         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8509                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8510    (set (match_operand:HI 3 "register_operand" "=d")
8511         (umod:HI (match_dup 1) (match_dup 2)))
8512    (use (match_operand:HI 4 "register_operand" "3"))
8513    (clobber (reg:CC FLAGS_REG))]
8514   ""
8515   "div{w}\t%2"
8516   [(set_attr "type" "idiv")
8517    (set_attr "mode" "HI")])
8518
8519 ;; We cannot use div/idiv for double division, because it causes
8520 ;; "division by zero" on the overflow and that's not what we expect
8521 ;; from truncate.  Because true (non truncating) double division is
8522 ;; never generated, we can't create this insn anyway.
8523 ;
8524 ;(define_insn ""
8525 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8526 ;       (truncate:SI
8527 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8528 ;                  (zero_extend:DI
8529 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8530 ;   (set (match_operand:SI 3 "register_operand" "=d")
8531 ;       (truncate:SI
8532 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8533 ;   (clobber (reg:CC FLAGS_REG))]
8534 ;  ""
8535 ;  "div{l}\t{%2, %0|%0, %2}"
8536 ;  [(set_attr "type" "idiv")])
8537 \f
8538 ;;- Logical AND instructions
8539
8540 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8541 ;; Note that this excludes ah.
8542
8543 (define_insn "*testdi_1_rex64"
8544   [(set (reg FLAGS_REG)
8545         (compare
8546           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8547                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8548           (const_int 0)))]
8549   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8550    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8551   "@
8552    test{l}\t{%k1, %k0|%k0, %k1}
8553    test{l}\t{%k1, %k0|%k0, %k1}
8554    test{q}\t{%1, %0|%0, %1}
8555    test{q}\t{%1, %0|%0, %1}
8556    test{q}\t{%1, %0|%0, %1}"
8557   [(set_attr "type" "test")
8558    (set_attr "modrm" "0,1,0,1,1")
8559    (set_attr "mode" "SI,SI,DI,DI,DI")
8560    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8561
8562 (define_insn "testsi_1"
8563   [(set (reg FLAGS_REG)
8564         (compare
8565           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8566                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8567           (const_int 0)))]
8568   "ix86_match_ccmode (insn, CCNOmode)
8569    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8570   "test{l}\t{%1, %0|%0, %1}"
8571   [(set_attr "type" "test")
8572    (set_attr "modrm" "0,1,1")
8573    (set_attr "mode" "SI")
8574    (set_attr "pent_pair" "uv,np,uv")])
8575
8576 (define_expand "testsi_ccno_1"
8577   [(set (reg:CCNO FLAGS_REG)
8578         (compare:CCNO
8579           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8580                   (match_operand:SI 1 "nonmemory_operand" ""))
8581           (const_int 0)))]
8582   ""
8583   "")
8584
8585 (define_insn "*testhi_1"
8586   [(set (reg FLAGS_REG)
8587         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8588                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8589                  (const_int 0)))]
8590   "ix86_match_ccmode (insn, CCNOmode)
8591    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8592   "test{w}\t{%1, %0|%0, %1}"
8593   [(set_attr "type" "test")
8594    (set_attr "modrm" "0,1,1")
8595    (set_attr "mode" "HI")
8596    (set_attr "pent_pair" "uv,np,uv")])
8597
8598 (define_expand "testqi_ccz_1"
8599   [(set (reg:CCZ FLAGS_REG)
8600         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8601                              (match_operand:QI 1 "nonmemory_operand" ""))
8602                  (const_int 0)))]
8603   ""
8604   "")
8605
8606 (define_insn "*testqi_1_maybe_si"
8607   [(set (reg FLAGS_REG)
8608         (compare
8609           (and:QI
8610             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8611             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8612           (const_int 0)))]
8613    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8614     && ix86_match_ccmode (insn,
8615                          CONST_INT_P (operands[1])
8616                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8617 {
8618   if (which_alternative == 3)
8619     {
8620       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8621         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8622       return "test{l}\t{%1, %k0|%k0, %1}";
8623     }
8624   return "test{b}\t{%1, %0|%0, %1}";
8625 }
8626   [(set_attr "type" "test")
8627    (set_attr "modrm" "0,1,1,1")
8628    (set_attr "mode" "QI,QI,QI,SI")
8629    (set_attr "pent_pair" "uv,np,uv,np")])
8630
8631 (define_insn "*testqi_1"
8632   [(set (reg FLAGS_REG)
8633         (compare
8634           (and:QI
8635             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8636             (match_operand:QI 1 "general_operand" "n,n,qn"))
8637           (const_int 0)))]
8638   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8639    && ix86_match_ccmode (insn, CCNOmode)"
8640   "test{b}\t{%1, %0|%0, %1}"
8641   [(set_attr "type" "test")
8642    (set_attr "modrm" "0,1,1")
8643    (set_attr "mode" "QI")
8644    (set_attr "pent_pair" "uv,np,uv")])
8645
8646 (define_expand "testqi_ext_ccno_0"
8647   [(set (reg:CCNO FLAGS_REG)
8648         (compare:CCNO
8649           (and:SI
8650             (zero_extract:SI
8651               (match_operand 0 "ext_register_operand" "")
8652               (const_int 8)
8653               (const_int 8))
8654             (match_operand 1 "const_int_operand" ""))
8655           (const_int 0)))]
8656   ""
8657   "")
8658
8659 (define_insn "*testqi_ext_0"
8660   [(set (reg FLAGS_REG)
8661         (compare
8662           (and:SI
8663             (zero_extract:SI
8664               (match_operand 0 "ext_register_operand" "Q")
8665               (const_int 8)
8666               (const_int 8))
8667             (match_operand 1 "const_int_operand" "n"))
8668           (const_int 0)))]
8669   "ix86_match_ccmode (insn, CCNOmode)"
8670   "test{b}\t{%1, %h0|%h0, %1}"
8671   [(set_attr "type" "test")
8672    (set_attr "mode" "QI")
8673    (set_attr "length_immediate" "1")
8674    (set_attr "pent_pair" "np")])
8675
8676 (define_insn "*testqi_ext_1"
8677   [(set (reg FLAGS_REG)
8678         (compare
8679           (and:SI
8680             (zero_extract:SI
8681               (match_operand 0 "ext_register_operand" "Q")
8682               (const_int 8)
8683               (const_int 8))
8684             (zero_extend:SI
8685               (match_operand:QI 1 "general_operand" "Qm")))
8686           (const_int 0)))]
8687   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8688    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8689   "test{b}\t{%1, %h0|%h0, %1}"
8690   [(set_attr "type" "test")
8691    (set_attr "mode" "QI")])
8692
8693 (define_insn "*testqi_ext_1_rex64"
8694   [(set (reg FLAGS_REG)
8695         (compare
8696           (and:SI
8697             (zero_extract:SI
8698               (match_operand 0 "ext_register_operand" "Q")
8699               (const_int 8)
8700               (const_int 8))
8701             (zero_extend:SI
8702               (match_operand:QI 1 "register_operand" "Q")))
8703           (const_int 0)))]
8704   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8705   "test{b}\t{%1, %h0|%h0, %1}"
8706   [(set_attr "type" "test")
8707    (set_attr "mode" "QI")])
8708
8709 (define_insn "*testqi_ext_2"
8710   [(set (reg FLAGS_REG)
8711         (compare
8712           (and:SI
8713             (zero_extract:SI
8714               (match_operand 0 "ext_register_operand" "Q")
8715               (const_int 8)
8716               (const_int 8))
8717             (zero_extract:SI
8718               (match_operand 1 "ext_register_operand" "Q")
8719               (const_int 8)
8720               (const_int 8)))
8721           (const_int 0)))]
8722   "ix86_match_ccmode (insn, CCNOmode)"
8723   "test{b}\t{%h1, %h0|%h0, %h1}"
8724   [(set_attr "type" "test")
8725    (set_attr "mode" "QI")])
8726
8727 ;; Combine likes to form bit extractions for some tests.  Humor it.
8728 (define_insn "*testqi_ext_3"
8729   [(set (reg FLAGS_REG)
8730         (compare (zero_extract:SI
8731                    (match_operand 0 "nonimmediate_operand" "rm")
8732                    (match_operand:SI 1 "const_int_operand" "")
8733                    (match_operand:SI 2 "const_int_operand" ""))
8734                  (const_int 0)))]
8735   "ix86_match_ccmode (insn, CCNOmode)
8736    && INTVAL (operands[1]) > 0
8737    && INTVAL (operands[2]) >= 0
8738    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8739    && (GET_MODE (operands[0]) == SImode
8740        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8741        || GET_MODE (operands[0]) == HImode
8742        || GET_MODE (operands[0]) == QImode)"
8743   "#")
8744
8745 (define_insn "*testqi_ext_3_rex64"
8746   [(set (reg FLAGS_REG)
8747         (compare (zero_extract:DI
8748                    (match_operand 0 "nonimmediate_operand" "rm")
8749                    (match_operand:DI 1 "const_int_operand" "")
8750                    (match_operand:DI 2 "const_int_operand" ""))
8751                  (const_int 0)))]
8752   "TARGET_64BIT
8753    && ix86_match_ccmode (insn, CCNOmode)
8754    && INTVAL (operands[1]) > 0
8755    && INTVAL (operands[2]) >= 0
8756    /* Ensure that resulting mask is zero or sign extended operand.  */
8757    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8758        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8759            && INTVAL (operands[1]) > 32))
8760    && (GET_MODE (operands[0]) == SImode
8761        || GET_MODE (operands[0]) == DImode
8762        || GET_MODE (operands[0]) == HImode
8763        || GET_MODE (operands[0]) == QImode)"
8764   "#")
8765
8766 (define_split
8767   [(set (match_operand 0 "flags_reg_operand" "")
8768         (match_operator 1 "compare_operator"
8769           [(zero_extract
8770              (match_operand 2 "nonimmediate_operand" "")
8771              (match_operand 3 "const_int_operand" "")
8772              (match_operand 4 "const_int_operand" ""))
8773            (const_int 0)]))]
8774   "ix86_match_ccmode (insn, CCNOmode)"
8775   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8776 {
8777   rtx val = operands[2];
8778   HOST_WIDE_INT len = INTVAL (operands[3]);
8779   HOST_WIDE_INT pos = INTVAL (operands[4]);
8780   HOST_WIDE_INT mask;
8781   enum machine_mode mode, submode;
8782
8783   mode = GET_MODE (val);
8784   if (MEM_P (val))
8785     {
8786       /* ??? Combine likes to put non-volatile mem extractions in QImode
8787          no matter the size of the test.  So find a mode that works.  */
8788       if (! MEM_VOLATILE_P (val))
8789         {
8790           mode = smallest_mode_for_size (pos + len, MODE_INT);
8791           val = adjust_address (val, mode, 0);
8792         }
8793     }
8794   else if (GET_CODE (val) == SUBREG
8795            && (submode = GET_MODE (SUBREG_REG (val)),
8796                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8797            && pos + len <= GET_MODE_BITSIZE (submode))
8798     {
8799       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8800       mode = submode;
8801       val = SUBREG_REG (val);
8802     }
8803   else if (mode == HImode && pos + len <= 8)
8804     {
8805       /* Small HImode tests can be converted to QImode.  */
8806       mode = QImode;
8807       val = gen_lowpart (QImode, val);
8808     }
8809
8810   if (len == HOST_BITS_PER_WIDE_INT)
8811     mask = -1;
8812   else
8813     mask = ((HOST_WIDE_INT)1 << len) - 1;
8814   mask <<= pos;
8815
8816   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8817 })
8818
8819 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8820 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8821 ;; this is relatively important trick.
8822 ;; Do the conversion only post-reload to avoid limiting of the register class
8823 ;; to QI regs.
8824 (define_split
8825   [(set (match_operand 0 "flags_reg_operand" "")
8826         (match_operator 1 "compare_operator"
8827           [(and (match_operand 2 "register_operand" "")
8828                 (match_operand 3 "const_int_operand" ""))
8829            (const_int 0)]))]
8830    "reload_completed
8831     && QI_REG_P (operands[2])
8832     && GET_MODE (operands[2]) != QImode
8833     && ((ix86_match_ccmode (insn, CCZmode)
8834          && !(INTVAL (operands[3]) & ~(255 << 8)))
8835         || (ix86_match_ccmode (insn, CCNOmode)
8836             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8837   [(set (match_dup 0)
8838         (match_op_dup 1
8839           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8840                    (match_dup 3))
8841            (const_int 0)]))]
8842   "operands[2] = gen_lowpart (SImode, operands[2]);
8843    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8844
8845 (define_split
8846   [(set (match_operand 0 "flags_reg_operand" "")
8847         (match_operator 1 "compare_operator"
8848           [(and (match_operand 2 "nonimmediate_operand" "")
8849                 (match_operand 3 "const_int_operand" ""))
8850            (const_int 0)]))]
8851    "reload_completed
8852     && GET_MODE (operands[2]) != QImode
8853     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8854     && ((ix86_match_ccmode (insn, CCZmode)
8855          && !(INTVAL (operands[3]) & ~255))
8856         || (ix86_match_ccmode (insn, CCNOmode)
8857             && !(INTVAL (operands[3]) & ~127)))"
8858   [(set (match_dup 0)
8859         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8860                          (const_int 0)]))]
8861   "operands[2] = gen_lowpart (QImode, operands[2]);
8862    operands[3] = gen_lowpart (QImode, operands[3]);")
8863
8864
8865 ;; %%% This used to optimize known byte-wide and operations to memory,
8866 ;; and sometimes to QImode registers.  If this is considered useful,
8867 ;; it should be done with splitters.
8868
8869 (define_expand "anddi3"
8870   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8871         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8872                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8873   "TARGET_64BIT"
8874   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8875
8876 (define_insn "*anddi_1_rex64"
8877   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8878         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8879                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8880    (clobber (reg:CC FLAGS_REG))]
8881   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8882 {
8883   switch (get_attr_type (insn))
8884     {
8885     case TYPE_IMOVX:
8886       {
8887         enum machine_mode mode;
8888
8889         gcc_assert (CONST_INT_P (operands[2]));
8890         if (INTVAL (operands[2]) == 0xff)
8891           mode = QImode;
8892         else
8893           {
8894             gcc_assert (INTVAL (operands[2]) == 0xffff);
8895             mode = HImode;
8896           }
8897
8898         operands[1] = gen_lowpart (mode, operands[1]);
8899         if (mode == QImode)
8900           return "movz{bq|x}\t{%1,%0|%0, %1}";
8901         else
8902           return "movz{wq|x}\t{%1,%0|%0, %1}";
8903       }
8904
8905     default:
8906       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8907       if (get_attr_mode (insn) == MODE_SI)
8908         return "and{l}\t{%k2, %k0|%k0, %k2}";
8909       else
8910         return "and{q}\t{%2, %0|%0, %2}";
8911     }
8912 }
8913   [(set_attr "type" "alu,alu,alu,imovx")
8914    (set_attr "length_immediate" "*,*,*,0")
8915    (set_attr "mode" "SI,DI,DI,DI")])
8916
8917 (define_insn "*anddi_2"
8918   [(set (reg FLAGS_REG)
8919         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8920                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8921                  (const_int 0)))
8922    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8923         (and:DI (match_dup 1) (match_dup 2)))]
8924   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8925    && ix86_binary_operator_ok (AND, DImode, operands)"
8926   "@
8927    and{l}\t{%k2, %k0|%k0, %k2}
8928    and{q}\t{%2, %0|%0, %2}
8929    and{q}\t{%2, %0|%0, %2}"
8930   [(set_attr "type" "alu")
8931    (set_attr "mode" "SI,DI,DI")])
8932
8933 (define_expand "andsi3"
8934   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8935         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8936                 (match_operand:SI 2 "general_operand" "")))]
8937   ""
8938   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8939
8940 (define_insn "*andsi_1"
8941   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8942         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8943                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8944    (clobber (reg:CC FLAGS_REG))]
8945   "ix86_binary_operator_ok (AND, SImode, operands)"
8946 {
8947   switch (get_attr_type (insn))
8948     {
8949     case TYPE_IMOVX:
8950       {
8951         enum machine_mode mode;
8952
8953         gcc_assert (CONST_INT_P (operands[2]));
8954         if (INTVAL (operands[2]) == 0xff)
8955           mode = QImode;
8956         else
8957           {
8958             gcc_assert (INTVAL (operands[2]) == 0xffff);
8959             mode = HImode;
8960           }
8961
8962         operands[1] = gen_lowpart (mode, operands[1]);
8963         if (mode == QImode)
8964           return "movz{bl|x}\t{%1,%0|%0, %1}";
8965         else
8966           return "movz{wl|x}\t{%1,%0|%0, %1}";
8967       }
8968
8969     default:
8970       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8971       return "and{l}\t{%2, %0|%0, %2}";
8972     }
8973 }
8974   [(set_attr "type" "alu,alu,imovx")
8975    (set_attr "length_immediate" "*,*,0")
8976    (set_attr "mode" "SI")])
8977
8978 (define_split
8979   [(set (match_operand 0 "register_operand" "")
8980         (and (match_dup 0)
8981              (const_int -65536)))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8984   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8985   "operands[1] = gen_lowpart (HImode, operands[0]);")
8986
8987 (define_split
8988   [(set (match_operand 0 "ext_register_operand" "")
8989         (and (match_dup 0)
8990              (const_int -256)))
8991    (clobber (reg:CC FLAGS_REG))]
8992   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8993   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8994   "operands[1] = gen_lowpart (QImode, operands[0]);")
8995
8996 (define_split
8997   [(set (match_operand 0 "ext_register_operand" "")
8998         (and (match_dup 0)
8999              (const_int -65281)))
9000    (clobber (reg:CC FLAGS_REG))]
9001   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9002   [(parallel [(set (zero_extract:SI (match_dup 0)
9003                                     (const_int 8)
9004                                     (const_int 8))
9005                    (xor:SI
9006                      (zero_extract:SI (match_dup 0)
9007                                       (const_int 8)
9008                                       (const_int 8))
9009                      (zero_extract:SI (match_dup 0)
9010                                       (const_int 8)
9011                                       (const_int 8))))
9012               (clobber (reg:CC FLAGS_REG))])]
9013   "operands[0] = gen_lowpart (SImode, operands[0]);")
9014
9015 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9016 (define_insn "*andsi_1_zext"
9017   [(set (match_operand:DI 0 "register_operand" "=r")
9018         (zero_extend:DI
9019           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9020                   (match_operand:SI 2 "general_operand" "g"))))
9021    (clobber (reg:CC FLAGS_REG))]
9022   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9023   "and{l}\t{%2, %k0|%k0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "SI")])
9026
9027 (define_insn "*andsi_2"
9028   [(set (reg FLAGS_REG)
9029         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9030                          (match_operand:SI 2 "general_operand" "g,ri"))
9031                  (const_int 0)))
9032    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9033         (and:SI (match_dup 1) (match_dup 2)))]
9034   "ix86_match_ccmode (insn, CCNOmode)
9035    && ix86_binary_operator_ok (AND, SImode, operands)"
9036   "and{l}\t{%2, %0|%0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "SI")])
9039
9040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041 (define_insn "*andsi_2_zext"
9042   [(set (reg FLAGS_REG)
9043         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044                          (match_operand:SI 2 "general_operand" "g"))
9045                  (const_int 0)))
9046    (set (match_operand:DI 0 "register_operand" "=r")
9047         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9048   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9049    && ix86_binary_operator_ok (AND, SImode, operands)"
9050   "and{l}\t{%2, %k0|%k0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "SI")])
9053
9054 (define_expand "andhi3"
9055   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9056         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9057                 (match_operand:HI 2 "general_operand" "")))]
9058   "TARGET_HIMODE_MATH"
9059   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9060
9061 (define_insn "*andhi_1"
9062   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9063         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9064                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9065    (clobber (reg:CC FLAGS_REG))]
9066   "ix86_binary_operator_ok (AND, HImode, operands)"
9067 {
9068   switch (get_attr_type (insn))
9069     {
9070     case TYPE_IMOVX:
9071       gcc_assert (CONST_INT_P (operands[2]));
9072       gcc_assert (INTVAL (operands[2]) == 0xff);
9073       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9074
9075     default:
9076       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9077
9078       return "and{w}\t{%2, %0|%0, %2}";
9079     }
9080 }
9081   [(set_attr "type" "alu,alu,imovx")
9082    (set_attr "length_immediate" "*,*,0")
9083    (set_attr "mode" "HI,HI,SI")])
9084
9085 (define_insn "*andhi_2"
9086   [(set (reg FLAGS_REG)
9087         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9088                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9089                  (const_int 0)))
9090    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9091         (and:HI (match_dup 1) (match_dup 2)))]
9092   "ix86_match_ccmode (insn, CCNOmode)
9093    && ix86_binary_operator_ok (AND, HImode, operands)"
9094   "and{w}\t{%2, %0|%0, %2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "mode" "HI")])
9097
9098 (define_expand "andqi3"
9099   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9100         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9101                 (match_operand:QI 2 "general_operand" "")))]
9102   "TARGET_QIMODE_MATH"
9103   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9104
9105 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9106 (define_insn "*andqi_1"
9107   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9108         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9109                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "ix86_binary_operator_ok (AND, QImode, operands)"
9112   "@
9113    and{b}\t{%2, %0|%0, %2}
9114    and{b}\t{%2, %0|%0, %2}
9115    and{l}\t{%k2, %k0|%k0, %k2}"
9116   [(set_attr "type" "alu")
9117    (set_attr "mode" "QI,QI,SI")])
9118
9119 (define_insn "*andqi_1_slp"
9120   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9121         (and:QI (match_dup 0)
9122                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9123    (clobber (reg:CC FLAGS_REG))]
9124   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9125    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9126   "and{b}\t{%1, %0|%0, %1}"
9127   [(set_attr "type" "alu1")
9128    (set_attr "mode" "QI")])
9129
9130 (define_insn "*andqi_2_maybe_si"
9131   [(set (reg FLAGS_REG)
9132         (compare (and:QI
9133                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9134                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9135                  (const_int 0)))
9136    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9137         (and:QI (match_dup 1) (match_dup 2)))]
9138   "ix86_binary_operator_ok (AND, QImode, operands)
9139    && ix86_match_ccmode (insn,
9140                          CONST_INT_P (operands[2])
9141                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9142 {
9143   if (which_alternative == 2)
9144     {
9145       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9146         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9147       return "and{l}\t{%2, %k0|%k0, %2}";
9148     }
9149   return "and{b}\t{%2, %0|%0, %2}";
9150 }
9151   [(set_attr "type" "alu")
9152    (set_attr "mode" "QI,QI,SI")])
9153
9154 (define_insn "*andqi_2"
9155   [(set (reg FLAGS_REG)
9156         (compare (and:QI
9157                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9158                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9159                  (const_int 0)))
9160    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9161         (and:QI (match_dup 1) (match_dup 2)))]
9162   "ix86_match_ccmode (insn, CCNOmode)
9163    && ix86_binary_operator_ok (AND, QImode, operands)"
9164   "and{b}\t{%2, %0|%0, %2}"
9165   [(set_attr "type" "alu")
9166    (set_attr "mode" "QI")])
9167
9168 (define_insn "*andqi_2_slp"
9169   [(set (reg FLAGS_REG)
9170         (compare (and:QI
9171                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9172                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9173                  (const_int 0)))
9174    (set (strict_low_part (match_dup 0))
9175         (and:QI (match_dup 0) (match_dup 1)))]
9176   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9177    && ix86_match_ccmode (insn, CCNOmode)
9178    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9179   "and{b}\t{%1, %0|%0, %1}"
9180   [(set_attr "type" "alu1")
9181    (set_attr "mode" "QI")])
9182
9183 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9184 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9185 ;; for a QImode operand, which of course failed.
9186
9187 (define_insn "andqi_ext_0"
9188   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9189                          (const_int 8)
9190                          (const_int 8))
9191         (and:SI
9192           (zero_extract:SI
9193             (match_operand 1 "ext_register_operand" "0")
9194             (const_int 8)
9195             (const_int 8))
9196           (match_operand 2 "const_int_operand" "n")))
9197    (clobber (reg:CC FLAGS_REG))]
9198   ""
9199   "and{b}\t{%2, %h0|%h0, %2}"
9200   [(set_attr "type" "alu")
9201    (set_attr "length_immediate" "1")
9202    (set_attr "mode" "QI")])
9203
9204 ;; Generated by peephole translating test to and.  This shows up
9205 ;; often in fp comparisons.
9206
9207 (define_insn "*andqi_ext_0_cc"
9208   [(set (reg FLAGS_REG)
9209         (compare
9210           (and:SI
9211             (zero_extract:SI
9212               (match_operand 1 "ext_register_operand" "0")
9213               (const_int 8)
9214               (const_int 8))
9215             (match_operand 2 "const_int_operand" "n"))
9216           (const_int 0)))
9217    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218                          (const_int 8)
9219                          (const_int 8))
9220         (and:SI
9221           (zero_extract:SI
9222             (match_dup 1)
9223             (const_int 8)
9224             (const_int 8))
9225           (match_dup 2)))]
9226   "ix86_match_ccmode (insn, CCNOmode)"
9227   "and{b}\t{%2, %h0|%h0, %2}"
9228   [(set_attr "type" "alu")
9229    (set_attr "length_immediate" "1")
9230    (set_attr "mode" "QI")])
9231
9232 (define_insn "*andqi_ext_1"
9233   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9234                          (const_int 8)
9235                          (const_int 8))
9236         (and:SI
9237           (zero_extract:SI
9238             (match_operand 1 "ext_register_operand" "0")
9239             (const_int 8)
9240             (const_int 8))
9241           (zero_extend:SI
9242             (match_operand:QI 2 "general_operand" "Qm"))))
9243    (clobber (reg:CC FLAGS_REG))]
9244   "!TARGET_64BIT"
9245   "and{b}\t{%2, %h0|%h0, %2}"
9246   [(set_attr "type" "alu")
9247    (set_attr "length_immediate" "0")
9248    (set_attr "mode" "QI")])
9249
9250 (define_insn "*andqi_ext_1_rex64"
9251   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9252                          (const_int 8)
9253                          (const_int 8))
9254         (and:SI
9255           (zero_extract:SI
9256             (match_operand 1 "ext_register_operand" "0")
9257             (const_int 8)
9258             (const_int 8))
9259           (zero_extend:SI
9260             (match_operand 2 "ext_register_operand" "Q"))))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "TARGET_64BIT"
9263   "and{b}\t{%2, %h0|%h0, %2}"
9264   [(set_attr "type" "alu")
9265    (set_attr "length_immediate" "0")
9266    (set_attr "mode" "QI")])
9267
9268 (define_insn "*andqi_ext_2"
9269   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9270                          (const_int 8)
9271                          (const_int 8))
9272         (and:SI
9273           (zero_extract:SI
9274             (match_operand 1 "ext_register_operand" "%0")
9275             (const_int 8)
9276             (const_int 8))
9277           (zero_extract:SI
9278             (match_operand 2 "ext_register_operand" "Q")
9279             (const_int 8)
9280             (const_int 8))))
9281    (clobber (reg:CC FLAGS_REG))]
9282   ""
9283   "and{b}\t{%h2, %h0|%h0, %h2}"
9284   [(set_attr "type" "alu")
9285    (set_attr "length_immediate" "0")
9286    (set_attr "mode" "QI")])
9287
9288 ;; Convert wide AND instructions with immediate operand to shorter QImode
9289 ;; equivalents when possible.
9290 ;; Don't do the splitting with memory operands, since it introduces risk
9291 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9292 ;; for size, but that can (should?) be handled by generic code instead.
9293 (define_split
9294   [(set (match_operand 0 "register_operand" "")
9295         (and (match_operand 1 "register_operand" "")
9296              (match_operand 2 "const_int_operand" "")))
9297    (clobber (reg:CC FLAGS_REG))]
9298    "reload_completed
9299     && QI_REG_P (operands[0])
9300     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9301     && !(~INTVAL (operands[2]) & ~(255 << 8))
9302     && GET_MODE (operands[0]) != QImode"
9303   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9304                    (and:SI (zero_extract:SI (match_dup 1)
9305                                             (const_int 8) (const_int 8))
9306                            (match_dup 2)))
9307               (clobber (reg:CC FLAGS_REG))])]
9308   "operands[0] = gen_lowpart (SImode, operands[0]);
9309    operands[1] = gen_lowpart (SImode, operands[1]);
9310    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9311
9312 ;; Since AND can be encoded with sign extended immediate, this is only
9313 ;; profitable when 7th bit is not set.
9314 (define_split
9315   [(set (match_operand 0 "register_operand" "")
9316         (and (match_operand 1 "general_operand" "")
9317              (match_operand 2 "const_int_operand" "")))
9318    (clobber (reg:CC FLAGS_REG))]
9319    "reload_completed
9320     && ANY_QI_REG_P (operands[0])
9321     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9322     && !(~INTVAL (operands[2]) & ~255)
9323     && !(INTVAL (operands[2]) & 128)
9324     && GET_MODE (operands[0]) != QImode"
9325   [(parallel [(set (strict_low_part (match_dup 0))
9326                    (and:QI (match_dup 1)
9327                            (match_dup 2)))
9328               (clobber (reg:CC FLAGS_REG))])]
9329   "operands[0] = gen_lowpart (QImode, operands[0]);
9330    operands[1] = gen_lowpart (QImode, operands[1]);
9331    operands[2] = gen_lowpart (QImode, operands[2]);")
9332 \f
9333 ;; Logical inclusive OR instructions
9334
9335 ;; %%% This used to optimize known byte-wide and operations to memory.
9336 ;; If this is considered useful, it should be done with splitters.
9337
9338 (define_expand "iordi3"
9339   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9340         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9341                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9342   "TARGET_64BIT"
9343   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9344
9345 (define_insn "*iordi_1_rex64"
9346   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9347         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9348                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9349    (clobber (reg:CC FLAGS_REG))]
9350   "TARGET_64BIT
9351    && ix86_binary_operator_ok (IOR, DImode, operands)"
9352   "or{q}\t{%2, %0|%0, %2}"
9353   [(set_attr "type" "alu")
9354    (set_attr "mode" "DI")])
9355
9356 (define_insn "*iordi_2_rex64"
9357   [(set (reg FLAGS_REG)
9358         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9359                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9360                  (const_int 0)))
9361    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9362         (ior:DI (match_dup 1) (match_dup 2)))]
9363   "TARGET_64BIT
9364    && ix86_match_ccmode (insn, CCNOmode)
9365    && ix86_binary_operator_ok (IOR, DImode, operands)"
9366   "or{q}\t{%2, %0|%0, %2}"
9367   [(set_attr "type" "alu")
9368    (set_attr "mode" "DI")])
9369
9370 (define_insn "*iordi_3_rex64"
9371   [(set (reg FLAGS_REG)
9372         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9373                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9374                  (const_int 0)))
9375    (clobber (match_scratch:DI 0 "=r"))]
9376   "TARGET_64BIT
9377    && ix86_match_ccmode (insn, CCNOmode)
9378    && ix86_binary_operator_ok (IOR, DImode, operands)"
9379   "or{q}\t{%2, %0|%0, %2}"
9380   [(set_attr "type" "alu")
9381    (set_attr "mode" "DI")])
9382
9383
9384 (define_expand "iorsi3"
9385   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9387                 (match_operand:SI 2 "general_operand" "")))]
9388   ""
9389   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9390
9391 (define_insn "*iorsi_1"
9392   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9393         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9394                 (match_operand:SI 2 "general_operand" "ri,g")))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "ix86_binary_operator_ok (IOR, SImode, operands)"
9397   "or{l}\t{%2, %0|%0, %2}"
9398   [(set_attr "type" "alu")
9399    (set_attr "mode" "SI")])
9400
9401 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9402 (define_insn "*iorsi_1_zext"
9403   [(set (match_operand:DI 0 "register_operand" "=r")
9404         (zero_extend:DI
9405           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9406                   (match_operand:SI 2 "general_operand" "g"))))
9407    (clobber (reg:CC FLAGS_REG))]
9408   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9409   "or{l}\t{%2, %k0|%k0, %2}"
9410   [(set_attr "type" "alu")
9411    (set_attr "mode" "SI")])
9412
9413 (define_insn "*iorsi_1_zext_imm"
9414   [(set (match_operand:DI 0 "register_operand" "=r")
9415         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9416                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9417    (clobber (reg:CC FLAGS_REG))]
9418   "TARGET_64BIT"
9419   "or{l}\t{%2, %k0|%k0, %2}"
9420   [(set_attr "type" "alu")
9421    (set_attr "mode" "SI")])
9422
9423 (define_insn "*iorsi_2"
9424   [(set (reg FLAGS_REG)
9425         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9426                          (match_operand:SI 2 "general_operand" "g,ri"))
9427                  (const_int 0)))
9428    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9429         (ior:SI (match_dup 1) (match_dup 2)))]
9430   "ix86_match_ccmode (insn, CCNOmode)
9431    && ix86_binary_operator_ok (IOR, SImode, operands)"
9432   "or{l}\t{%2, %0|%0, %2}"
9433   [(set_attr "type" "alu")
9434    (set_attr "mode" "SI")])
9435
9436 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9437 ;; ??? Special case for immediate operand is missing - it is tricky.
9438 (define_insn "*iorsi_2_zext"
9439   [(set (reg FLAGS_REG)
9440         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9441                          (match_operand:SI 2 "general_operand" "g"))
9442                  (const_int 0)))
9443    (set (match_operand:DI 0 "register_operand" "=r")
9444         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9445   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9446    && ix86_binary_operator_ok (IOR, SImode, operands)"
9447   "or{l}\t{%2, %k0|%k0, %2}"
9448   [(set_attr "type" "alu")
9449    (set_attr "mode" "SI")])
9450
9451 (define_insn "*iorsi_2_zext_imm"
9452   [(set (reg FLAGS_REG)
9453         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9454                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9455                  (const_int 0)))
9456    (set (match_operand:DI 0 "register_operand" "=r")
9457         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9458   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9459    && ix86_binary_operator_ok (IOR, SImode, operands)"
9460   "or{l}\t{%2, %k0|%k0, %2}"
9461   [(set_attr "type" "alu")
9462    (set_attr "mode" "SI")])
9463
9464 (define_insn "*iorsi_3"
9465   [(set (reg FLAGS_REG)
9466         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9467                          (match_operand:SI 2 "general_operand" "g"))
9468                  (const_int 0)))
9469    (clobber (match_scratch:SI 0 "=r"))]
9470   "ix86_match_ccmode (insn, CCNOmode)
9471    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9472   "or{l}\t{%2, %0|%0, %2}"
9473   [(set_attr "type" "alu")
9474    (set_attr "mode" "SI")])
9475
9476 (define_expand "iorhi3"
9477   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9478         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9479                 (match_operand:HI 2 "general_operand" "")))]
9480   "TARGET_HIMODE_MATH"
9481   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9482
9483 (define_insn "*iorhi_1"
9484   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9485         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9486                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9487    (clobber (reg:CC FLAGS_REG))]
9488   "ix86_binary_operator_ok (IOR, HImode, operands)"
9489   "or{w}\t{%2, %0|%0, %2}"
9490   [(set_attr "type" "alu")
9491    (set_attr "mode" "HI")])
9492
9493 (define_insn "*iorhi_2"
9494   [(set (reg FLAGS_REG)
9495         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9496                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9497                  (const_int 0)))
9498    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9499         (ior:HI (match_dup 1) (match_dup 2)))]
9500   "ix86_match_ccmode (insn, CCNOmode)
9501    && ix86_binary_operator_ok (IOR, HImode, operands)"
9502   "or{w}\t{%2, %0|%0, %2}"
9503   [(set_attr "type" "alu")
9504    (set_attr "mode" "HI")])
9505
9506 (define_insn "*iorhi_3"
9507   [(set (reg FLAGS_REG)
9508         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9509                          (match_operand:HI 2 "general_operand" "rmn"))
9510                  (const_int 0)))
9511    (clobber (match_scratch:HI 0 "=r"))]
9512   "ix86_match_ccmode (insn, CCNOmode)
9513    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9514   "or{w}\t{%2, %0|%0, %2}"
9515   [(set_attr "type" "alu")
9516    (set_attr "mode" "HI")])
9517
9518 (define_expand "iorqi3"
9519   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9520         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9521                 (match_operand:QI 2 "general_operand" "")))]
9522   "TARGET_QIMODE_MATH"
9523   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9524
9525 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9526 (define_insn "*iorqi_1"
9527   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9528         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9529                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9530    (clobber (reg:CC FLAGS_REG))]
9531   "ix86_binary_operator_ok (IOR, QImode, operands)"
9532   "@
9533    or{b}\t{%2, %0|%0, %2}
9534    or{b}\t{%2, %0|%0, %2}
9535    or{l}\t{%k2, %k0|%k0, %k2}"
9536   [(set_attr "type" "alu")
9537    (set_attr "mode" "QI,QI,SI")])
9538
9539 (define_insn "*iorqi_1_slp"
9540   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9541         (ior:QI (match_dup 0)
9542                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9545    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9546   "or{b}\t{%1, %0|%0, %1}"
9547   [(set_attr "type" "alu1")
9548    (set_attr "mode" "QI")])
9549
9550 (define_insn "*iorqi_2"
9551   [(set (reg FLAGS_REG)
9552         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9553                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9554                  (const_int 0)))
9555    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9556         (ior:QI (match_dup 1) (match_dup 2)))]
9557   "ix86_match_ccmode (insn, CCNOmode)
9558    && ix86_binary_operator_ok (IOR, QImode, operands)"
9559   "or{b}\t{%2, %0|%0, %2}"
9560   [(set_attr "type" "alu")
9561    (set_attr "mode" "QI")])
9562
9563 (define_insn "*iorqi_2_slp"
9564   [(set (reg FLAGS_REG)
9565         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9566                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9567                  (const_int 0)))
9568    (set (strict_low_part (match_dup 0))
9569         (ior:QI (match_dup 0) (match_dup 1)))]
9570   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9571    && ix86_match_ccmode (insn, CCNOmode)
9572    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9573   "or{b}\t{%1, %0|%0, %1}"
9574   [(set_attr "type" "alu1")
9575    (set_attr "mode" "QI")])
9576
9577 (define_insn "*iorqi_3"
9578   [(set (reg FLAGS_REG)
9579         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9580                          (match_operand:QI 2 "general_operand" "qmn"))
9581                  (const_int 0)))
9582    (clobber (match_scratch:QI 0 "=q"))]
9583   "ix86_match_ccmode (insn, CCNOmode)
9584    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9585   "or{b}\t{%2, %0|%0, %2}"
9586   [(set_attr "type" "alu")
9587    (set_attr "mode" "QI")])
9588
9589 (define_insn "iorqi_ext_0"
9590   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9591                          (const_int 8)
9592                          (const_int 8))
9593         (ior:SI
9594           (zero_extract:SI
9595             (match_operand 1 "ext_register_operand" "0")
9596             (const_int 8)
9597             (const_int 8))
9598           (match_operand 2 "const_int_operand" "n")))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9601   "or{b}\t{%2, %h0|%h0, %2}"
9602   [(set_attr "type" "alu")
9603    (set_attr "length_immediate" "1")
9604    (set_attr "mode" "QI")])
9605
9606 (define_insn "*iorqi_ext_1"
9607   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9608                          (const_int 8)
9609                          (const_int 8))
9610         (ior:SI
9611           (zero_extract:SI
9612             (match_operand 1 "ext_register_operand" "0")
9613             (const_int 8)
9614             (const_int 8))
9615           (zero_extend:SI
9616             (match_operand:QI 2 "general_operand" "Qm"))))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "!TARGET_64BIT
9619    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9620   "or{b}\t{%2, %h0|%h0, %2}"
9621   [(set_attr "type" "alu")
9622    (set_attr "length_immediate" "0")
9623    (set_attr "mode" "QI")])
9624
9625 (define_insn "*iorqi_ext_1_rex64"
9626   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9627                          (const_int 8)
9628                          (const_int 8))
9629         (ior:SI
9630           (zero_extract:SI
9631             (match_operand 1 "ext_register_operand" "0")
9632             (const_int 8)
9633             (const_int 8))
9634           (zero_extend:SI
9635             (match_operand 2 "ext_register_operand" "Q"))))
9636    (clobber (reg:CC FLAGS_REG))]
9637   "TARGET_64BIT
9638    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9639   "or{b}\t{%2, %h0|%h0, %2}"
9640   [(set_attr "type" "alu")
9641    (set_attr "length_immediate" "0")
9642    (set_attr "mode" "QI")])
9643
9644 (define_insn "*iorqi_ext_2"
9645   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9646                          (const_int 8)
9647                          (const_int 8))
9648         (ior:SI
9649           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9650                            (const_int 8)
9651                            (const_int 8))
9652           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9653                            (const_int 8)
9654                            (const_int 8))))
9655    (clobber (reg:CC FLAGS_REG))]
9656   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9657   "ior{b}\t{%h2, %h0|%h0, %h2}"
9658   [(set_attr "type" "alu")
9659    (set_attr "length_immediate" "0")
9660    (set_attr "mode" "QI")])
9661
9662 (define_split
9663   [(set (match_operand 0 "register_operand" "")
9664         (ior (match_operand 1 "register_operand" "")
9665              (match_operand 2 "const_int_operand" "")))
9666    (clobber (reg:CC FLAGS_REG))]
9667    "reload_completed
9668     && QI_REG_P (operands[0])
9669     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9670     && !(INTVAL (operands[2]) & ~(255 << 8))
9671     && GET_MODE (operands[0]) != QImode"
9672   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9673                    (ior:SI (zero_extract:SI (match_dup 1)
9674                                             (const_int 8) (const_int 8))
9675                            (match_dup 2)))
9676               (clobber (reg:CC FLAGS_REG))])]
9677   "operands[0] = gen_lowpart (SImode, operands[0]);
9678    operands[1] = gen_lowpart (SImode, operands[1]);
9679    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9680
9681 ;; Since OR can be encoded with sign extended immediate, this is only
9682 ;; profitable when 7th bit is set.
9683 (define_split
9684   [(set (match_operand 0 "register_operand" "")
9685         (ior (match_operand 1 "general_operand" "")
9686              (match_operand 2 "const_int_operand" "")))
9687    (clobber (reg:CC FLAGS_REG))]
9688    "reload_completed
9689     && ANY_QI_REG_P (operands[0])
9690     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9691     && !(INTVAL (operands[2]) & ~255)
9692     && (INTVAL (operands[2]) & 128)
9693     && GET_MODE (operands[0]) != QImode"
9694   [(parallel [(set (strict_low_part (match_dup 0))
9695                    (ior:QI (match_dup 1)
9696                            (match_dup 2)))
9697               (clobber (reg:CC FLAGS_REG))])]
9698   "operands[0] = gen_lowpart (QImode, operands[0]);
9699    operands[1] = gen_lowpart (QImode, operands[1]);
9700    operands[2] = gen_lowpart (QImode, operands[2]);")
9701 \f
9702 ;; Logical XOR instructions
9703
9704 ;; %%% This used to optimize known byte-wide and operations to memory.
9705 ;; If this is considered useful, it should be done with splitters.
9706
9707 (define_expand "xordi3"
9708   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9709         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9710                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9711   "TARGET_64BIT"
9712   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9713
9714 (define_insn "*xordi_1_rex64"
9715   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9716         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9717                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9718    (clobber (reg:CC FLAGS_REG))]
9719   "TARGET_64BIT
9720    && ix86_binary_operator_ok (XOR, DImode, operands)"
9721   "xor{q}\t{%2, %0|%0, %2}"
9722   [(set_attr "type" "alu")
9723    (set_attr "mode" "DI")])
9724
9725 (define_insn "*xordi_2_rex64"
9726   [(set (reg FLAGS_REG)
9727         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9728                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9729                  (const_int 0)))
9730    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9731         (xor:DI (match_dup 1) (match_dup 2)))]
9732   "TARGET_64BIT
9733    && ix86_match_ccmode (insn, CCNOmode)
9734    && ix86_binary_operator_ok (XOR, DImode, operands)"
9735   "xor{q}\t{%2, %0|%0, %2}"
9736   [(set_attr "type" "alu")
9737    (set_attr "mode" "DI")])
9738
9739 (define_insn "*xordi_3_rex64"
9740   [(set (reg FLAGS_REG)
9741         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9742                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9743                  (const_int 0)))
9744    (clobber (match_scratch:DI 0 "=r"))]
9745   "TARGET_64BIT
9746    && ix86_match_ccmode (insn, CCNOmode)
9747    && ix86_binary_operator_ok (XOR, DImode, operands)"
9748   "xor{q}\t{%2, %0|%0, %2}"
9749   [(set_attr "type" "alu")
9750    (set_attr "mode" "DI")])
9751
9752 (define_expand "xorsi3"
9753   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9754         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9755                 (match_operand:SI 2 "general_operand" "")))]
9756   ""
9757   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9758
9759 (define_insn "*xorsi_1"
9760   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9761         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9762                 (match_operand:SI 2 "general_operand" "ri,rm")))
9763    (clobber (reg:CC FLAGS_REG))]
9764   "ix86_binary_operator_ok (XOR, SImode, operands)"
9765   "xor{l}\t{%2, %0|%0, %2}"
9766   [(set_attr "type" "alu")
9767    (set_attr "mode" "SI")])
9768
9769 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9770 ;; Add speccase for immediates
9771 (define_insn "*xorsi_1_zext"
9772   [(set (match_operand:DI 0 "register_operand" "=r")
9773         (zero_extend:DI
9774           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9775                   (match_operand:SI 2 "general_operand" "g"))))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9778   "xor{l}\t{%2, %k0|%k0, %2}"
9779   [(set_attr "type" "alu")
9780    (set_attr "mode" "SI")])
9781
9782 (define_insn "*xorsi_1_zext_imm"
9783   [(set (match_operand:DI 0 "register_operand" "=r")
9784         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9785                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9788   "xor{l}\t{%2, %k0|%k0, %2}"
9789   [(set_attr "type" "alu")
9790    (set_attr "mode" "SI")])
9791
9792 (define_insn "*xorsi_2"
9793   [(set (reg FLAGS_REG)
9794         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9795                          (match_operand:SI 2 "general_operand" "g,ri"))
9796                  (const_int 0)))
9797    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9798         (xor:SI (match_dup 1) (match_dup 2)))]
9799   "ix86_match_ccmode (insn, CCNOmode)
9800    && ix86_binary_operator_ok (XOR, SImode, operands)"
9801   "xor{l}\t{%2, %0|%0, %2}"
9802   [(set_attr "type" "alu")
9803    (set_attr "mode" "SI")])
9804
9805 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9806 ;; ??? Special case for immediate operand is missing - it is tricky.
9807 (define_insn "*xorsi_2_zext"
9808   [(set (reg FLAGS_REG)
9809         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9810                          (match_operand:SI 2 "general_operand" "g"))
9811                  (const_int 0)))
9812    (set (match_operand:DI 0 "register_operand" "=r")
9813         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9814   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9815    && ix86_binary_operator_ok (XOR, SImode, operands)"
9816   "xor{l}\t{%2, %k0|%k0, %2}"
9817   [(set_attr "type" "alu")
9818    (set_attr "mode" "SI")])
9819
9820 (define_insn "*xorsi_2_zext_imm"
9821   [(set (reg FLAGS_REG)
9822         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9823                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9824                  (const_int 0)))
9825    (set (match_operand:DI 0 "register_operand" "=r")
9826         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9827   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9828    && ix86_binary_operator_ok (XOR, SImode, operands)"
9829   "xor{l}\t{%2, %k0|%k0, %2}"
9830   [(set_attr "type" "alu")
9831    (set_attr "mode" "SI")])
9832
9833 (define_insn "*xorsi_3"
9834   [(set (reg FLAGS_REG)
9835         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9836                          (match_operand:SI 2 "general_operand" "g"))
9837                  (const_int 0)))
9838    (clobber (match_scratch:SI 0 "=r"))]
9839   "ix86_match_ccmode (insn, CCNOmode)
9840    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9841   "xor{l}\t{%2, %0|%0, %2}"
9842   [(set_attr "type" "alu")
9843    (set_attr "mode" "SI")])
9844
9845 (define_expand "xorhi3"
9846   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9847         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9848                 (match_operand:HI 2 "general_operand" "")))]
9849   "TARGET_HIMODE_MATH"
9850   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9851
9852 (define_insn "*xorhi_1"
9853   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9854         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9855                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9856    (clobber (reg:CC FLAGS_REG))]
9857   "ix86_binary_operator_ok (XOR, HImode, operands)"
9858   "xor{w}\t{%2, %0|%0, %2}"
9859   [(set_attr "type" "alu")
9860    (set_attr "mode" "HI")])
9861
9862 (define_insn "*xorhi_2"
9863   [(set (reg FLAGS_REG)
9864         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9865                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9866                  (const_int 0)))
9867    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9868         (xor:HI (match_dup 1) (match_dup 2)))]
9869   "ix86_match_ccmode (insn, CCNOmode)
9870    && ix86_binary_operator_ok (XOR, HImode, operands)"
9871   "xor{w}\t{%2, %0|%0, %2}"
9872   [(set_attr "type" "alu")
9873    (set_attr "mode" "HI")])
9874
9875 (define_insn "*xorhi_3"
9876   [(set (reg FLAGS_REG)
9877         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9878                          (match_operand:HI 2 "general_operand" "rmn"))
9879                  (const_int 0)))
9880    (clobber (match_scratch:HI 0 "=r"))]
9881   "ix86_match_ccmode (insn, CCNOmode)
9882    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9883   "xor{w}\t{%2, %0|%0, %2}"
9884   [(set_attr "type" "alu")
9885    (set_attr "mode" "HI")])
9886
9887 (define_expand "xorqi3"
9888   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9889         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9890                 (match_operand:QI 2 "general_operand" "")))]
9891   "TARGET_QIMODE_MATH"
9892   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9893
9894 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9895 (define_insn "*xorqi_1"
9896   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9897         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9898                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9899    (clobber (reg:CC FLAGS_REG))]
9900   "ix86_binary_operator_ok (XOR, QImode, operands)"
9901   "@
9902    xor{b}\t{%2, %0|%0, %2}
9903    xor{b}\t{%2, %0|%0, %2}
9904    xor{l}\t{%k2, %k0|%k0, %k2}"
9905   [(set_attr "type" "alu")
9906    (set_attr "mode" "QI,QI,SI")])
9907
9908 (define_insn "*xorqi_1_slp"
9909   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9910         (xor:QI (match_dup 0)
9911                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9912    (clobber (reg:CC FLAGS_REG))]
9913   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9914    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9915   "xor{b}\t{%1, %0|%0, %1}"
9916   [(set_attr "type" "alu1")
9917    (set_attr "mode" "QI")])
9918
9919 (define_insn "xorqi_ext_0"
9920   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9921                          (const_int 8)
9922                          (const_int 8))
9923         (xor:SI
9924           (zero_extract:SI
9925             (match_operand 1 "ext_register_operand" "0")
9926             (const_int 8)
9927             (const_int 8))
9928           (match_operand 2 "const_int_operand" "n")))
9929    (clobber (reg:CC FLAGS_REG))]
9930   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9931   "xor{b}\t{%2, %h0|%h0, %2}"
9932   [(set_attr "type" "alu")
9933    (set_attr "length_immediate" "1")
9934    (set_attr "mode" "QI")])
9935
9936 (define_insn "*xorqi_ext_1"
9937   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9938                          (const_int 8)
9939                          (const_int 8))
9940         (xor:SI
9941           (zero_extract:SI
9942             (match_operand 1 "ext_register_operand" "0")
9943             (const_int 8)
9944             (const_int 8))
9945           (zero_extend:SI
9946             (match_operand:QI 2 "general_operand" "Qm"))))
9947    (clobber (reg:CC FLAGS_REG))]
9948   "!TARGET_64BIT
9949    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9950   "xor{b}\t{%2, %h0|%h0, %2}"
9951   [(set_attr "type" "alu")
9952    (set_attr "length_immediate" "0")
9953    (set_attr "mode" "QI")])
9954
9955 (define_insn "*xorqi_ext_1_rex64"
9956   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9957                          (const_int 8)
9958                          (const_int 8))
9959         (xor:SI
9960           (zero_extract:SI
9961             (match_operand 1 "ext_register_operand" "0")
9962             (const_int 8)
9963             (const_int 8))
9964           (zero_extend:SI
9965             (match_operand 2 "ext_register_operand" "Q"))))
9966    (clobber (reg:CC FLAGS_REG))]
9967   "TARGET_64BIT
9968    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9969   "xor{b}\t{%2, %h0|%h0, %2}"
9970   [(set_attr "type" "alu")
9971    (set_attr "length_immediate" "0")
9972    (set_attr "mode" "QI")])
9973
9974 (define_insn "*xorqi_ext_2"
9975   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9976                          (const_int 8)
9977                          (const_int 8))
9978         (xor:SI
9979           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9980                            (const_int 8)
9981                            (const_int 8))
9982           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9983                            (const_int 8)
9984                            (const_int 8))))
9985    (clobber (reg:CC FLAGS_REG))]
9986   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9987   "xor{b}\t{%h2, %h0|%h0, %h2}"
9988   [(set_attr "type" "alu")
9989    (set_attr "length_immediate" "0")
9990    (set_attr "mode" "QI")])
9991
9992 (define_insn "*xorqi_cc_1"
9993   [(set (reg FLAGS_REG)
9994         (compare
9995           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9996                   (match_operand:QI 2 "general_operand" "qmn,qn"))
9997           (const_int 0)))
9998    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9999         (xor:QI (match_dup 1) (match_dup 2)))]
10000   "ix86_match_ccmode (insn, CCNOmode)
10001    && ix86_binary_operator_ok (XOR, QImode, operands)"
10002   "xor{b}\t{%2, %0|%0, %2}"
10003   [(set_attr "type" "alu")
10004    (set_attr "mode" "QI")])
10005
10006 (define_insn "*xorqi_2_slp"
10007   [(set (reg FLAGS_REG)
10008         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10009                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10010                  (const_int 0)))
10011    (set (strict_low_part (match_dup 0))
10012         (xor:QI (match_dup 0) (match_dup 1)))]
10013   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10014    && ix86_match_ccmode (insn, CCNOmode)
10015    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10016   "xor{b}\t{%1, %0|%0, %1}"
10017   [(set_attr "type" "alu1")
10018    (set_attr "mode" "QI")])
10019
10020 (define_insn "*xorqi_cc_2"
10021   [(set (reg FLAGS_REG)
10022         (compare
10023           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10024                   (match_operand:QI 2 "general_operand" "qmn"))
10025           (const_int 0)))
10026    (clobber (match_scratch:QI 0 "=q"))]
10027   "ix86_match_ccmode (insn, CCNOmode)
10028    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10029   "xor{b}\t{%2, %0|%0, %2}"
10030   [(set_attr "type" "alu")
10031    (set_attr "mode" "QI")])
10032
10033 (define_insn "*xorqi_cc_ext_1"
10034   [(set (reg FLAGS_REG)
10035         (compare
10036           (xor:SI
10037             (zero_extract:SI
10038               (match_operand 1 "ext_register_operand" "0")
10039               (const_int 8)
10040               (const_int 8))
10041             (match_operand:QI 2 "general_operand" "qmn"))
10042           (const_int 0)))
10043    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10044                          (const_int 8)
10045                          (const_int 8))
10046         (xor:SI
10047           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10048           (match_dup 2)))]
10049   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10050   "xor{b}\t{%2, %h0|%h0, %2}"
10051   [(set_attr "type" "alu")
10052    (set_attr "mode" "QI")])
10053
10054 (define_insn "*xorqi_cc_ext_1_rex64"
10055   [(set (reg FLAGS_REG)
10056         (compare
10057           (xor:SI
10058             (zero_extract:SI
10059               (match_operand 1 "ext_register_operand" "0")
10060               (const_int 8)
10061               (const_int 8))
10062             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10063           (const_int 0)))
10064    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10065                          (const_int 8)
10066                          (const_int 8))
10067         (xor:SI
10068           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10069           (match_dup 2)))]
10070   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10071   "xor{b}\t{%2, %h0|%h0, %2}"
10072   [(set_attr "type" "alu")
10073    (set_attr "mode" "QI")])
10074
10075 (define_expand "xorqi_cc_ext_1"
10076   [(parallel [
10077      (set (reg:CCNO FLAGS_REG)
10078           (compare:CCNO
10079             (xor:SI
10080               (zero_extract:SI
10081                 (match_operand 1 "ext_register_operand" "")
10082                 (const_int 8)
10083                 (const_int 8))
10084               (match_operand:QI 2 "general_operand" ""))
10085             (const_int 0)))
10086      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10087                            (const_int 8)
10088                            (const_int 8))
10089           (xor:SI
10090             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10091             (match_dup 2)))])]
10092   ""
10093   "")
10094
10095 (define_split
10096   [(set (match_operand 0 "register_operand" "")
10097         (xor (match_operand 1 "register_operand" "")
10098              (match_operand 2 "const_int_operand" "")))
10099    (clobber (reg:CC FLAGS_REG))]
10100    "reload_completed
10101     && QI_REG_P (operands[0])
10102     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10103     && !(INTVAL (operands[2]) & ~(255 << 8))
10104     && GET_MODE (operands[0]) != QImode"
10105   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10106                    (xor:SI (zero_extract:SI (match_dup 1)
10107                                             (const_int 8) (const_int 8))
10108                            (match_dup 2)))
10109               (clobber (reg:CC FLAGS_REG))])]
10110   "operands[0] = gen_lowpart (SImode, operands[0]);
10111    operands[1] = gen_lowpart (SImode, operands[1]);
10112    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10113
10114 ;; Since XOR can be encoded with sign extended immediate, this is only
10115 ;; profitable when 7th bit is set.
10116 (define_split
10117   [(set (match_operand 0 "register_operand" "")
10118         (xor (match_operand 1 "general_operand" "")
10119              (match_operand 2 "const_int_operand" "")))
10120    (clobber (reg:CC FLAGS_REG))]
10121    "reload_completed
10122     && ANY_QI_REG_P (operands[0])
10123     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10124     && !(INTVAL (operands[2]) & ~255)
10125     && (INTVAL (operands[2]) & 128)
10126     && GET_MODE (operands[0]) != QImode"
10127   [(parallel [(set (strict_low_part (match_dup 0))
10128                    (xor:QI (match_dup 1)
10129                            (match_dup 2)))
10130               (clobber (reg:CC FLAGS_REG))])]
10131   "operands[0] = gen_lowpart (QImode, operands[0]);
10132    operands[1] = gen_lowpart (QImode, operands[1]);
10133    operands[2] = gen_lowpart (QImode, operands[2]);")
10134 \f
10135 ;; Negation instructions
10136
10137 (define_expand "negti2"
10138   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10139         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10140   "TARGET_64BIT"
10141   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10142
10143 (define_insn "*negti2_1"
10144   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10145         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10146    (clobber (reg:CC FLAGS_REG))]
10147   "TARGET_64BIT
10148    && ix86_unary_operator_ok (NEG, TImode, operands)"
10149   "#")
10150
10151 (define_split
10152   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10153         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10154    (clobber (reg:CC FLAGS_REG))]
10155   "TARGET_64BIT && reload_completed"
10156   [(parallel
10157     [(set (reg:CCZ FLAGS_REG)
10158           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10159      (set (match_dup 0) (neg:DI (match_dup 1)))])
10160    (parallel
10161     [(set (match_dup 2)
10162           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10163                             (match_dup 3))
10164                    (const_int 0)))
10165      (clobber (reg:CC FLAGS_REG))])
10166    (parallel
10167     [(set (match_dup 2)
10168           (neg:DI (match_dup 2)))
10169      (clobber (reg:CC FLAGS_REG))])]
10170   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10171
10172 (define_expand "negdi2"
10173   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10174         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10175   ""
10176   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10177
10178 (define_insn "*negdi2_1"
10179   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10180         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10181    (clobber (reg:CC FLAGS_REG))]
10182   "!TARGET_64BIT
10183    && ix86_unary_operator_ok (NEG, DImode, operands)"
10184   "#")
10185
10186 (define_split
10187   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10188         (neg:DI (match_operand:DI 1 "general_operand" "")))
10189    (clobber (reg:CC FLAGS_REG))]
10190   "!TARGET_64BIT && reload_completed"
10191   [(parallel
10192     [(set (reg:CCZ FLAGS_REG)
10193           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10194      (set (match_dup 0) (neg:SI (match_dup 1)))])
10195    (parallel
10196     [(set (match_dup 2)
10197           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10198                             (match_dup 3))
10199                    (const_int 0)))
10200      (clobber (reg:CC FLAGS_REG))])
10201    (parallel
10202     [(set (match_dup 2)
10203           (neg:SI (match_dup 2)))
10204      (clobber (reg:CC FLAGS_REG))])]
10205   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10206
10207 (define_insn "*negdi2_1_rex64"
10208   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10209         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10210    (clobber (reg:CC FLAGS_REG))]
10211   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10212   "neg{q}\t%0"
10213   [(set_attr "type" "negnot")
10214    (set_attr "mode" "DI")])
10215
10216 ;; The problem with neg is that it does not perform (compare x 0),
10217 ;; it really performs (compare 0 x), which leaves us with the zero
10218 ;; flag being the only useful item.
10219
10220 (define_insn "*negdi2_cmpz_rex64"
10221   [(set (reg:CCZ FLAGS_REG)
10222         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10223                      (const_int 0)))
10224    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10225         (neg:DI (match_dup 1)))]
10226   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10227   "neg{q}\t%0"
10228   [(set_attr "type" "negnot")
10229    (set_attr "mode" "DI")])
10230
10231
10232 (define_expand "negsi2"
10233   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10234         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10235   ""
10236   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10237
10238 (define_insn "*negsi2_1"
10239   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10240         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10241    (clobber (reg:CC FLAGS_REG))]
10242   "ix86_unary_operator_ok (NEG, SImode, operands)"
10243   "neg{l}\t%0"
10244   [(set_attr "type" "negnot")
10245    (set_attr "mode" "SI")])
10246
10247 ;; Combine is quite creative about this pattern.
10248 (define_insn "*negsi2_1_zext"
10249   [(set (match_operand:DI 0 "register_operand" "=r")
10250         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10251                                         (const_int 32)))
10252                      (const_int 32)))
10253    (clobber (reg:CC FLAGS_REG))]
10254   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10255   "neg{l}\t%k0"
10256   [(set_attr "type" "negnot")
10257    (set_attr "mode" "SI")])
10258
10259 ;; The problem with neg is that it does not perform (compare x 0),
10260 ;; it really performs (compare 0 x), which leaves us with the zero
10261 ;; flag being the only useful item.
10262
10263 (define_insn "*negsi2_cmpz"
10264   [(set (reg:CCZ FLAGS_REG)
10265         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10266                      (const_int 0)))
10267    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10268         (neg:SI (match_dup 1)))]
10269   "ix86_unary_operator_ok (NEG, SImode, operands)"
10270   "neg{l}\t%0"
10271   [(set_attr "type" "negnot")
10272    (set_attr "mode" "SI")])
10273
10274 (define_insn "*negsi2_cmpz_zext"
10275   [(set (reg:CCZ FLAGS_REG)
10276         (compare:CCZ (lshiftrt:DI
10277                        (neg:DI (ashift:DI
10278                                  (match_operand:DI 1 "register_operand" "0")
10279                                  (const_int 32)))
10280                        (const_int 32))
10281                      (const_int 0)))
10282    (set (match_operand:DI 0 "register_operand" "=r")
10283         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10284                                         (const_int 32)))
10285                      (const_int 32)))]
10286   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10287   "neg{l}\t%k0"
10288   [(set_attr "type" "negnot")
10289    (set_attr "mode" "SI")])
10290
10291 (define_expand "neghi2"
10292   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10293         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10294   "TARGET_HIMODE_MATH"
10295   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10296
10297 (define_insn "*neghi2_1"
10298   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10299         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "ix86_unary_operator_ok (NEG, HImode, operands)"
10302   "neg{w}\t%0"
10303   [(set_attr "type" "negnot")
10304    (set_attr "mode" "HI")])
10305
10306 (define_insn "*neghi2_cmpz"
10307   [(set (reg:CCZ FLAGS_REG)
10308         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10309                      (const_int 0)))
10310    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10311         (neg:HI (match_dup 1)))]
10312   "ix86_unary_operator_ok (NEG, HImode, operands)"
10313   "neg{w}\t%0"
10314   [(set_attr "type" "negnot")
10315    (set_attr "mode" "HI")])
10316
10317 (define_expand "negqi2"
10318   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10319         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10320   "TARGET_QIMODE_MATH"
10321   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10322
10323 (define_insn "*negqi2_1"
10324   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10325         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10326    (clobber (reg:CC FLAGS_REG))]
10327   "ix86_unary_operator_ok (NEG, QImode, operands)"
10328   "neg{b}\t%0"
10329   [(set_attr "type" "negnot")
10330    (set_attr "mode" "QI")])
10331
10332 (define_insn "*negqi2_cmpz"
10333   [(set (reg:CCZ FLAGS_REG)
10334         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10335                      (const_int 0)))
10336    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10337         (neg:QI (match_dup 1)))]
10338   "ix86_unary_operator_ok (NEG, QImode, operands)"
10339   "neg{b}\t%0"
10340   [(set_attr "type" "negnot")
10341    (set_attr "mode" "QI")])
10342
10343 ;; Changing of sign for FP values is doable using integer unit too.
10344
10345 (define_expand "<code><mode>2"
10346   [(set (match_operand:X87MODEF 0 "register_operand" "")
10347         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10348   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10349   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10350
10351 (define_insn "*absneg<mode>2_mixed"
10352   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10353         (match_operator:MODEF 3 "absneg_operator"
10354           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10355    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10356    (clobber (reg:CC FLAGS_REG))]
10357   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10358   "#")
10359
10360 (define_insn "*absneg<mode>2_sse"
10361   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10362         (match_operator:MODEF 3 "absneg_operator"
10363           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10364    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10365    (clobber (reg:CC FLAGS_REG))]
10366   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10367   "#")
10368
10369 (define_insn "*absneg<mode>2_i387"
10370   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10371         (match_operator:X87MODEF 3 "absneg_operator"
10372           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10373    (use (match_operand 2 "" ""))
10374    (clobber (reg:CC FLAGS_REG))]
10375   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10376   "#")
10377
10378 (define_expand "<code>tf2"
10379   [(set (match_operand:TF 0 "register_operand" "")
10380         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10381   "TARGET_SSE2"
10382   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10383
10384 (define_insn "*absnegtf2_sse"
10385   [(set (match_operand:TF 0 "register_operand" "=x,x")
10386         (match_operator:TF 3 "absneg_operator"
10387           [(match_operand:TF 1 "register_operand" "0,x")]))
10388    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "TARGET_SSE2"
10391   "#")
10392
10393 ;; Splitters for fp abs and neg.
10394
10395 (define_split
10396   [(set (match_operand 0 "fp_register_operand" "")
10397         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10398    (use (match_operand 2 "" ""))
10399    (clobber (reg:CC FLAGS_REG))]
10400   "reload_completed"
10401   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10402
10403 (define_split
10404   [(set (match_operand 0 "register_operand" "")
10405         (match_operator 3 "absneg_operator"
10406           [(match_operand 1 "register_operand" "")]))
10407    (use (match_operand 2 "nonimmediate_operand" ""))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "reload_completed && SSE_REG_P (operands[0])"
10410   [(set (match_dup 0) (match_dup 3))]
10411 {
10412   enum machine_mode mode = GET_MODE (operands[0]);
10413   enum machine_mode vmode = GET_MODE (operands[2]);
10414   rtx tmp;
10415
10416   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10417   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10418   if (operands_match_p (operands[0], operands[2]))
10419     {
10420       tmp = operands[1];
10421       operands[1] = operands[2];
10422       operands[2] = tmp;
10423     }
10424   if (GET_CODE (operands[3]) == ABS)
10425     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10426   else
10427     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10428   operands[3] = tmp;
10429 })
10430
10431 (define_split
10432   [(set (match_operand:SF 0 "register_operand" "")
10433         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10434    (use (match_operand:V4SF 2 "" ""))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "reload_completed"
10437   [(parallel [(set (match_dup 0) (match_dup 1))
10438               (clobber (reg:CC FLAGS_REG))])]
10439 {
10440   rtx tmp;
10441   operands[0] = gen_lowpart (SImode, operands[0]);
10442   if (GET_CODE (operands[1]) == ABS)
10443     {
10444       tmp = gen_int_mode (0x7fffffff, SImode);
10445       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10446     }
10447   else
10448     {
10449       tmp = gen_int_mode (0x80000000, SImode);
10450       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10451     }
10452   operands[1] = tmp;
10453 })
10454
10455 (define_split
10456   [(set (match_operand:DF 0 "register_operand" "")
10457         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10458    (use (match_operand 2 "" ""))
10459    (clobber (reg:CC FLAGS_REG))]
10460   "reload_completed"
10461   [(parallel [(set (match_dup 0) (match_dup 1))
10462               (clobber (reg:CC FLAGS_REG))])]
10463 {
10464   rtx tmp;
10465   if (TARGET_64BIT)
10466     {
10467       tmp = gen_lowpart (DImode, operands[0]);
10468       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10469       operands[0] = tmp;
10470
10471       if (GET_CODE (operands[1]) == ABS)
10472         tmp = const0_rtx;
10473       else
10474         tmp = gen_rtx_NOT (DImode, tmp);
10475     }
10476   else
10477     {
10478       operands[0] = gen_highpart (SImode, operands[0]);
10479       if (GET_CODE (operands[1]) == ABS)
10480         {
10481           tmp = gen_int_mode (0x7fffffff, SImode);
10482           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10483         }
10484       else
10485         {
10486           tmp = gen_int_mode (0x80000000, SImode);
10487           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10488         }
10489     }
10490   operands[1] = tmp;
10491 })
10492
10493 (define_split
10494   [(set (match_operand:XF 0 "register_operand" "")
10495         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10496    (use (match_operand 2 "" ""))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "reload_completed"
10499   [(parallel [(set (match_dup 0) (match_dup 1))
10500               (clobber (reg:CC FLAGS_REG))])]
10501 {
10502   rtx tmp;
10503   operands[0] = gen_rtx_REG (SImode,
10504                              true_regnum (operands[0])
10505                              + (TARGET_64BIT ? 1 : 2));
10506   if (GET_CODE (operands[1]) == ABS)
10507     {
10508       tmp = GEN_INT (0x7fff);
10509       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10510     }
10511   else
10512     {
10513       tmp = GEN_INT (0x8000);
10514       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10515     }
10516   operands[1] = tmp;
10517 })
10518
10519 ;; Conditionalize these after reload. If they match before reload, we
10520 ;; lose the clobber and ability to use integer instructions.
10521
10522 (define_insn "*<code><mode>2_1"
10523   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10524         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10525   "TARGET_80387
10526    && (reload_completed
10527        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10528   "f<absnegprefix>"
10529   [(set_attr "type" "fsgn")
10530    (set_attr "mode" "<MODE>")])
10531
10532 (define_insn "*<code>extendsfdf2"
10533   [(set (match_operand:DF 0 "register_operand" "=f")
10534         (absneg:DF (float_extend:DF
10535                      (match_operand:SF 1 "register_operand" "0"))))]
10536   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10537   "f<absnegprefix>"
10538   [(set_attr "type" "fsgn")
10539    (set_attr "mode" "DF")])
10540
10541 (define_insn "*<code>extendsfxf2"
10542   [(set (match_operand:XF 0 "register_operand" "=f")
10543         (absneg:XF (float_extend:XF
10544                      (match_operand:SF 1 "register_operand" "0"))))]
10545   "TARGET_80387"
10546   "f<absnegprefix>"
10547   [(set_attr "type" "fsgn")
10548    (set_attr "mode" "XF")])
10549
10550 (define_insn "*<code>extenddfxf2"
10551   [(set (match_operand:XF 0 "register_operand" "=f")
10552         (absneg:XF (float_extend:XF
10553                       (match_operand:DF 1 "register_operand" "0"))))]
10554   "TARGET_80387"
10555   "f<absnegprefix>"
10556   [(set_attr "type" "fsgn")
10557    (set_attr "mode" "XF")])
10558
10559 ;; Copysign instructions
10560
10561 (define_mode_iterator CSGNMODE [SF DF TF])
10562 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10563
10564 (define_expand "copysign<mode>3"
10565   [(match_operand:CSGNMODE 0 "register_operand" "")
10566    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10567    (match_operand:CSGNMODE 2 "register_operand" "")]
10568   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10569    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10570 {
10571   ix86_expand_copysign (operands);
10572   DONE;
10573 })
10574
10575 (define_insn_and_split "copysign<mode>3_const"
10576   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10577         (unspec:CSGNMODE
10578           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10579            (match_operand:CSGNMODE 2 "register_operand" "0")
10580            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10581           UNSPEC_COPYSIGN))]
10582   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10583    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10584   "#"
10585   "&& reload_completed"
10586   [(const_int 0)]
10587 {
10588   ix86_split_copysign_const (operands);
10589   DONE;
10590 })
10591
10592 (define_insn "copysign<mode>3_var"
10593   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10594         (unspec:CSGNMODE
10595           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10596            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10597            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10598            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10599           UNSPEC_COPYSIGN))
10600    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10601   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10602    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10603   "#")
10604
10605 (define_split
10606   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10607         (unspec:CSGNMODE
10608           [(match_operand:CSGNMODE 2 "register_operand" "")
10609            (match_operand:CSGNMODE 3 "register_operand" "")
10610            (match_operand:<CSGNVMODE> 4 "" "")
10611            (match_operand:<CSGNVMODE> 5 "" "")]
10612           UNSPEC_COPYSIGN))
10613    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10614   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10615     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10616    && reload_completed"
10617   [(const_int 0)]
10618 {
10619   ix86_split_copysign_var (operands);
10620   DONE;
10621 })
10622 \f
10623 ;; One complement instructions
10624
10625 (define_expand "one_cmpldi2"
10626   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10627         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10628   "TARGET_64BIT"
10629   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10630
10631 (define_insn "*one_cmpldi2_1_rex64"
10632   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10633         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10634   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10635   "not{q}\t%0"
10636   [(set_attr "type" "negnot")
10637    (set_attr "mode" "DI")])
10638
10639 (define_insn "*one_cmpldi2_2_rex64"
10640   [(set (reg FLAGS_REG)
10641         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10642                  (const_int 0)))
10643    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10644         (not:DI (match_dup 1)))]
10645   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10646    && ix86_unary_operator_ok (NOT, DImode, operands)"
10647   "#"
10648   [(set_attr "type" "alu1")
10649    (set_attr "mode" "DI")])
10650
10651 (define_split
10652   [(set (match_operand 0 "flags_reg_operand" "")
10653         (match_operator 2 "compare_operator"
10654           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10655            (const_int 0)]))
10656    (set (match_operand:DI 1 "nonimmediate_operand" "")
10657         (not:DI (match_dup 3)))]
10658   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10659   [(parallel [(set (match_dup 0)
10660                    (match_op_dup 2
10661                      [(xor:DI (match_dup 3) (const_int -1))
10662                       (const_int 0)]))
10663               (set (match_dup 1)
10664                    (xor:DI (match_dup 3) (const_int -1)))])]
10665   "")
10666
10667 (define_expand "one_cmplsi2"
10668   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10669         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10670   ""
10671   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10672
10673 (define_insn "*one_cmplsi2_1"
10674   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10675         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10676   "ix86_unary_operator_ok (NOT, SImode, operands)"
10677   "not{l}\t%0"
10678   [(set_attr "type" "negnot")
10679    (set_attr "mode" "SI")])
10680
10681 ;; ??? Currently never generated - xor is used instead.
10682 (define_insn "*one_cmplsi2_1_zext"
10683   [(set (match_operand:DI 0 "register_operand" "=r")
10684         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10685   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10686   "not{l}\t%k0"
10687   [(set_attr "type" "negnot")
10688    (set_attr "mode" "SI")])
10689
10690 (define_insn "*one_cmplsi2_2"
10691   [(set (reg FLAGS_REG)
10692         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10693                  (const_int 0)))
10694    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10695         (not:SI (match_dup 1)))]
10696   "ix86_match_ccmode (insn, CCNOmode)
10697    && ix86_unary_operator_ok (NOT, SImode, operands)"
10698   "#"
10699   [(set_attr "type" "alu1")
10700    (set_attr "mode" "SI")])
10701
10702 (define_split
10703   [(set (match_operand 0 "flags_reg_operand" "")
10704         (match_operator 2 "compare_operator"
10705           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10706            (const_int 0)]))
10707    (set (match_operand:SI 1 "nonimmediate_operand" "")
10708         (not:SI (match_dup 3)))]
10709   "ix86_match_ccmode (insn, CCNOmode)"
10710   [(parallel [(set (match_dup 0)
10711                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10712                                     (const_int 0)]))
10713               (set (match_dup 1)
10714                    (xor:SI (match_dup 3) (const_int -1)))])]
10715   "")
10716
10717 ;; ??? Currently never generated - xor is used instead.
10718 (define_insn "*one_cmplsi2_2_zext"
10719   [(set (reg FLAGS_REG)
10720         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10721                  (const_int 0)))
10722    (set (match_operand:DI 0 "register_operand" "=r")
10723         (zero_extend:DI (not:SI (match_dup 1))))]
10724   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10725    && ix86_unary_operator_ok (NOT, SImode, operands)"
10726   "#"
10727   [(set_attr "type" "alu1")
10728    (set_attr "mode" "SI")])
10729
10730 (define_split
10731   [(set (match_operand 0 "flags_reg_operand" "")
10732         (match_operator 2 "compare_operator"
10733           [(not:SI (match_operand:SI 3 "register_operand" ""))
10734            (const_int 0)]))
10735    (set (match_operand:DI 1 "register_operand" "")
10736         (zero_extend:DI (not:SI (match_dup 3))))]
10737   "ix86_match_ccmode (insn, CCNOmode)"
10738   [(parallel [(set (match_dup 0)
10739                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10740                                     (const_int 0)]))
10741               (set (match_dup 1)
10742                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10743   "")
10744
10745 (define_expand "one_cmplhi2"
10746   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10747         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10748   "TARGET_HIMODE_MATH"
10749   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10750
10751 (define_insn "*one_cmplhi2_1"
10752   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10753         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10754   "ix86_unary_operator_ok (NOT, HImode, operands)"
10755   "not{w}\t%0"
10756   [(set_attr "type" "negnot")
10757    (set_attr "mode" "HI")])
10758
10759 (define_insn "*one_cmplhi2_2"
10760   [(set (reg FLAGS_REG)
10761         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10762                  (const_int 0)))
10763    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10764         (not:HI (match_dup 1)))]
10765   "ix86_match_ccmode (insn, CCNOmode)
10766    && ix86_unary_operator_ok (NEG, HImode, operands)"
10767   "#"
10768   [(set_attr "type" "alu1")
10769    (set_attr "mode" "HI")])
10770
10771 (define_split
10772   [(set (match_operand 0 "flags_reg_operand" "")
10773         (match_operator 2 "compare_operator"
10774           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10775            (const_int 0)]))
10776    (set (match_operand:HI 1 "nonimmediate_operand" "")
10777         (not:HI (match_dup 3)))]
10778   "ix86_match_ccmode (insn, CCNOmode)"
10779   [(parallel [(set (match_dup 0)
10780                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10781                                     (const_int 0)]))
10782               (set (match_dup 1)
10783                    (xor:HI (match_dup 3) (const_int -1)))])]
10784   "")
10785
10786 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10787 (define_expand "one_cmplqi2"
10788   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10789         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10790   "TARGET_QIMODE_MATH"
10791   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10792
10793 (define_insn "*one_cmplqi2_1"
10794   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10795         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10796   "ix86_unary_operator_ok (NOT, QImode, operands)"
10797   "@
10798    not{b}\t%0
10799    not{l}\t%k0"
10800   [(set_attr "type" "negnot")
10801    (set_attr "mode" "QI,SI")])
10802
10803 (define_insn "*one_cmplqi2_2"
10804   [(set (reg FLAGS_REG)
10805         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10806                  (const_int 0)))
10807    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10808         (not:QI (match_dup 1)))]
10809   "ix86_match_ccmode (insn, CCNOmode)
10810    && ix86_unary_operator_ok (NOT, QImode, operands)"
10811   "#"
10812   [(set_attr "type" "alu1")
10813    (set_attr "mode" "QI")])
10814
10815 (define_split
10816   [(set (match_operand 0 "flags_reg_operand" "")
10817         (match_operator 2 "compare_operator"
10818           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10819            (const_int 0)]))
10820    (set (match_operand:QI 1 "nonimmediate_operand" "")
10821         (not:QI (match_dup 3)))]
10822   "ix86_match_ccmode (insn, CCNOmode)"
10823   [(parallel [(set (match_dup 0)
10824                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10825                                     (const_int 0)]))
10826               (set (match_dup 1)
10827                    (xor:QI (match_dup 3) (const_int -1)))])]
10828   "")
10829 \f
10830 ;; Arithmetic shift instructions
10831
10832 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10833 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10834 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10835 ;; from the assembler input.
10836 ;;
10837 ;; This instruction shifts the target reg/mem as usual, but instead of
10838 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10839 ;; is a left shift double, bits are taken from the high order bits of
10840 ;; reg, else if the insn is a shift right double, bits are taken from the
10841 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10842 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10843 ;;
10844 ;; Since sh[lr]d does not change the `reg' operand, that is done
10845 ;; separately, making all shifts emit pairs of shift double and normal
10846 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10847 ;; support a 63 bit shift, each shift where the count is in a reg expands
10848 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10849 ;;
10850 ;; If the shift count is a constant, we need never emit more than one
10851 ;; shift pair, instead using moves and sign extension for counts greater
10852 ;; than 31.
10853
10854 (define_expand "ashlti3"
10855   [(set (match_operand:TI 0 "register_operand" "")
10856         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10857                    (match_operand:QI 2 "nonmemory_operand" "")))]
10858   "TARGET_64BIT"
10859   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10860
10861 ;; This pattern must be defined before *ashlti3_1 to prevent
10862 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10863
10864 (define_insn "sse2_ashlti3"
10865   [(set (match_operand:TI 0 "register_operand" "=x")
10866         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10867                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10868   "TARGET_SSE2"
10869 {
10870   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10871   return "pslldq\t{%2, %0|%0, %2}";
10872 }
10873   [(set_attr "type" "sseishft")
10874    (set_attr "prefix_data16" "1")
10875    (set_attr "mode" "TI")])
10876
10877 (define_insn "*ashlti3_1"
10878   [(set (match_operand:TI 0 "register_operand" "=&r,r")
10879         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10880                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10881    (clobber (reg:CC FLAGS_REG))]
10882   "TARGET_64BIT"
10883   "#"
10884   [(set_attr "type" "multi")])
10885
10886 (define_peephole2
10887   [(match_scratch:DI 3 "r")
10888    (parallel [(set (match_operand:TI 0 "register_operand" "")
10889                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10890                               (match_operand:QI 2 "nonmemory_operand" "")))
10891               (clobber (reg:CC FLAGS_REG))])
10892    (match_dup 3)]
10893   "TARGET_64BIT"
10894   [(const_int 0)]
10895   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10896
10897 (define_split
10898   [(set (match_operand:TI 0 "register_operand" "")
10899         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10900                    (match_operand:QI 2 "nonmemory_operand" "")))
10901    (clobber (reg:CC FLAGS_REG))]
10902   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10903                     ? epilogue_completed : reload_completed)"
10904   [(const_int 0)]
10905   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10906
10907 (define_insn "x86_64_shld"
10908   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10909         (ior:DI (ashift:DI (match_dup 0)
10910                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10911                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10912                   (minus:QI (const_int 64) (match_dup 2)))))
10913    (clobber (reg:CC FLAGS_REG))]
10914   "TARGET_64BIT"
10915   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10916   [(set_attr "type" "ishift")
10917    (set_attr "prefix_0f" "1")
10918    (set_attr "mode" "DI")
10919    (set_attr "athlon_decode" "vector")
10920    (set_attr "amdfam10_decode" "vector")])
10921
10922 (define_expand "x86_64_shift_adj_1"
10923   [(set (reg:CCZ FLAGS_REG)
10924         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10925                              (const_int 64))
10926                      (const_int 0)))
10927    (set (match_operand:DI 0 "register_operand" "")
10928         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10929                          (match_operand:DI 1 "register_operand" "")
10930                          (match_dup 0)))
10931    (set (match_dup 1)
10932         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10933                          (match_operand:DI 3 "register_operand" "r")
10934                          (match_dup 1)))]
10935   "TARGET_64BIT"
10936   "")
10937
10938 (define_expand "x86_64_shift_adj_2"
10939   [(use (match_operand:DI 0 "register_operand" ""))
10940    (use (match_operand:DI 1 "register_operand" ""))
10941    (use (match_operand:QI 2 "register_operand" ""))]
10942   "TARGET_64BIT"
10943 {
10944   rtx label = gen_label_rtx ();
10945   rtx tmp;
10946
10947   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10948
10949   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10950   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10951   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10952                               gen_rtx_LABEL_REF (VOIDmode, label),
10953                               pc_rtx);
10954   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10955   JUMP_LABEL (tmp) = label;
10956
10957   emit_move_insn (operands[0], operands[1]);
10958   ix86_expand_clear (operands[1]);
10959
10960   emit_label (label);
10961   LABEL_NUSES (label) = 1;
10962
10963   DONE;
10964 })
10965
10966 (define_expand "ashldi3"
10967   [(set (match_operand:DI 0 "shiftdi_operand" "")
10968         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10969                    (match_operand:QI 2 "nonmemory_operand" "")))]
10970   ""
10971   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10972
10973 (define_insn "*ashldi3_1_rex64"
10974   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10975         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10976                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10977    (clobber (reg:CC FLAGS_REG))]
10978   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10979 {
10980   switch (get_attr_type (insn))
10981     {
10982     case TYPE_ALU:
10983       gcc_assert (operands[2] == const1_rtx);
10984       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10985       return "add{q}\t%0, %0";
10986
10987     case TYPE_LEA:
10988       gcc_assert (CONST_INT_P (operands[2]));
10989       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10990       operands[1] = gen_rtx_MULT (DImode, operands[1],
10991                                   GEN_INT (1 << INTVAL (operands[2])));
10992       return "lea{q}\t{%a1, %0|%0, %a1}";
10993
10994     default:
10995       if (REG_P (operands[2]))
10996         return "sal{q}\t{%b2, %0|%0, %b2}";
10997       else if (operands[2] == const1_rtx
10998                && (TARGET_SHIFT1 || optimize_size))
10999         return "sal{q}\t%0";
11000       else
11001         return "sal{q}\t{%2, %0|%0, %2}";
11002     }
11003 }
11004   [(set (attr "type")
11005      (cond [(eq_attr "alternative" "1")
11006               (const_string "lea")
11007             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11008                           (const_int 0))
11009                       (match_operand 0 "register_operand" ""))
11010                  (match_operand 2 "const1_operand" ""))
11011               (const_string "alu")
11012            ]
11013            (const_string "ishift")))
11014    (set_attr "mode" "DI")])
11015
11016 ;; Convert lea to the lea pattern to avoid flags dependency.
11017 (define_split
11018   [(set (match_operand:DI 0 "register_operand" "")
11019         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11020                    (match_operand:QI 2 "immediate_operand" "")))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "TARGET_64BIT && reload_completed
11023    && true_regnum (operands[0]) != true_regnum (operands[1])"
11024   [(set (match_dup 0)
11025         (mult:DI (match_dup 1)
11026                  (match_dup 2)))]
11027   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11028
11029 ;; This pattern can't accept a variable shift count, since shifts by
11030 ;; zero don't affect the flags.  We assume that shifts by constant
11031 ;; zero are optimized away.
11032 (define_insn "*ashldi3_cmp_rex64"
11033   [(set (reg FLAGS_REG)
11034         (compare
11035           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11036                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11037           (const_int 0)))
11038    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11039         (ashift:DI (match_dup 1) (match_dup 2)))]
11040   "TARGET_64BIT
11041    && (optimize_size
11042        || !TARGET_PARTIAL_FLAG_REG_STALL
11043        || (operands[2] == const1_rtx
11044            && (TARGET_SHIFT1
11045                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11046    && ix86_match_ccmode (insn, CCGOCmode)
11047    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11048 {
11049   switch (get_attr_type (insn))
11050     {
11051     case TYPE_ALU:
11052       gcc_assert (operands[2] == const1_rtx);
11053       return "add{q}\t%0, %0";
11054
11055     default:
11056       if (REG_P (operands[2]))
11057         return "sal{q}\t{%b2, %0|%0, %b2}";
11058       else if (operands[2] == const1_rtx
11059                && (TARGET_SHIFT1 || optimize_size))
11060         return "sal{q}\t%0";
11061       else
11062         return "sal{q}\t{%2, %0|%0, %2}";
11063     }
11064 }
11065   [(set (attr "type")
11066      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11067                           (const_int 0))
11068                       (match_operand 0 "register_operand" ""))
11069                  (match_operand 2 "const1_operand" ""))
11070               (const_string "alu")
11071            ]
11072            (const_string "ishift")))
11073    (set_attr "mode" "DI")])
11074
11075 (define_insn "*ashldi3_cconly_rex64"
11076   [(set (reg FLAGS_REG)
11077         (compare
11078           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11079                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11080           (const_int 0)))
11081    (clobber (match_scratch:DI 0 "=r"))]
11082   "TARGET_64BIT
11083    && (optimize_size
11084        || !TARGET_PARTIAL_FLAG_REG_STALL
11085        || (operands[2] == const1_rtx
11086            && (TARGET_SHIFT1
11087                || TARGET_DOUBLE_WITH_ADD)))
11088    && ix86_match_ccmode (insn, CCGOCmode)
11089    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11090 {
11091   switch (get_attr_type (insn))
11092     {
11093     case TYPE_ALU:
11094       gcc_assert (operands[2] == const1_rtx);
11095       return "add{q}\t%0, %0";
11096
11097     default:
11098       if (REG_P (operands[2]))
11099         return "sal{q}\t{%b2, %0|%0, %b2}";
11100       else if (operands[2] == const1_rtx
11101                && (TARGET_SHIFT1 || optimize_size))
11102         return "sal{q}\t%0";
11103       else
11104         return "sal{q}\t{%2, %0|%0, %2}";
11105     }
11106 }
11107   [(set (attr "type")
11108      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11109                           (const_int 0))
11110                       (match_operand 0 "register_operand" ""))
11111                  (match_operand 2 "const1_operand" ""))
11112               (const_string "alu")
11113            ]
11114            (const_string "ishift")))
11115    (set_attr "mode" "DI")])
11116
11117 (define_insn "*ashldi3_1"
11118   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11119         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11120                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11121    (clobber (reg:CC FLAGS_REG))]
11122   "!TARGET_64BIT"
11123   "#"
11124   [(set_attr "type" "multi")])
11125
11126 ;; By default we don't ask for a scratch register, because when DImode
11127 ;; values are manipulated, registers are already at a premium.  But if
11128 ;; we have one handy, we won't turn it away.
11129 (define_peephole2
11130   [(match_scratch:SI 3 "r")
11131    (parallel [(set (match_operand:DI 0 "register_operand" "")
11132                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11133                               (match_operand:QI 2 "nonmemory_operand" "")))
11134               (clobber (reg:CC FLAGS_REG))])
11135    (match_dup 3)]
11136   "!TARGET_64BIT && TARGET_CMOVE"
11137   [(const_int 0)]
11138   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11139
11140 (define_split
11141   [(set (match_operand:DI 0 "register_operand" "")
11142         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11143                    (match_operand:QI 2 "nonmemory_operand" "")))
11144    (clobber (reg:CC FLAGS_REG))]
11145   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11146                      ? epilogue_completed : reload_completed)"
11147   [(const_int 0)]
11148   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11149
11150 (define_insn "x86_shld"
11151   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11152         (ior:SI (ashift:SI (match_dup 0)
11153                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11154                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11155                   (minus:QI (const_int 32) (match_dup 2)))))
11156    (clobber (reg:CC FLAGS_REG))]
11157   ""
11158   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11159   [(set_attr "type" "ishift")
11160    (set_attr "prefix_0f" "1")
11161    (set_attr "mode" "SI")
11162    (set_attr "pent_pair" "np")
11163    (set_attr "athlon_decode" "vector")
11164    (set_attr "amdfam10_decode" "vector")])
11165
11166 (define_expand "x86_shift_adj_1"
11167   [(set (reg:CCZ FLAGS_REG)
11168         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11169                              (const_int 32))
11170                      (const_int 0)))
11171    (set (match_operand:SI 0 "register_operand" "")
11172         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11173                          (match_operand:SI 1 "register_operand" "")
11174                          (match_dup 0)))
11175    (set (match_dup 1)
11176         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11177                          (match_operand:SI 3 "register_operand" "r")
11178                          (match_dup 1)))]
11179   "TARGET_CMOVE"
11180   "")
11181
11182 (define_expand "x86_shift_adj_2"
11183   [(use (match_operand:SI 0 "register_operand" ""))
11184    (use (match_operand:SI 1 "register_operand" ""))
11185    (use (match_operand:QI 2 "register_operand" ""))]
11186   ""
11187 {
11188   rtx label = gen_label_rtx ();
11189   rtx tmp;
11190
11191   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11192
11193   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11194   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11195   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11196                               gen_rtx_LABEL_REF (VOIDmode, label),
11197                               pc_rtx);
11198   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11199   JUMP_LABEL (tmp) = label;
11200
11201   emit_move_insn (operands[0], operands[1]);
11202   ix86_expand_clear (operands[1]);
11203
11204   emit_label (label);
11205   LABEL_NUSES (label) = 1;
11206
11207   DONE;
11208 })
11209
11210 (define_expand "ashlsi3"
11211   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11212         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11213                    (match_operand:QI 2 "nonmemory_operand" "")))]
11214   ""
11215   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11216
11217 (define_insn "*ashlsi3_1"
11218   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11219         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11220                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11221    (clobber (reg:CC FLAGS_REG))]
11222   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11223 {
11224   switch (get_attr_type (insn))
11225     {
11226     case TYPE_ALU:
11227       gcc_assert (operands[2] == const1_rtx);
11228       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11229       return "add{l}\t%0, %0";
11230
11231     case TYPE_LEA:
11232       return "#";
11233
11234     default:
11235       if (REG_P (operands[2]))
11236         return "sal{l}\t{%b2, %0|%0, %b2}";
11237       else if (operands[2] == const1_rtx
11238                && (TARGET_SHIFT1 || optimize_size))
11239         return "sal{l}\t%0";
11240       else
11241         return "sal{l}\t{%2, %0|%0, %2}";
11242     }
11243 }
11244   [(set (attr "type")
11245      (cond [(eq_attr "alternative" "1")
11246               (const_string "lea")
11247             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11248                           (const_int 0))
11249                       (match_operand 0 "register_operand" ""))
11250                  (match_operand 2 "const1_operand" ""))
11251               (const_string "alu")
11252            ]
11253            (const_string "ishift")))
11254    (set_attr "mode" "SI")])
11255
11256 ;; Convert lea to the lea pattern to avoid flags dependency.
11257 (define_split
11258   [(set (match_operand 0 "register_operand" "")
11259         (ashift (match_operand 1 "index_register_operand" "")
11260                 (match_operand:QI 2 "const_int_operand" "")))
11261    (clobber (reg:CC FLAGS_REG))]
11262   "reload_completed
11263    && true_regnum (operands[0]) != true_regnum (operands[1])
11264    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11265   [(const_int 0)]
11266 {
11267   rtx pat;
11268   enum machine_mode mode = GET_MODE (operands[0]);
11269
11270   if (GET_MODE_SIZE (mode) < 4)
11271     operands[0] = gen_lowpart (SImode, operands[0]);
11272   if (mode != Pmode)
11273     operands[1] = gen_lowpart (Pmode, operands[1]);
11274   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11275
11276   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11277   if (Pmode != SImode)
11278     pat = gen_rtx_SUBREG (SImode, pat, 0);
11279   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11280   DONE;
11281 })
11282
11283 ;; Rare case of shifting RSP is handled by generating move and shift
11284 (define_split
11285   [(set (match_operand 0 "register_operand" "")
11286         (ashift (match_operand 1 "register_operand" "")
11287                 (match_operand:QI 2 "const_int_operand" "")))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "reload_completed
11290    && true_regnum (operands[0]) != true_regnum (operands[1])"
11291   [(const_int 0)]
11292 {
11293   rtx pat, clob;
11294   emit_move_insn (operands[0], operands[1]);
11295   pat = gen_rtx_SET (VOIDmode, operands[0],
11296                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11297                                      operands[0], operands[2]));
11298   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11299   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11300   DONE;
11301 })
11302
11303 (define_insn "*ashlsi3_1_zext"
11304   [(set (match_operand:DI 0 "register_operand" "=r,r")
11305         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11306                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11307    (clobber (reg:CC FLAGS_REG))]
11308   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11309 {
11310   switch (get_attr_type (insn))
11311     {
11312     case TYPE_ALU:
11313       gcc_assert (operands[2] == const1_rtx);
11314       return "add{l}\t%k0, %k0";
11315
11316     case TYPE_LEA:
11317       return "#";
11318
11319     default:
11320       if (REG_P (operands[2]))
11321         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11322       else if (operands[2] == const1_rtx
11323                && (TARGET_SHIFT1 || optimize_size))
11324         return "sal{l}\t%k0";
11325       else
11326         return "sal{l}\t{%2, %k0|%k0, %2}";
11327     }
11328 }
11329   [(set (attr "type")
11330      (cond [(eq_attr "alternative" "1")
11331               (const_string "lea")
11332             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11333                      (const_int 0))
11334                  (match_operand 2 "const1_operand" ""))
11335               (const_string "alu")
11336            ]
11337            (const_string "ishift")))
11338    (set_attr "mode" "SI")])
11339
11340 ;; Convert lea to the lea pattern to avoid flags dependency.
11341 (define_split
11342   [(set (match_operand:DI 0 "register_operand" "")
11343         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11344                                 (match_operand:QI 2 "const_int_operand" ""))))
11345    (clobber (reg:CC FLAGS_REG))]
11346   "TARGET_64BIT && reload_completed
11347    && true_regnum (operands[0]) != true_regnum (operands[1])"
11348   [(set (match_dup 0) (zero_extend:DI
11349                         (subreg:SI (mult:SI (match_dup 1)
11350                                             (match_dup 2)) 0)))]
11351 {
11352   operands[1] = gen_lowpart (Pmode, operands[1]);
11353   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11354 })
11355
11356 ;; This pattern can't accept a variable shift count, since shifts by
11357 ;; zero don't affect the flags.  We assume that shifts by constant
11358 ;; zero are optimized away.
11359 (define_insn "*ashlsi3_cmp"
11360   [(set (reg FLAGS_REG)
11361         (compare
11362           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11363                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11364           (const_int 0)))
11365    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11366         (ashift:SI (match_dup 1) (match_dup 2)))]
11367    "(optimize_size
11368      || !TARGET_PARTIAL_FLAG_REG_STALL
11369      || (operands[2] == const1_rtx
11370          && (TARGET_SHIFT1
11371              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11372    && ix86_match_ccmode (insn, CCGOCmode)
11373    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11374 {
11375   switch (get_attr_type (insn))
11376     {
11377     case TYPE_ALU:
11378       gcc_assert (operands[2] == const1_rtx);
11379       return "add{l}\t%0, %0";
11380
11381     default:
11382       if (REG_P (operands[2]))
11383         return "sal{l}\t{%b2, %0|%0, %b2}";
11384       else if (operands[2] == const1_rtx
11385                && (TARGET_SHIFT1 || optimize_size))
11386         return "sal{l}\t%0";
11387       else
11388         return "sal{l}\t{%2, %0|%0, %2}";
11389     }
11390 }
11391   [(set (attr "type")
11392      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11393                           (const_int 0))
11394                       (match_operand 0 "register_operand" ""))
11395                  (match_operand 2 "const1_operand" ""))
11396               (const_string "alu")
11397            ]
11398            (const_string "ishift")))
11399    (set_attr "mode" "SI")])
11400
11401 (define_insn "*ashlsi3_cconly"
11402   [(set (reg FLAGS_REG)
11403         (compare
11404           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11405                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11406           (const_int 0)))
11407    (clobber (match_scratch:SI 0 "=r"))]
11408   "(optimize_size
11409     || !TARGET_PARTIAL_FLAG_REG_STALL
11410     || (operands[2] == const1_rtx
11411         && (TARGET_SHIFT1
11412             || TARGET_DOUBLE_WITH_ADD)))
11413    && ix86_match_ccmode (insn, CCGOCmode)
11414    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11415 {
11416   switch (get_attr_type (insn))
11417     {
11418     case TYPE_ALU:
11419       gcc_assert (operands[2] == const1_rtx);
11420       return "add{l}\t%0, %0";
11421
11422     default:
11423       if (REG_P (operands[2]))
11424         return "sal{l}\t{%b2, %0|%0, %b2}";
11425       else if (operands[2] == const1_rtx
11426                && (TARGET_SHIFT1 || optimize_size))
11427         return "sal{l}\t%0";
11428       else
11429         return "sal{l}\t{%2, %0|%0, %2}";
11430     }
11431 }
11432   [(set (attr "type")
11433      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11434                           (const_int 0))
11435                       (match_operand 0 "register_operand" ""))
11436                  (match_operand 2 "const1_operand" ""))
11437               (const_string "alu")
11438            ]
11439            (const_string "ishift")))
11440    (set_attr "mode" "SI")])
11441
11442 (define_insn "*ashlsi3_cmp_zext"
11443   [(set (reg FLAGS_REG)
11444         (compare
11445           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11446                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11447           (const_int 0)))
11448    (set (match_operand:DI 0 "register_operand" "=r")
11449         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11450   "TARGET_64BIT
11451    && (optimize_size
11452        || !TARGET_PARTIAL_FLAG_REG_STALL
11453        || (operands[2] == const1_rtx
11454            && (TARGET_SHIFT1
11455                || TARGET_DOUBLE_WITH_ADD)))
11456    && ix86_match_ccmode (insn, CCGOCmode)
11457    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11458 {
11459   switch (get_attr_type (insn))
11460     {
11461     case TYPE_ALU:
11462       gcc_assert (operands[2] == const1_rtx);
11463       return "add{l}\t%k0, %k0";
11464
11465     default:
11466       if (REG_P (operands[2]))
11467         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11468       else if (operands[2] == const1_rtx
11469                && (TARGET_SHIFT1 || optimize_size))
11470         return "sal{l}\t%k0";
11471       else
11472         return "sal{l}\t{%2, %k0|%k0, %2}";
11473     }
11474 }
11475   [(set (attr "type")
11476      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11477                      (const_int 0))
11478                  (match_operand 2 "const1_operand" ""))
11479               (const_string "alu")
11480            ]
11481            (const_string "ishift")))
11482    (set_attr "mode" "SI")])
11483
11484 (define_expand "ashlhi3"
11485   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11486         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11487                    (match_operand:QI 2 "nonmemory_operand" "")))]
11488   "TARGET_HIMODE_MATH"
11489   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11490
11491 (define_insn "*ashlhi3_1_lea"
11492   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11493         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11494                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11495    (clobber (reg:CC FLAGS_REG))]
11496   "!TARGET_PARTIAL_REG_STALL
11497    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11498 {
11499   switch (get_attr_type (insn))
11500     {
11501     case TYPE_LEA:
11502       return "#";
11503     case TYPE_ALU:
11504       gcc_assert (operands[2] == const1_rtx);
11505       return "add{w}\t%0, %0";
11506
11507     default:
11508       if (REG_P (operands[2]))
11509         return "sal{w}\t{%b2, %0|%0, %b2}";
11510       else if (operands[2] == const1_rtx
11511                && (TARGET_SHIFT1 || optimize_size))
11512         return "sal{w}\t%0";
11513       else
11514         return "sal{w}\t{%2, %0|%0, %2}";
11515     }
11516 }
11517   [(set (attr "type")
11518      (cond [(eq_attr "alternative" "1")
11519               (const_string "lea")
11520             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11521                           (const_int 0))
11522                       (match_operand 0 "register_operand" ""))
11523                  (match_operand 2 "const1_operand" ""))
11524               (const_string "alu")
11525            ]
11526            (const_string "ishift")))
11527    (set_attr "mode" "HI,SI")])
11528
11529 (define_insn "*ashlhi3_1"
11530   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11531         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11532                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "TARGET_PARTIAL_REG_STALL
11535    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11536 {
11537   switch (get_attr_type (insn))
11538     {
11539     case TYPE_ALU:
11540       gcc_assert (operands[2] == const1_rtx);
11541       return "add{w}\t%0, %0";
11542
11543     default:
11544       if (REG_P (operands[2]))
11545         return "sal{w}\t{%b2, %0|%0, %b2}";
11546       else if (operands[2] == const1_rtx
11547                && (TARGET_SHIFT1 || optimize_size))
11548         return "sal{w}\t%0";
11549       else
11550         return "sal{w}\t{%2, %0|%0, %2}";
11551     }
11552 }
11553   [(set (attr "type")
11554      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11555                           (const_int 0))
11556                       (match_operand 0 "register_operand" ""))
11557                  (match_operand 2 "const1_operand" ""))
11558               (const_string "alu")
11559            ]
11560            (const_string "ishift")))
11561    (set_attr "mode" "HI")])
11562
11563 ;; This pattern can't accept a variable shift count, since shifts by
11564 ;; zero don't affect the flags.  We assume that shifts by constant
11565 ;; zero are optimized away.
11566 (define_insn "*ashlhi3_cmp"
11567   [(set (reg FLAGS_REG)
11568         (compare
11569           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11570                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11571           (const_int 0)))
11572    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11573         (ashift:HI (match_dup 1) (match_dup 2)))]
11574   "(optimize_size
11575     || !TARGET_PARTIAL_FLAG_REG_STALL
11576     || (operands[2] == const1_rtx
11577         && (TARGET_SHIFT1
11578             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11579    && ix86_match_ccmode (insn, CCGOCmode)
11580    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11581 {
11582   switch (get_attr_type (insn))
11583     {
11584     case TYPE_ALU:
11585       gcc_assert (operands[2] == const1_rtx);
11586       return "add{w}\t%0, %0";
11587
11588     default:
11589       if (REG_P (operands[2]))
11590         return "sal{w}\t{%b2, %0|%0, %b2}";
11591       else if (operands[2] == const1_rtx
11592                && (TARGET_SHIFT1 || optimize_size))
11593         return "sal{w}\t%0";
11594       else
11595         return "sal{w}\t{%2, %0|%0, %2}";
11596     }
11597 }
11598   [(set (attr "type")
11599      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11600                           (const_int 0))
11601                       (match_operand 0 "register_operand" ""))
11602                  (match_operand 2 "const1_operand" ""))
11603               (const_string "alu")
11604            ]
11605            (const_string "ishift")))
11606    (set_attr "mode" "HI")])
11607
11608 (define_insn "*ashlhi3_cconly"
11609   [(set (reg FLAGS_REG)
11610         (compare
11611           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11612                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11613           (const_int 0)))
11614    (clobber (match_scratch:HI 0 "=r"))]
11615   "(optimize_size
11616     || !TARGET_PARTIAL_FLAG_REG_STALL
11617     || (operands[2] == const1_rtx
11618         && (TARGET_SHIFT1
11619             || TARGET_DOUBLE_WITH_ADD)))
11620    && ix86_match_ccmode (insn, CCGOCmode)
11621    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11622 {
11623   switch (get_attr_type (insn))
11624     {
11625     case TYPE_ALU:
11626       gcc_assert (operands[2] == const1_rtx);
11627       return "add{w}\t%0, %0";
11628
11629     default:
11630       if (REG_P (operands[2]))
11631         return "sal{w}\t{%b2, %0|%0, %b2}";
11632       else if (operands[2] == const1_rtx
11633                && (TARGET_SHIFT1 || optimize_size))
11634         return "sal{w}\t%0";
11635       else
11636         return "sal{w}\t{%2, %0|%0, %2}";
11637     }
11638 }
11639   [(set (attr "type")
11640      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11641                           (const_int 0))
11642                       (match_operand 0 "register_operand" ""))
11643                  (match_operand 2 "const1_operand" ""))
11644               (const_string "alu")
11645            ]
11646            (const_string "ishift")))
11647    (set_attr "mode" "HI")])
11648
11649 (define_expand "ashlqi3"
11650   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11651         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11652                    (match_operand:QI 2 "nonmemory_operand" "")))]
11653   "TARGET_QIMODE_MATH"
11654   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11655
11656 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11657
11658 (define_insn "*ashlqi3_1_lea"
11659   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11660         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11661                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11662    (clobber (reg:CC FLAGS_REG))]
11663   "!TARGET_PARTIAL_REG_STALL
11664    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11665 {
11666   switch (get_attr_type (insn))
11667     {
11668     case TYPE_LEA:
11669       return "#";
11670     case TYPE_ALU:
11671       gcc_assert (operands[2] == const1_rtx);
11672       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11673         return "add{l}\t%k0, %k0";
11674       else
11675         return "add{b}\t%0, %0";
11676
11677     default:
11678       if (REG_P (operands[2]))
11679         {
11680           if (get_attr_mode (insn) == MODE_SI)
11681             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11682           else
11683             return "sal{b}\t{%b2, %0|%0, %b2}";
11684         }
11685       else if (operands[2] == const1_rtx
11686                && (TARGET_SHIFT1 || optimize_size))
11687         {
11688           if (get_attr_mode (insn) == MODE_SI)
11689             return "sal{l}\t%0";
11690           else
11691             return "sal{b}\t%0";
11692         }
11693       else
11694         {
11695           if (get_attr_mode (insn) == MODE_SI)
11696             return "sal{l}\t{%2, %k0|%k0, %2}";
11697           else
11698             return "sal{b}\t{%2, %0|%0, %2}";
11699         }
11700     }
11701 }
11702   [(set (attr "type")
11703      (cond [(eq_attr "alternative" "2")
11704               (const_string "lea")
11705             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11706                           (const_int 0))
11707                       (match_operand 0 "register_operand" ""))
11708                  (match_operand 2 "const1_operand" ""))
11709               (const_string "alu")
11710            ]
11711            (const_string "ishift")))
11712    (set_attr "mode" "QI,SI,SI")])
11713
11714 (define_insn "*ashlqi3_1"
11715   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11716         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11717                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11718    (clobber (reg:CC FLAGS_REG))]
11719   "TARGET_PARTIAL_REG_STALL
11720    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11721 {
11722   switch (get_attr_type (insn))
11723     {
11724     case TYPE_ALU:
11725       gcc_assert (operands[2] == const1_rtx);
11726       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11727         return "add{l}\t%k0, %k0";
11728       else
11729         return "add{b}\t%0, %0";
11730
11731     default:
11732       if (REG_P (operands[2]))
11733         {
11734           if (get_attr_mode (insn) == MODE_SI)
11735             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11736           else
11737             return "sal{b}\t{%b2, %0|%0, %b2}";
11738         }
11739       else if (operands[2] == const1_rtx
11740                && (TARGET_SHIFT1 || optimize_size))
11741         {
11742           if (get_attr_mode (insn) == MODE_SI)
11743             return "sal{l}\t%0";
11744           else
11745             return "sal{b}\t%0";
11746         }
11747       else
11748         {
11749           if (get_attr_mode (insn) == MODE_SI)
11750             return "sal{l}\t{%2, %k0|%k0, %2}";
11751           else
11752             return "sal{b}\t{%2, %0|%0, %2}";
11753         }
11754     }
11755 }
11756   [(set (attr "type")
11757      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11758                           (const_int 0))
11759                       (match_operand 0 "register_operand" ""))
11760                  (match_operand 2 "const1_operand" ""))
11761               (const_string "alu")
11762            ]
11763            (const_string "ishift")))
11764    (set_attr "mode" "QI,SI")])
11765
11766 ;; This pattern can't accept a variable shift count, since shifts by
11767 ;; zero don't affect the flags.  We assume that shifts by constant
11768 ;; zero are optimized away.
11769 (define_insn "*ashlqi3_cmp"
11770   [(set (reg FLAGS_REG)
11771         (compare
11772           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11773                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11774           (const_int 0)))
11775    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11776         (ashift:QI (match_dup 1) (match_dup 2)))]
11777   "(optimize_size
11778     || !TARGET_PARTIAL_FLAG_REG_STALL
11779     || (operands[2] == const1_rtx
11780         && (TARGET_SHIFT1
11781             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11782    && ix86_match_ccmode (insn, CCGOCmode)
11783    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11784 {
11785   switch (get_attr_type (insn))
11786     {
11787     case TYPE_ALU:
11788       gcc_assert (operands[2] == const1_rtx);
11789       return "add{b}\t%0, %0";
11790
11791     default:
11792       if (REG_P (operands[2]))
11793         return "sal{b}\t{%b2, %0|%0, %b2}";
11794       else if (operands[2] == const1_rtx
11795                && (TARGET_SHIFT1 || optimize_size))
11796         return "sal{b}\t%0";
11797       else
11798         return "sal{b}\t{%2, %0|%0, %2}";
11799     }
11800 }
11801   [(set (attr "type")
11802      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11803                           (const_int 0))
11804                       (match_operand 0 "register_operand" ""))
11805                  (match_operand 2 "const1_operand" ""))
11806               (const_string "alu")
11807            ]
11808            (const_string "ishift")))
11809    (set_attr "mode" "QI")])
11810
11811 (define_insn "*ashlqi3_cconly"
11812   [(set (reg FLAGS_REG)
11813         (compare
11814           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11815                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11816           (const_int 0)))
11817    (clobber (match_scratch:QI 0 "=q"))]
11818   "(optimize_size
11819     || !TARGET_PARTIAL_FLAG_REG_STALL
11820     || (operands[2] == const1_rtx
11821         && (TARGET_SHIFT1
11822             || TARGET_DOUBLE_WITH_ADD)))
11823    && ix86_match_ccmode (insn, CCGOCmode)
11824    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11825 {
11826   switch (get_attr_type (insn))
11827     {
11828     case TYPE_ALU:
11829       gcc_assert (operands[2] == const1_rtx);
11830       return "add{b}\t%0, %0";
11831
11832     default:
11833       if (REG_P (operands[2]))
11834         return "sal{b}\t{%b2, %0|%0, %b2}";
11835       else if (operands[2] == const1_rtx
11836                && (TARGET_SHIFT1 || optimize_size))
11837         return "sal{b}\t%0";
11838       else
11839         return "sal{b}\t{%2, %0|%0, %2}";
11840     }
11841 }
11842   [(set (attr "type")
11843      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11844                           (const_int 0))
11845                       (match_operand 0 "register_operand" ""))
11846                  (match_operand 2 "const1_operand" ""))
11847               (const_string "alu")
11848            ]
11849            (const_string "ishift")))
11850    (set_attr "mode" "QI")])
11851
11852 ;; See comment above `ashldi3' about how this works.
11853
11854 (define_expand "ashrti3"
11855   [(set (match_operand:TI 0 "register_operand" "")
11856         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11857                      (match_operand:QI 2 "nonmemory_operand" "")))]
11858   "TARGET_64BIT"
11859   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11860
11861 (define_insn "*ashrti3_1"
11862   [(set (match_operand:TI 0 "register_operand" "=r")
11863         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11864                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_64BIT"
11867   "#"
11868   [(set_attr "type" "multi")])
11869
11870 (define_peephole2
11871   [(match_scratch:DI 3 "r")
11872    (parallel [(set (match_operand:TI 0 "register_operand" "")
11873                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11874                                 (match_operand:QI 2 "nonmemory_operand" "")))
11875               (clobber (reg:CC FLAGS_REG))])
11876    (match_dup 3)]
11877   "TARGET_64BIT"
11878   [(const_int 0)]
11879   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11880
11881 (define_split
11882   [(set (match_operand:TI 0 "register_operand" "")
11883         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11884                      (match_operand:QI 2 "nonmemory_operand" "")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11887                     ? epilogue_completed : reload_completed)"
11888   [(const_int 0)]
11889   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11890
11891 (define_insn "x86_64_shrd"
11892   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11893         (ior:DI (ashiftrt:DI (match_dup 0)
11894                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11895                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11896                   (minus:QI (const_int 64) (match_dup 2)))))
11897    (clobber (reg:CC FLAGS_REG))]
11898   "TARGET_64BIT"
11899   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11900   [(set_attr "type" "ishift")
11901    (set_attr "prefix_0f" "1")
11902    (set_attr "mode" "DI")
11903    (set_attr "athlon_decode" "vector")
11904    (set_attr "amdfam10_decode" "vector")])
11905
11906 (define_expand "ashrdi3"
11907   [(set (match_operand:DI 0 "shiftdi_operand" "")
11908         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11909                      (match_operand:QI 2 "nonmemory_operand" "")))]
11910   ""
11911   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11912
11913 (define_expand "x86_64_shift_adj_3"
11914   [(use (match_operand:DI 0 "register_operand" ""))
11915    (use (match_operand:DI 1 "register_operand" ""))
11916    (use (match_operand:QI 2 "register_operand" ""))]
11917   ""
11918 {
11919   rtx label = gen_label_rtx ();
11920   rtx tmp;
11921
11922   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11923
11924   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11925   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11926   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11927                               gen_rtx_LABEL_REF (VOIDmode, label),
11928                               pc_rtx);
11929   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11930   JUMP_LABEL (tmp) = label;
11931
11932   emit_move_insn (operands[0], operands[1]);
11933   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11934
11935   emit_label (label);
11936   LABEL_NUSES (label) = 1;
11937
11938   DONE;
11939 })
11940
11941 (define_insn "ashrdi3_63_rex64"
11942   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11943         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11944                      (match_operand:DI 2 "const_int_operand" "i,i")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "TARGET_64BIT && INTVAL (operands[2]) == 63
11947    && (TARGET_USE_CLTD || optimize_size)
11948    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11949   "@
11950    {cqto|cqo}
11951    sar{q}\t{%2, %0|%0, %2}"
11952   [(set_attr "type" "imovx,ishift")
11953    (set_attr "prefix_0f" "0,*")
11954    (set_attr "length_immediate" "0,*")
11955    (set_attr "modrm" "0,1")
11956    (set_attr "mode" "DI")])
11957
11958 (define_insn "*ashrdi3_1_one_bit_rex64"
11959   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11960         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11961                      (match_operand:QI 2 "const1_operand" "")))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "TARGET_64BIT
11964    && (TARGET_SHIFT1 || optimize_size)
11965    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11966   "sar{q}\t%0"
11967   [(set_attr "type" "ishift")
11968    (set (attr "length")
11969      (if_then_else (match_operand:DI 0 "register_operand" "")
11970         (const_string "2")
11971         (const_string "*")))])
11972
11973 (define_insn "*ashrdi3_1_rex64"
11974   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11975         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11976                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11977    (clobber (reg:CC FLAGS_REG))]
11978   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11979   "@
11980    sar{q}\t{%2, %0|%0, %2}
11981    sar{q}\t{%b2, %0|%0, %b2}"
11982   [(set_attr "type" "ishift")
11983    (set_attr "mode" "DI")])
11984
11985 ;; This pattern can't accept a variable shift count, since shifts by
11986 ;; zero don't affect the flags.  We assume that shifts by constant
11987 ;; zero are optimized away.
11988 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11989   [(set (reg FLAGS_REG)
11990         (compare
11991           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11992                        (match_operand:QI 2 "const1_operand" ""))
11993           (const_int 0)))
11994    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11995         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11996   "TARGET_64BIT
11997    && (TARGET_SHIFT1 || optimize_size)
11998    && ix86_match_ccmode (insn, CCGOCmode)
11999    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12000   "sar{q}\t%0"
12001   [(set_attr "type" "ishift")
12002    (set (attr "length")
12003      (if_then_else (match_operand:DI 0 "register_operand" "")
12004         (const_string "2")
12005         (const_string "*")))])
12006
12007 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12008   [(set (reg FLAGS_REG)
12009         (compare
12010           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12011                        (match_operand:QI 2 "const1_operand" ""))
12012           (const_int 0)))
12013    (clobber (match_scratch:DI 0 "=r"))]
12014   "TARGET_64BIT
12015    && (TARGET_SHIFT1 || optimize_size)
12016    && ix86_match_ccmode (insn, CCGOCmode)
12017    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12018   "sar{q}\t%0"
12019   [(set_attr "type" "ishift")
12020    (set_attr "length" "2")])
12021
12022 ;; This pattern can't accept a variable shift count, since shifts by
12023 ;; zero don't affect the flags.  We assume that shifts by constant
12024 ;; zero are optimized away.
12025 (define_insn "*ashrdi3_cmp_rex64"
12026   [(set (reg FLAGS_REG)
12027         (compare
12028           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12029                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12030           (const_int 0)))
12031    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12032         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12033   "TARGET_64BIT
12034    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12035    && ix86_match_ccmode (insn, CCGOCmode)
12036    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12037   "sar{q}\t{%2, %0|%0, %2}"
12038   [(set_attr "type" "ishift")
12039    (set_attr "mode" "DI")])
12040
12041 (define_insn "*ashrdi3_cconly_rex64"
12042   [(set (reg FLAGS_REG)
12043         (compare
12044           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12045                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12046           (const_int 0)))
12047    (clobber (match_scratch:DI 0 "=r"))]
12048   "TARGET_64BIT
12049    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12050    && ix86_match_ccmode (insn, CCGOCmode)
12051    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12052   "sar{q}\t{%2, %0|%0, %2}"
12053   [(set_attr "type" "ishift")
12054    (set_attr "mode" "DI")])
12055
12056 (define_insn "*ashrdi3_1"
12057   [(set (match_operand:DI 0 "register_operand" "=r")
12058         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12059                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12060    (clobber (reg:CC FLAGS_REG))]
12061   "!TARGET_64BIT"
12062   "#"
12063   [(set_attr "type" "multi")])
12064
12065 ;; By default we don't ask for a scratch register, because when DImode
12066 ;; values are manipulated, registers are already at a premium.  But if
12067 ;; we have one handy, we won't turn it away.
12068 (define_peephole2
12069   [(match_scratch:SI 3 "r")
12070    (parallel [(set (match_operand:DI 0 "register_operand" "")
12071                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12072                                 (match_operand:QI 2 "nonmemory_operand" "")))
12073               (clobber (reg:CC FLAGS_REG))])
12074    (match_dup 3)]
12075   "!TARGET_64BIT && TARGET_CMOVE"
12076   [(const_int 0)]
12077   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12078
12079 (define_split
12080   [(set (match_operand:DI 0 "register_operand" "")
12081         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12082                      (match_operand:QI 2 "nonmemory_operand" "")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12085                      ? epilogue_completed : reload_completed)"
12086   [(const_int 0)]
12087   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12088
12089 (define_insn "x86_shrd"
12090   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12091         (ior:SI (ashiftrt:SI (match_dup 0)
12092                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12093                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12094                   (minus:QI (const_int 32) (match_dup 2)))))
12095    (clobber (reg:CC FLAGS_REG))]
12096   ""
12097   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12098   [(set_attr "type" "ishift")
12099    (set_attr "prefix_0f" "1")
12100    (set_attr "pent_pair" "np")
12101    (set_attr "mode" "SI")])
12102
12103 (define_expand "x86_shift_adj_3"
12104   [(use (match_operand:SI 0 "register_operand" ""))
12105    (use (match_operand:SI 1 "register_operand" ""))
12106    (use (match_operand:QI 2 "register_operand" ""))]
12107   ""
12108 {
12109   rtx label = gen_label_rtx ();
12110   rtx tmp;
12111
12112   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12113
12114   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12115   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12116   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12117                               gen_rtx_LABEL_REF (VOIDmode, label),
12118                               pc_rtx);
12119   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12120   JUMP_LABEL (tmp) = label;
12121
12122   emit_move_insn (operands[0], operands[1]);
12123   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12124
12125   emit_label (label);
12126   LABEL_NUSES (label) = 1;
12127
12128   DONE;
12129 })
12130
12131 (define_insn "ashrsi3_31"
12132   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12133         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12134                      (match_operand:SI 2 "const_int_operand" "i,i")))
12135    (clobber (reg:CC FLAGS_REG))]
12136   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12137    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12138   "@
12139    {cltd|cdq}
12140    sar{l}\t{%2, %0|%0, %2}"
12141   [(set_attr "type" "imovx,ishift")
12142    (set_attr "prefix_0f" "0,*")
12143    (set_attr "length_immediate" "0,*")
12144    (set_attr "modrm" "0,1")
12145    (set_attr "mode" "SI")])
12146
12147 (define_insn "*ashrsi3_31_zext"
12148   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12149         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12150                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12153    && INTVAL (operands[2]) == 31
12154    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12155   "@
12156    {cltd|cdq}
12157    sar{l}\t{%2, %k0|%k0, %2}"
12158   [(set_attr "type" "imovx,ishift")
12159    (set_attr "prefix_0f" "0,*")
12160    (set_attr "length_immediate" "0,*")
12161    (set_attr "modrm" "0,1")
12162    (set_attr "mode" "SI")])
12163
12164 (define_expand "ashrsi3"
12165   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12166         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12167                      (match_operand:QI 2 "nonmemory_operand" "")))]
12168   ""
12169   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12170
12171 (define_insn "*ashrsi3_1_one_bit"
12172   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12173         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12174                      (match_operand:QI 2 "const1_operand" "")))
12175    (clobber (reg:CC FLAGS_REG))]
12176   "(TARGET_SHIFT1 || optimize_size)
12177    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12178   "sar{l}\t%0"
12179   [(set_attr "type" "ishift")
12180    (set (attr "length")
12181      (if_then_else (match_operand:SI 0 "register_operand" "")
12182         (const_string "2")
12183         (const_string "*")))])
12184
12185 (define_insn "*ashrsi3_1_one_bit_zext"
12186   [(set (match_operand:DI 0 "register_operand" "=r")
12187         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12188                                      (match_operand:QI 2 "const1_operand" ""))))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "TARGET_64BIT
12191    && (TARGET_SHIFT1 || optimize_size)
12192    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12193   "sar{l}\t%k0"
12194   [(set_attr "type" "ishift")
12195    (set_attr "length" "2")])
12196
12197 (define_insn "*ashrsi3_1"
12198   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12199         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12200                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12201    (clobber (reg:CC FLAGS_REG))]
12202   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12203   "@
12204    sar{l}\t{%2, %0|%0, %2}
12205    sar{l}\t{%b2, %0|%0, %b2}"
12206   [(set_attr "type" "ishift")
12207    (set_attr "mode" "SI")])
12208
12209 (define_insn "*ashrsi3_1_zext"
12210   [(set (match_operand:DI 0 "register_operand" "=r,r")
12211         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12212                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12213    (clobber (reg:CC FLAGS_REG))]
12214   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12215   "@
12216    sar{l}\t{%2, %k0|%k0, %2}
12217    sar{l}\t{%b2, %k0|%k0, %b2}"
12218   [(set_attr "type" "ishift")
12219    (set_attr "mode" "SI")])
12220
12221 ;; This pattern can't accept a variable shift count, since shifts by
12222 ;; zero don't affect the flags.  We assume that shifts by constant
12223 ;; zero are optimized away.
12224 (define_insn "*ashrsi3_one_bit_cmp"
12225   [(set (reg FLAGS_REG)
12226         (compare
12227           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12228                        (match_operand:QI 2 "const1_operand" ""))
12229           (const_int 0)))
12230    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12231         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12232   "(TARGET_SHIFT1 || optimize_size)
12233    && ix86_match_ccmode (insn, CCGOCmode)
12234    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12235   "sar{l}\t%0"
12236   [(set_attr "type" "ishift")
12237    (set (attr "length")
12238      (if_then_else (match_operand:SI 0 "register_operand" "")
12239         (const_string "2")
12240         (const_string "*")))])
12241
12242 (define_insn "*ashrsi3_one_bit_cconly"
12243   [(set (reg FLAGS_REG)
12244         (compare
12245           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12246                        (match_operand:QI 2 "const1_operand" ""))
12247           (const_int 0)))
12248    (clobber (match_scratch:SI 0 "=r"))]
12249   "(TARGET_SHIFT1 || optimize_size)
12250    && ix86_match_ccmode (insn, CCGOCmode)
12251    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12252   "sar{l}\t%0"
12253   [(set_attr "type" "ishift")
12254    (set_attr "length" "2")])
12255
12256 (define_insn "*ashrsi3_one_bit_cmp_zext"
12257   [(set (reg FLAGS_REG)
12258         (compare
12259           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12260                        (match_operand:QI 2 "const1_operand" ""))
12261           (const_int 0)))
12262    (set (match_operand:DI 0 "register_operand" "=r")
12263         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12264   "TARGET_64BIT
12265    && (TARGET_SHIFT1 || optimize_size)
12266    && ix86_match_ccmode (insn, CCmode)
12267    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12268   "sar{l}\t%k0"
12269   [(set_attr "type" "ishift")
12270    (set_attr "length" "2")])
12271
12272 ;; This pattern can't accept a variable shift count, since shifts by
12273 ;; zero don't affect the flags.  We assume that shifts by constant
12274 ;; zero are optimized away.
12275 (define_insn "*ashrsi3_cmp"
12276   [(set (reg FLAGS_REG)
12277         (compare
12278           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12279                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12280           (const_int 0)))
12281    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12282         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12283   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12284    && ix86_match_ccmode (insn, CCGOCmode)
12285    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12286   "sar{l}\t{%2, %0|%0, %2}"
12287   [(set_attr "type" "ishift")
12288    (set_attr "mode" "SI")])
12289
12290 (define_insn "*ashrsi3_cconly"
12291   [(set (reg FLAGS_REG)
12292         (compare
12293           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12294                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12295           (const_int 0)))
12296    (clobber (match_scratch:SI 0 "=r"))]
12297   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12298    && ix86_match_ccmode (insn, CCGOCmode)
12299    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12300   "sar{l}\t{%2, %0|%0, %2}"
12301   [(set_attr "type" "ishift")
12302    (set_attr "mode" "SI")])
12303
12304 (define_insn "*ashrsi3_cmp_zext"
12305   [(set (reg FLAGS_REG)
12306         (compare
12307           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12308                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12309           (const_int 0)))
12310    (set (match_operand:DI 0 "register_operand" "=r")
12311         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12312   "TARGET_64BIT
12313    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12314    && ix86_match_ccmode (insn, CCGOCmode)
12315    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12316   "sar{l}\t{%2, %k0|%k0, %2}"
12317   [(set_attr "type" "ishift")
12318    (set_attr "mode" "SI")])
12319
12320 (define_expand "ashrhi3"
12321   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12322         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12323                      (match_operand:QI 2 "nonmemory_operand" "")))]
12324   "TARGET_HIMODE_MATH"
12325   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12326
12327 (define_insn "*ashrhi3_1_one_bit"
12328   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12329         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12330                      (match_operand:QI 2 "const1_operand" "")))
12331    (clobber (reg:CC FLAGS_REG))]
12332   "(TARGET_SHIFT1 || optimize_size)
12333    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12334   "sar{w}\t%0"
12335   [(set_attr "type" "ishift")
12336    (set (attr "length")
12337      (if_then_else (match_operand 0 "register_operand" "")
12338         (const_string "2")
12339         (const_string "*")))])
12340
12341 (define_insn "*ashrhi3_1"
12342   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12343         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12344                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12345    (clobber (reg:CC FLAGS_REG))]
12346   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12347   "@
12348    sar{w}\t{%2, %0|%0, %2}
12349    sar{w}\t{%b2, %0|%0, %b2}"
12350   [(set_attr "type" "ishift")
12351    (set_attr "mode" "HI")])
12352
12353 ;; This pattern can't accept a variable shift count, since shifts by
12354 ;; zero don't affect the flags.  We assume that shifts by constant
12355 ;; zero are optimized away.
12356 (define_insn "*ashrhi3_one_bit_cmp"
12357   [(set (reg FLAGS_REG)
12358         (compare
12359           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12360                        (match_operand:QI 2 "const1_operand" ""))
12361           (const_int 0)))
12362    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12363         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12364   "(TARGET_SHIFT1 || optimize_size)
12365    && ix86_match_ccmode (insn, CCGOCmode)
12366    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12367   "sar{w}\t%0"
12368   [(set_attr "type" "ishift")
12369    (set (attr "length")
12370      (if_then_else (match_operand 0 "register_operand" "")
12371         (const_string "2")
12372         (const_string "*")))])
12373
12374 (define_insn "*ashrhi3_one_bit_cconly"
12375   [(set (reg FLAGS_REG)
12376         (compare
12377           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12378                        (match_operand:QI 2 "const1_operand" ""))
12379           (const_int 0)))
12380    (clobber (match_scratch:HI 0 "=r"))]
12381   "(TARGET_SHIFT1 || optimize_size)
12382    && ix86_match_ccmode (insn, CCGOCmode)
12383    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12384   "sar{w}\t%0"
12385   [(set_attr "type" "ishift")
12386    (set_attr "length" "2")])
12387
12388 ;; This pattern can't accept a variable shift count, since shifts by
12389 ;; zero don't affect the flags.  We assume that shifts by constant
12390 ;; zero are optimized away.
12391 (define_insn "*ashrhi3_cmp"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12395                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12396           (const_int 0)))
12397    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12398         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12399   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12400    && ix86_match_ccmode (insn, CCGOCmode)
12401    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12402   "sar{w}\t{%2, %0|%0, %2}"
12403   [(set_attr "type" "ishift")
12404    (set_attr "mode" "HI")])
12405
12406 (define_insn "*ashrhi3_cconly"
12407   [(set (reg FLAGS_REG)
12408         (compare
12409           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12410                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12411           (const_int 0)))
12412    (clobber (match_scratch:HI 0 "=r"))]
12413   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12414    && ix86_match_ccmode (insn, CCGOCmode)
12415    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12416   "sar{w}\t{%2, %0|%0, %2}"
12417   [(set_attr "type" "ishift")
12418    (set_attr "mode" "HI")])
12419
12420 (define_expand "ashrqi3"
12421   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12422         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12423                      (match_operand:QI 2 "nonmemory_operand" "")))]
12424   "TARGET_QIMODE_MATH"
12425   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12426
12427 (define_insn "*ashrqi3_1_one_bit"
12428   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12429         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12430                      (match_operand:QI 2 "const1_operand" "")))
12431    (clobber (reg:CC FLAGS_REG))]
12432   "(TARGET_SHIFT1 || optimize_size)
12433    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12434   "sar{b}\t%0"
12435   [(set_attr "type" "ishift")
12436    (set (attr "length")
12437      (if_then_else (match_operand 0 "register_operand" "")
12438         (const_string "2")
12439         (const_string "*")))])
12440
12441 (define_insn "*ashrqi3_1_one_bit_slp"
12442   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12443         (ashiftrt:QI (match_dup 0)
12444                      (match_operand:QI 1 "const1_operand" "")))
12445    (clobber (reg:CC FLAGS_REG))]
12446   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12447    && (TARGET_SHIFT1 || optimize_size)
12448    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12449   "sar{b}\t%0"
12450   [(set_attr "type" "ishift1")
12451    (set (attr "length")
12452      (if_then_else (match_operand 0 "register_operand" "")
12453         (const_string "2")
12454         (const_string "*")))])
12455
12456 (define_insn "*ashrqi3_1"
12457   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12458         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12459                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12460    (clobber (reg:CC FLAGS_REG))]
12461   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12462   "@
12463    sar{b}\t{%2, %0|%0, %2}
12464    sar{b}\t{%b2, %0|%0, %b2}"
12465   [(set_attr "type" "ishift")
12466    (set_attr "mode" "QI")])
12467
12468 (define_insn "*ashrqi3_1_slp"
12469   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12470         (ashiftrt:QI (match_dup 0)
12471                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12474    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12475   "@
12476    sar{b}\t{%1, %0|%0, %1}
12477    sar{b}\t{%b1, %0|%0, %b1}"
12478   [(set_attr "type" "ishift1")
12479    (set_attr "mode" "QI")])
12480
12481 ;; This pattern can't accept a variable shift count, since shifts by
12482 ;; zero don't affect the flags.  We assume that shifts by constant
12483 ;; zero are optimized away.
12484 (define_insn "*ashrqi3_one_bit_cmp"
12485   [(set (reg FLAGS_REG)
12486         (compare
12487           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12488                        (match_operand:QI 2 "const1_operand" "I"))
12489           (const_int 0)))
12490    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12491         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12492   "(TARGET_SHIFT1 || optimize_size)
12493    && ix86_match_ccmode (insn, CCGOCmode)
12494    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12495   "sar{b}\t%0"
12496   [(set_attr "type" "ishift")
12497    (set (attr "length")
12498      (if_then_else (match_operand 0 "register_operand" "")
12499         (const_string "2")
12500         (const_string "*")))])
12501
12502 (define_insn "*ashrqi3_one_bit_cconly"
12503   [(set (reg FLAGS_REG)
12504         (compare
12505           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12506                        (match_operand:QI 2 "const1_operand" ""))
12507           (const_int 0)))
12508    (clobber (match_scratch:QI 0 "=q"))]
12509   "(TARGET_SHIFT1 || optimize_size)
12510    && ix86_match_ccmode (insn, CCGOCmode)
12511    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12512   "sar{b}\t%0"
12513   [(set_attr "type" "ishift")
12514    (set_attr "length" "2")])
12515
12516 ;; This pattern can't accept a variable shift count, since shifts by
12517 ;; zero don't affect the flags.  We assume that shifts by constant
12518 ;; zero are optimized away.
12519 (define_insn "*ashrqi3_cmp"
12520   [(set (reg FLAGS_REG)
12521         (compare
12522           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12523                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12524           (const_int 0)))
12525    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12526         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12527   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12528    && ix86_match_ccmode (insn, CCGOCmode)
12529    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12530   "sar{b}\t{%2, %0|%0, %2}"
12531   [(set_attr "type" "ishift")
12532    (set_attr "mode" "QI")])
12533
12534 (define_insn "*ashrqi3_cconly"
12535   [(set (reg FLAGS_REG)
12536         (compare
12537           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12538                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12539           (const_int 0)))
12540    (clobber (match_scratch:QI 0 "=q"))]
12541   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12542    && ix86_match_ccmode (insn, CCGOCmode)
12543    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12544   "sar{b}\t{%2, %0|%0, %2}"
12545   [(set_attr "type" "ishift")
12546    (set_attr "mode" "QI")])
12547
12548 \f
12549 ;; Logical shift instructions
12550
12551 ;; See comment above `ashldi3' about how this works.
12552
12553 (define_expand "lshrti3"
12554   [(set (match_operand:TI 0 "register_operand" "")
12555         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12556                      (match_operand:QI 2 "nonmemory_operand" "")))]
12557   "TARGET_64BIT"
12558   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12559
12560 ;; This pattern must be defined before *lshrti3_1 to prevent
12561 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12562
12563 (define_insn "sse2_lshrti3"
12564   [(set (match_operand:TI 0 "register_operand" "=x")
12565         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12566                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12567   "TARGET_SSE2"
12568 {
12569   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12570   return "psrldq\t{%2, %0|%0, %2}";
12571 }
12572   [(set_attr "type" "sseishft")
12573    (set_attr "prefix_data16" "1")
12574    (set_attr "mode" "TI")])
12575
12576 (define_insn "*lshrti3_1"
12577   [(set (match_operand:TI 0 "register_operand" "=r")
12578         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12579                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12580    (clobber (reg:CC FLAGS_REG))]
12581   "TARGET_64BIT"
12582   "#"
12583   [(set_attr "type" "multi")])
12584
12585 (define_peephole2
12586   [(match_scratch:DI 3 "r")
12587    (parallel [(set (match_operand:TI 0 "register_operand" "")
12588                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12589                                 (match_operand:QI 2 "nonmemory_operand" "")))
12590               (clobber (reg:CC FLAGS_REG))])
12591    (match_dup 3)]
12592   "TARGET_64BIT"
12593   [(const_int 0)]
12594   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12595
12596 (define_split
12597   [(set (match_operand:TI 0 "register_operand" "")
12598         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12599                      (match_operand:QI 2 "nonmemory_operand" "")))
12600    (clobber (reg:CC FLAGS_REG))]
12601   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12602                     ? epilogue_completed : reload_completed)"
12603   [(const_int 0)]
12604   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12605
12606 (define_expand "lshrdi3"
12607   [(set (match_operand:DI 0 "shiftdi_operand" "")
12608         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12609                      (match_operand:QI 2 "nonmemory_operand" "")))]
12610   ""
12611   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12612
12613 (define_insn "*lshrdi3_1_one_bit_rex64"
12614   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12615         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12616                      (match_operand:QI 2 "const1_operand" "")))
12617    (clobber (reg:CC FLAGS_REG))]
12618   "TARGET_64BIT
12619    && (TARGET_SHIFT1 || optimize_size)
12620    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12621   "shr{q}\t%0"
12622   [(set_attr "type" "ishift")
12623    (set (attr "length")
12624      (if_then_else (match_operand:DI 0 "register_operand" "")
12625         (const_string "2")
12626         (const_string "*")))])
12627
12628 (define_insn "*lshrdi3_1_rex64"
12629   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12630         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12631                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12632    (clobber (reg:CC FLAGS_REG))]
12633   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12634   "@
12635    shr{q}\t{%2, %0|%0, %2}
12636    shr{q}\t{%b2, %0|%0, %b2}"
12637   [(set_attr "type" "ishift")
12638    (set_attr "mode" "DI")])
12639
12640 ;; This pattern can't accept a variable shift count, since shifts by
12641 ;; zero don't affect the flags.  We assume that shifts by constant
12642 ;; zero are optimized away.
12643 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12644   [(set (reg FLAGS_REG)
12645         (compare
12646           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12647                        (match_operand:QI 2 "const1_operand" ""))
12648           (const_int 0)))
12649    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12650         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12651   "TARGET_64BIT
12652    && (TARGET_SHIFT1 || optimize_size)
12653    && ix86_match_ccmode (insn, CCGOCmode)
12654    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12655   "shr{q}\t%0"
12656   [(set_attr "type" "ishift")
12657    (set (attr "length")
12658      (if_then_else (match_operand:DI 0 "register_operand" "")
12659         (const_string "2")
12660         (const_string "*")))])
12661
12662 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12663   [(set (reg FLAGS_REG)
12664         (compare
12665           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12666                        (match_operand:QI 2 "const1_operand" ""))
12667           (const_int 0)))
12668    (clobber (match_scratch:DI 0 "=r"))]
12669   "TARGET_64BIT
12670    && (TARGET_SHIFT1 || optimize_size)
12671    && ix86_match_ccmode (insn, CCGOCmode)
12672    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12673   "shr{q}\t%0"
12674   [(set_attr "type" "ishift")
12675    (set_attr "length" "2")])
12676
12677 ;; This pattern can't accept a variable shift count, since shifts by
12678 ;; zero don't affect the flags.  We assume that shifts by constant
12679 ;; zero are optimized away.
12680 (define_insn "*lshrdi3_cmp_rex64"
12681   [(set (reg FLAGS_REG)
12682         (compare
12683           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12684                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12685           (const_int 0)))
12686    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12687         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12688   "TARGET_64BIT
12689    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12690    && ix86_match_ccmode (insn, CCGOCmode)
12691    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12692   "shr{q}\t{%2, %0|%0, %2}"
12693   [(set_attr "type" "ishift")
12694    (set_attr "mode" "DI")])
12695
12696 (define_insn "*lshrdi3_cconly_rex64"
12697   [(set (reg FLAGS_REG)
12698         (compare
12699           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12700                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12701           (const_int 0)))
12702    (clobber (match_scratch:DI 0 "=r"))]
12703   "TARGET_64BIT
12704    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12705    && ix86_match_ccmode (insn, CCGOCmode)
12706    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12707   "shr{q}\t{%2, %0|%0, %2}"
12708   [(set_attr "type" "ishift")
12709    (set_attr "mode" "DI")])
12710
12711 (define_insn "*lshrdi3_1"
12712   [(set (match_operand:DI 0 "register_operand" "=r")
12713         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12714                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12715    (clobber (reg:CC FLAGS_REG))]
12716   "!TARGET_64BIT"
12717   "#"
12718   [(set_attr "type" "multi")])
12719
12720 ;; By default we don't ask for a scratch register, because when DImode
12721 ;; values are manipulated, registers are already at a premium.  But if
12722 ;; we have one handy, we won't turn it away.
12723 (define_peephole2
12724   [(match_scratch:SI 3 "r")
12725    (parallel [(set (match_operand:DI 0 "register_operand" "")
12726                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12727                                 (match_operand:QI 2 "nonmemory_operand" "")))
12728               (clobber (reg:CC FLAGS_REG))])
12729    (match_dup 3)]
12730   "!TARGET_64BIT && TARGET_CMOVE"
12731   [(const_int 0)]
12732   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12733
12734 (define_split
12735   [(set (match_operand:DI 0 "register_operand" "")
12736         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12737                      (match_operand:QI 2 "nonmemory_operand" "")))
12738    (clobber (reg:CC FLAGS_REG))]
12739   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12740                      ? epilogue_completed : reload_completed)"
12741   [(const_int 0)]
12742   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12743
12744 (define_expand "lshrsi3"
12745   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12746         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12747                      (match_operand:QI 2 "nonmemory_operand" "")))]
12748   ""
12749   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12750
12751 (define_insn "*lshrsi3_1_one_bit"
12752   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12753         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12754                      (match_operand:QI 2 "const1_operand" "")))
12755    (clobber (reg:CC FLAGS_REG))]
12756   "(TARGET_SHIFT1 || optimize_size)
12757    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12758   "shr{l}\t%0"
12759   [(set_attr "type" "ishift")
12760    (set (attr "length")
12761      (if_then_else (match_operand:SI 0 "register_operand" "")
12762         (const_string "2")
12763         (const_string "*")))])
12764
12765 (define_insn "*lshrsi3_1_one_bit_zext"
12766   [(set (match_operand:DI 0 "register_operand" "=r")
12767         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12768                      (match_operand:QI 2 "const1_operand" "")))
12769    (clobber (reg:CC FLAGS_REG))]
12770   "TARGET_64BIT
12771    && (TARGET_SHIFT1 || optimize_size)
12772    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12773   "shr{l}\t%k0"
12774   [(set_attr "type" "ishift")
12775    (set_attr "length" "2")])
12776
12777 (define_insn "*lshrsi3_1"
12778   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12779         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12780                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12781    (clobber (reg:CC FLAGS_REG))]
12782   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12783   "@
12784    shr{l}\t{%2, %0|%0, %2}
12785    shr{l}\t{%b2, %0|%0, %b2}"
12786   [(set_attr "type" "ishift")
12787    (set_attr "mode" "SI")])
12788
12789 (define_insn "*lshrsi3_1_zext"
12790   [(set (match_operand:DI 0 "register_operand" "=r,r")
12791         (zero_extend:DI
12792           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12793                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12794    (clobber (reg:CC FLAGS_REG))]
12795   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12796   "@
12797    shr{l}\t{%2, %k0|%k0, %2}
12798    shr{l}\t{%b2, %k0|%k0, %b2}"
12799   [(set_attr "type" "ishift")
12800    (set_attr "mode" "SI")])
12801
12802 ;; This pattern can't accept a variable shift count, since shifts by
12803 ;; zero don't affect the flags.  We assume that shifts by constant
12804 ;; zero are optimized away.
12805 (define_insn "*lshrsi3_one_bit_cmp"
12806   [(set (reg FLAGS_REG)
12807         (compare
12808           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12809                        (match_operand:QI 2 "const1_operand" ""))
12810           (const_int 0)))
12811    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12812         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12813   "(TARGET_SHIFT1 || optimize_size)
12814    && ix86_match_ccmode (insn, CCGOCmode)
12815    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12816   "shr{l}\t%0"
12817   [(set_attr "type" "ishift")
12818    (set (attr "length")
12819      (if_then_else (match_operand:SI 0 "register_operand" "")
12820         (const_string "2")
12821         (const_string "*")))])
12822
12823 (define_insn "*lshrsi3_one_bit_cconly"
12824   [(set (reg FLAGS_REG)
12825         (compare
12826           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12827                        (match_operand:QI 2 "const1_operand" ""))
12828           (const_int 0)))
12829    (clobber (match_scratch:SI 0 "=r"))]
12830   "(TARGET_SHIFT1 || optimize_size)
12831    && ix86_match_ccmode (insn, CCGOCmode)
12832    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12833   "shr{l}\t%0"
12834   [(set_attr "type" "ishift")
12835    (set_attr "length" "2")])
12836
12837 (define_insn "*lshrsi3_cmp_one_bit_zext"
12838   [(set (reg FLAGS_REG)
12839         (compare
12840           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12841                        (match_operand:QI 2 "const1_operand" ""))
12842           (const_int 0)))
12843    (set (match_operand:DI 0 "register_operand" "=r")
12844         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12845   "TARGET_64BIT
12846    && (TARGET_SHIFT1 || optimize_size)
12847    && ix86_match_ccmode (insn, CCGOCmode)
12848    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12849   "shr{l}\t%k0"
12850   [(set_attr "type" "ishift")
12851    (set_attr "length" "2")])
12852
12853 ;; This pattern can't accept a variable shift count, since shifts by
12854 ;; zero don't affect the flags.  We assume that shifts by constant
12855 ;; zero are optimized away.
12856 (define_insn "*lshrsi3_cmp"
12857   [(set (reg FLAGS_REG)
12858         (compare
12859           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12860                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12861           (const_int 0)))
12862    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12863         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12864   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12865    && ix86_match_ccmode (insn, CCGOCmode)
12866    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12867   "shr{l}\t{%2, %0|%0, %2}"
12868   [(set_attr "type" "ishift")
12869    (set_attr "mode" "SI")])
12870
12871 (define_insn "*lshrsi3_cconly"
12872   [(set (reg FLAGS_REG)
12873       (compare
12874         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12875                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12876         (const_int 0)))
12877    (clobber (match_scratch:SI 0 "=r"))]
12878   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12879    && ix86_match_ccmode (insn, CCGOCmode)
12880    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12881   "shr{l}\t{%2, %0|%0, %2}"
12882   [(set_attr "type" "ishift")
12883    (set_attr "mode" "SI")])
12884
12885 (define_insn "*lshrsi3_cmp_zext"
12886   [(set (reg FLAGS_REG)
12887         (compare
12888           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12889                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12890           (const_int 0)))
12891    (set (match_operand:DI 0 "register_operand" "=r")
12892         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12893   "TARGET_64BIT
12894    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12895    && ix86_match_ccmode (insn, CCGOCmode)
12896    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897   "shr{l}\t{%2, %k0|%k0, %2}"
12898   [(set_attr "type" "ishift")
12899    (set_attr "mode" "SI")])
12900
12901 (define_expand "lshrhi3"
12902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12903         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12904                      (match_operand:QI 2 "nonmemory_operand" "")))]
12905   "TARGET_HIMODE_MATH"
12906   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12907
12908 (define_insn "*lshrhi3_1_one_bit"
12909   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12910         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12911                      (match_operand:QI 2 "const1_operand" "")))
12912    (clobber (reg:CC FLAGS_REG))]
12913   "(TARGET_SHIFT1 || optimize_size)
12914    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12915   "shr{w}\t%0"
12916   [(set_attr "type" "ishift")
12917    (set (attr "length")
12918      (if_then_else (match_operand 0 "register_operand" "")
12919         (const_string "2")
12920         (const_string "*")))])
12921
12922 (define_insn "*lshrhi3_1"
12923   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12924         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12925                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926    (clobber (reg:CC FLAGS_REG))]
12927   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12928   "@
12929    shr{w}\t{%2, %0|%0, %2}
12930    shr{w}\t{%b2, %0|%0, %b2}"
12931   [(set_attr "type" "ishift")
12932    (set_attr "mode" "HI")])
12933
12934 ;; This pattern can't accept a variable shift count, since shifts by
12935 ;; zero don't affect the flags.  We assume that shifts by constant
12936 ;; zero are optimized away.
12937 (define_insn "*lshrhi3_one_bit_cmp"
12938   [(set (reg FLAGS_REG)
12939         (compare
12940           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12941                        (match_operand:QI 2 "const1_operand" ""))
12942           (const_int 0)))
12943    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12944         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12945   "(TARGET_SHIFT1 || optimize_size)
12946    && ix86_match_ccmode (insn, CCGOCmode)
12947    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12948   "shr{w}\t%0"
12949   [(set_attr "type" "ishift")
12950    (set (attr "length")
12951      (if_then_else (match_operand:SI 0 "register_operand" "")
12952         (const_string "2")
12953         (const_string "*")))])
12954
12955 (define_insn "*lshrhi3_one_bit_cconly"
12956   [(set (reg FLAGS_REG)
12957         (compare
12958           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12959                        (match_operand:QI 2 "const1_operand" ""))
12960           (const_int 0)))
12961    (clobber (match_scratch:HI 0 "=r"))]
12962   "(TARGET_SHIFT1 || optimize_size)
12963    && ix86_match_ccmode (insn, CCGOCmode)
12964    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12965   "shr{w}\t%0"
12966   [(set_attr "type" "ishift")
12967    (set_attr "length" "2")])
12968
12969 ;; This pattern can't accept a variable shift count, since shifts by
12970 ;; zero don't affect the flags.  We assume that shifts by constant
12971 ;; zero are optimized away.
12972 (define_insn "*lshrhi3_cmp"
12973   [(set (reg FLAGS_REG)
12974         (compare
12975           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12976                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12977           (const_int 0)))
12978    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12979         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12980   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12981    && ix86_match_ccmode (insn, CCGOCmode)
12982    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12983   "shr{w}\t{%2, %0|%0, %2}"
12984   [(set_attr "type" "ishift")
12985    (set_attr "mode" "HI")])
12986
12987 (define_insn "*lshrhi3_cconly"
12988   [(set (reg FLAGS_REG)
12989         (compare
12990           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12991                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12992           (const_int 0)))
12993    (clobber (match_scratch:HI 0 "=r"))]
12994   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12995    && ix86_match_ccmode (insn, CCGOCmode)
12996    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12997   "shr{w}\t{%2, %0|%0, %2}"
12998   [(set_attr "type" "ishift")
12999    (set_attr "mode" "HI")])
13000
13001 (define_expand "lshrqi3"
13002   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004                      (match_operand:QI 2 "nonmemory_operand" "")))]
13005   "TARGET_QIMODE_MATH"
13006   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13007
13008 (define_insn "*lshrqi3_1_one_bit"
13009   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13010         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13011                      (match_operand:QI 2 "const1_operand" "")))
13012    (clobber (reg:CC FLAGS_REG))]
13013   "(TARGET_SHIFT1 || optimize_size)
13014    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13015   "shr{b}\t%0"
13016   [(set_attr "type" "ishift")
13017    (set (attr "length")
13018      (if_then_else (match_operand 0 "register_operand" "")
13019         (const_string "2")
13020         (const_string "*")))])
13021
13022 (define_insn "*lshrqi3_1_one_bit_slp"
13023   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13024         (lshiftrt:QI (match_dup 0)
13025                      (match_operand:QI 1 "const1_operand" "")))
13026    (clobber (reg:CC FLAGS_REG))]
13027   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13028    && (TARGET_SHIFT1 || optimize_size)"
13029   "shr{b}\t%0"
13030   [(set_attr "type" "ishift1")
13031    (set (attr "length")
13032      (if_then_else (match_operand 0 "register_operand" "")
13033         (const_string "2")
13034         (const_string "*")))])
13035
13036 (define_insn "*lshrqi3_1"
13037   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13038         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13039                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13040    (clobber (reg:CC FLAGS_REG))]
13041   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13042   "@
13043    shr{b}\t{%2, %0|%0, %2}
13044    shr{b}\t{%b2, %0|%0, %b2}"
13045   [(set_attr "type" "ishift")
13046    (set_attr "mode" "QI")])
13047
13048 (define_insn "*lshrqi3_1_slp"
13049   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13050         (lshiftrt:QI (match_dup 0)
13051                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13052    (clobber (reg:CC FLAGS_REG))]
13053   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13054    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13055   "@
13056    shr{b}\t{%1, %0|%0, %1}
13057    shr{b}\t{%b1, %0|%0, %b1}"
13058   [(set_attr "type" "ishift1")
13059    (set_attr "mode" "QI")])
13060
13061 ;; This pattern can't accept a variable shift count, since shifts by
13062 ;; zero don't affect the flags.  We assume that shifts by constant
13063 ;; zero are optimized away.
13064 (define_insn "*lshrqi2_one_bit_cmp"
13065   [(set (reg FLAGS_REG)
13066         (compare
13067           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13068                        (match_operand:QI 2 "const1_operand" ""))
13069           (const_int 0)))
13070    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13071         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13072   "(TARGET_SHIFT1 || optimize_size)
13073    && ix86_match_ccmode (insn, CCGOCmode)
13074    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13075   "shr{b}\t%0"
13076   [(set_attr "type" "ishift")
13077    (set (attr "length")
13078      (if_then_else (match_operand:SI 0 "register_operand" "")
13079         (const_string "2")
13080         (const_string "*")))])
13081
13082 (define_insn "*lshrqi2_one_bit_cconly"
13083   [(set (reg FLAGS_REG)
13084         (compare
13085           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13086                        (match_operand:QI 2 "const1_operand" ""))
13087           (const_int 0)))
13088    (clobber (match_scratch:QI 0 "=q"))]
13089   "(TARGET_SHIFT1 || optimize_size)
13090    && ix86_match_ccmode (insn, CCGOCmode)
13091    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13092   "shr{b}\t%0"
13093   [(set_attr "type" "ishift")
13094    (set_attr "length" "2")])
13095
13096 ;; This pattern can't accept a variable shift count, since shifts by
13097 ;; zero don't affect the flags.  We assume that shifts by constant
13098 ;; zero are optimized away.
13099 (define_insn "*lshrqi2_cmp"
13100   [(set (reg FLAGS_REG)
13101         (compare
13102           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13103                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13104           (const_int 0)))
13105    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13106         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13107   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13108    && ix86_match_ccmode (insn, CCGOCmode)
13109    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13110   "shr{b}\t{%2, %0|%0, %2}"
13111   [(set_attr "type" "ishift")
13112    (set_attr "mode" "QI")])
13113
13114 (define_insn "*lshrqi2_cconly"
13115   [(set (reg FLAGS_REG)
13116         (compare
13117           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13118                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13119           (const_int 0)))
13120    (clobber (match_scratch:QI 0 "=q"))]
13121   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13122    && ix86_match_ccmode (insn, CCGOCmode)
13123    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13124   "shr{b}\t{%2, %0|%0, %2}"
13125   [(set_attr "type" "ishift")
13126    (set_attr "mode" "QI")])
13127 \f
13128 ;; Rotate instructions
13129
13130 (define_expand "rotldi3"
13131   [(set (match_operand:DI 0 "shiftdi_operand" "")
13132         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13133                    (match_operand:QI 2 "nonmemory_operand" "")))]
13134  ""
13135 {
13136   if (TARGET_64BIT)
13137     {
13138       ix86_expand_binary_operator (ROTATE, DImode, operands);
13139       DONE;
13140     }
13141   if (!const_1_to_31_operand (operands[2], VOIDmode))
13142     FAIL;
13143   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13144   DONE;
13145 })
13146
13147 ;; Implement rotation using two double-precision shift instructions
13148 ;; and a scratch register.
13149 (define_insn_and_split "ix86_rotldi3"
13150  [(set (match_operand:DI 0 "register_operand" "=r")
13151        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13152                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13153   (clobber (reg:CC FLAGS_REG))
13154   (clobber (match_scratch:SI 3 "=&r"))]
13155  "!TARGET_64BIT"
13156  ""
13157  "&& reload_completed"
13158  [(set (match_dup 3) (match_dup 4))
13159   (parallel
13160    [(set (match_dup 4)
13161          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13162                  (lshiftrt:SI (match_dup 5)
13163                               (minus:QI (const_int 32) (match_dup 2)))))
13164     (clobber (reg:CC FLAGS_REG))])
13165   (parallel
13166    [(set (match_dup 5)
13167          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13168                  (lshiftrt:SI (match_dup 3)
13169                               (minus:QI (const_int 32) (match_dup 2)))))
13170     (clobber (reg:CC FLAGS_REG))])]
13171  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13172
13173 (define_insn "*rotlsi3_1_one_bit_rex64"
13174   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13175         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13176                    (match_operand:QI 2 "const1_operand" "")))
13177    (clobber (reg:CC FLAGS_REG))]
13178   "TARGET_64BIT
13179    && (TARGET_SHIFT1 || optimize_size)
13180    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13181   "rol{q}\t%0"
13182   [(set_attr "type" "rotate")
13183    (set (attr "length")
13184      (if_then_else (match_operand:DI 0 "register_operand" "")
13185         (const_string "2")
13186         (const_string "*")))])
13187
13188 (define_insn "*rotldi3_1_rex64"
13189   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13190         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13191                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13192    (clobber (reg:CC FLAGS_REG))]
13193   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13194   "@
13195    rol{q}\t{%2, %0|%0, %2}
13196    rol{q}\t{%b2, %0|%0, %b2}"
13197   [(set_attr "type" "rotate")
13198    (set_attr "mode" "DI")])
13199
13200 (define_expand "rotlsi3"
13201   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13202         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13203                    (match_operand:QI 2 "nonmemory_operand" "")))]
13204   ""
13205   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13206
13207 (define_insn "*rotlsi3_1_one_bit"
13208   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13209         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13210                    (match_operand:QI 2 "const1_operand" "")))
13211    (clobber (reg:CC FLAGS_REG))]
13212   "(TARGET_SHIFT1 || optimize_size)
13213    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13214   "rol{l}\t%0"
13215   [(set_attr "type" "rotate")
13216    (set (attr "length")
13217      (if_then_else (match_operand:SI 0 "register_operand" "")
13218         (const_string "2")
13219         (const_string "*")))])
13220
13221 (define_insn "*rotlsi3_1_one_bit_zext"
13222   [(set (match_operand:DI 0 "register_operand" "=r")
13223         (zero_extend:DI
13224           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13225                      (match_operand:QI 2 "const1_operand" ""))))
13226    (clobber (reg:CC FLAGS_REG))]
13227   "TARGET_64BIT
13228    && (TARGET_SHIFT1 || optimize_size)
13229    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13230   "rol{l}\t%k0"
13231   [(set_attr "type" "rotate")
13232    (set_attr "length" "2")])
13233
13234 (define_insn "*rotlsi3_1"
13235   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13236         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13237                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13238    (clobber (reg:CC FLAGS_REG))]
13239   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13240   "@
13241    rol{l}\t{%2, %0|%0, %2}
13242    rol{l}\t{%b2, %0|%0, %b2}"
13243   [(set_attr "type" "rotate")
13244    (set_attr "mode" "SI")])
13245
13246 (define_insn "*rotlsi3_1_zext"
13247   [(set (match_operand:DI 0 "register_operand" "=r,r")
13248         (zero_extend:DI
13249           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13250                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13251    (clobber (reg:CC FLAGS_REG))]
13252   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13253   "@
13254    rol{l}\t{%2, %k0|%k0, %2}
13255    rol{l}\t{%b2, %k0|%k0, %b2}"
13256   [(set_attr "type" "rotate")
13257    (set_attr "mode" "SI")])
13258
13259 (define_expand "rotlhi3"
13260   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13261         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13262                    (match_operand:QI 2 "nonmemory_operand" "")))]
13263   "TARGET_HIMODE_MATH"
13264   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13265
13266 (define_insn "*rotlhi3_1_one_bit"
13267   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13268         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13269                    (match_operand:QI 2 "const1_operand" "")))
13270    (clobber (reg:CC FLAGS_REG))]
13271   "(TARGET_SHIFT1 || optimize_size)
13272    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13273   "rol{w}\t%0"
13274   [(set_attr "type" "rotate")
13275    (set (attr "length")
13276      (if_then_else (match_operand 0 "register_operand" "")
13277         (const_string "2")
13278         (const_string "*")))])
13279
13280 (define_insn "*rotlhi3_1"
13281   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13282         (rotate:HI (match_operand:HI 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 (ROTATE, HImode, operands)"
13286   "@
13287    rol{w}\t{%2, %0|%0, %2}
13288    rol{w}\t{%b2, %0|%0, %b2}"
13289   [(set_attr "type" "rotate")
13290    (set_attr "mode" "HI")])
13291
13292 (define_split
13293  [(set (match_operand:HI 0 "register_operand" "")
13294        (rotate:HI (match_dup 0) (const_int 8)))
13295   (clobber (reg:CC FLAGS_REG))]
13296  "reload_completed"
13297  [(parallel [(set (strict_low_part (match_dup 0))
13298                   (bswap:HI (match_dup 0)))
13299              (clobber (reg:CC FLAGS_REG))])]
13300  "")
13301
13302 (define_expand "rotlqi3"
13303   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13304         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13305                    (match_operand:QI 2 "nonmemory_operand" "")))]
13306   "TARGET_QIMODE_MATH"
13307   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13308
13309 (define_insn "*rotlqi3_1_one_bit_slp"
13310   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13311         (rotate:QI (match_dup 0)
13312                    (match_operand:QI 1 "const1_operand" "")))
13313    (clobber (reg:CC FLAGS_REG))]
13314   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13315    && (TARGET_SHIFT1 || optimize_size)"
13316   "rol{b}\t%0"
13317   [(set_attr "type" "rotate1")
13318    (set (attr "length")
13319      (if_then_else (match_operand 0 "register_operand" "")
13320         (const_string "2")
13321         (const_string "*")))])
13322
13323 (define_insn "*rotlqi3_1_one_bit"
13324   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13325         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13326                    (match_operand:QI 2 "const1_operand" "")))
13327    (clobber (reg:CC FLAGS_REG))]
13328   "(TARGET_SHIFT1 || optimize_size)
13329    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13330   "rol{b}\t%0"
13331   [(set_attr "type" "rotate")
13332    (set (attr "length")
13333      (if_then_else (match_operand 0 "register_operand" "")
13334         (const_string "2")
13335         (const_string "*")))])
13336
13337 (define_insn "*rotlqi3_1_slp"
13338   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13339         (rotate:QI (match_dup 0)
13340                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13341    (clobber (reg:CC FLAGS_REG))]
13342   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13343    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13344   "@
13345    rol{b}\t{%1, %0|%0, %1}
13346    rol{b}\t{%b1, %0|%0, %b1}"
13347   [(set_attr "type" "rotate1")
13348    (set_attr "mode" "QI")])
13349
13350 (define_insn "*rotlqi3_1"
13351   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13352         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13353                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13354    (clobber (reg:CC FLAGS_REG))]
13355   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13356   "@
13357    rol{b}\t{%2, %0|%0, %2}
13358    rol{b}\t{%b2, %0|%0, %b2}"
13359   [(set_attr "type" "rotate")
13360    (set_attr "mode" "QI")])
13361
13362 (define_expand "rotrdi3"
13363   [(set (match_operand:DI 0 "shiftdi_operand" "")
13364         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13365                    (match_operand:QI 2 "nonmemory_operand" "")))]
13366  ""
13367 {
13368   if (TARGET_64BIT)
13369     {
13370       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13371       DONE;
13372     }
13373   if (!const_1_to_31_operand (operands[2], VOIDmode))
13374     FAIL;
13375   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13376   DONE;
13377 })
13378
13379 ;; Implement rotation using two double-precision shift instructions
13380 ;; and a scratch register.
13381 (define_insn_and_split "ix86_rotrdi3"
13382  [(set (match_operand:DI 0 "register_operand" "=r")
13383        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13384                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13385   (clobber (reg:CC FLAGS_REG))
13386   (clobber (match_scratch:SI 3 "=&r"))]
13387  "!TARGET_64BIT"
13388  ""
13389  "&& reload_completed"
13390  [(set (match_dup 3) (match_dup 4))
13391   (parallel
13392    [(set (match_dup 4)
13393          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13394                  (ashift:SI (match_dup 5)
13395                             (minus:QI (const_int 32) (match_dup 2)))))
13396     (clobber (reg:CC FLAGS_REG))])
13397   (parallel
13398    [(set (match_dup 5)
13399          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13400                  (ashift:SI (match_dup 3)
13401                             (minus:QI (const_int 32) (match_dup 2)))))
13402     (clobber (reg:CC FLAGS_REG))])]
13403  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13404
13405 (define_insn "*rotrdi3_1_one_bit_rex64"
13406   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13407         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13408                      (match_operand:QI 2 "const1_operand" "")))
13409    (clobber (reg:CC FLAGS_REG))]
13410   "TARGET_64BIT
13411    && (TARGET_SHIFT1 || optimize_size)
13412    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13413   "ror{q}\t%0"
13414   [(set_attr "type" "rotate")
13415    (set (attr "length")
13416      (if_then_else (match_operand:DI 0 "register_operand" "")
13417         (const_string "2")
13418         (const_string "*")))])
13419
13420 (define_insn "*rotrdi3_1_rex64"
13421   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13422         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13423                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13424    (clobber (reg:CC FLAGS_REG))]
13425   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13426   "@
13427    ror{q}\t{%2, %0|%0, %2}
13428    ror{q}\t{%b2, %0|%0, %b2}"
13429   [(set_attr "type" "rotate")
13430    (set_attr "mode" "DI")])
13431
13432 (define_expand "rotrsi3"
13433   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13434         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13435                      (match_operand:QI 2 "nonmemory_operand" "")))]
13436   ""
13437   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13438
13439 (define_insn "*rotrsi3_1_one_bit"
13440   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13441         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13442                      (match_operand:QI 2 "const1_operand" "")))
13443    (clobber (reg:CC FLAGS_REG))]
13444   "(TARGET_SHIFT1 || optimize_size)
13445    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13446   "ror{l}\t%0"
13447   [(set_attr "type" "rotate")
13448    (set (attr "length")
13449      (if_then_else (match_operand:SI 0 "register_operand" "")
13450         (const_string "2")
13451         (const_string "*")))])
13452
13453 (define_insn "*rotrsi3_1_one_bit_zext"
13454   [(set (match_operand:DI 0 "register_operand" "=r")
13455         (zero_extend:DI
13456           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13457                        (match_operand:QI 2 "const1_operand" ""))))
13458    (clobber (reg:CC FLAGS_REG))]
13459   "TARGET_64BIT
13460    && (TARGET_SHIFT1 || optimize_size)
13461    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13462   "ror{l}\t%k0"
13463   [(set_attr "type" "rotate")
13464    (set (attr "length")
13465      (if_then_else (match_operand:SI 0 "register_operand" "")
13466         (const_string "2")
13467         (const_string "*")))])
13468
13469 (define_insn "*rotrsi3_1"
13470   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13471         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13472                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13473    (clobber (reg:CC FLAGS_REG))]
13474   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13475   "@
13476    ror{l}\t{%2, %0|%0, %2}
13477    ror{l}\t{%b2, %0|%0, %b2}"
13478   [(set_attr "type" "rotate")
13479    (set_attr "mode" "SI")])
13480
13481 (define_insn "*rotrsi3_1_zext"
13482   [(set (match_operand:DI 0 "register_operand" "=r,r")
13483         (zero_extend:DI
13484           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13485                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13486    (clobber (reg:CC FLAGS_REG))]
13487   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13488   "@
13489    ror{l}\t{%2, %k0|%k0, %2}
13490    ror{l}\t{%b2, %k0|%k0, %b2}"
13491   [(set_attr "type" "rotate")
13492    (set_attr "mode" "SI")])
13493
13494 (define_expand "rotrhi3"
13495   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13496         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13497                      (match_operand:QI 2 "nonmemory_operand" "")))]
13498   "TARGET_HIMODE_MATH"
13499   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13500
13501 (define_insn "*rotrhi3_one_bit"
13502   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13503         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13504                      (match_operand:QI 2 "const1_operand" "")))
13505    (clobber (reg:CC FLAGS_REG))]
13506   "(TARGET_SHIFT1 || optimize_size)
13507    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13508   "ror{w}\t%0"
13509   [(set_attr "type" "rotate")
13510    (set (attr "length")
13511      (if_then_else (match_operand 0 "register_operand" "")
13512         (const_string "2")
13513         (const_string "*")))])
13514
13515 (define_insn "*rotrhi3_1"
13516   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13517         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13518                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13519    (clobber (reg:CC FLAGS_REG))]
13520   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13521   "@
13522    ror{w}\t{%2, %0|%0, %2}
13523    ror{w}\t{%b2, %0|%0, %b2}"
13524   [(set_attr "type" "rotate")
13525    (set_attr "mode" "HI")])
13526
13527 (define_split
13528  [(set (match_operand:HI 0 "register_operand" "")
13529        (rotatert:HI (match_dup 0) (const_int 8)))
13530   (clobber (reg:CC FLAGS_REG))]
13531  "reload_completed"
13532  [(parallel [(set (strict_low_part (match_dup 0))
13533                   (bswap:HI (match_dup 0)))
13534              (clobber (reg:CC FLAGS_REG))])]
13535  "")
13536
13537 (define_expand "rotrqi3"
13538   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13539         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13540                      (match_operand:QI 2 "nonmemory_operand" "")))]
13541   "TARGET_QIMODE_MATH"
13542   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13543
13544 (define_insn "*rotrqi3_1_one_bit"
13545   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13546         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13547                      (match_operand:QI 2 "const1_operand" "")))
13548    (clobber (reg:CC FLAGS_REG))]
13549   "(TARGET_SHIFT1 || optimize_size)
13550    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13551   "ror{b}\t%0"
13552   [(set_attr "type" "rotate")
13553    (set (attr "length")
13554      (if_then_else (match_operand 0 "register_operand" "")
13555         (const_string "2")
13556         (const_string "*")))])
13557
13558 (define_insn "*rotrqi3_1_one_bit_slp"
13559   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13560         (rotatert:QI (match_dup 0)
13561                      (match_operand:QI 1 "const1_operand" "")))
13562    (clobber (reg:CC FLAGS_REG))]
13563   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13564    && (TARGET_SHIFT1 || optimize_size)"
13565   "ror{b}\t%0"
13566   [(set_attr "type" "rotate1")
13567    (set (attr "length")
13568      (if_then_else (match_operand 0 "register_operand" "")
13569         (const_string "2")
13570         (const_string "*")))])
13571
13572 (define_insn "*rotrqi3_1"
13573   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13574         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13575                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13576    (clobber (reg:CC FLAGS_REG))]
13577   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13578   "@
13579    ror{b}\t{%2, %0|%0, %2}
13580    ror{b}\t{%b2, %0|%0, %b2}"
13581   [(set_attr "type" "rotate")
13582    (set_attr "mode" "QI")])
13583
13584 (define_insn "*rotrqi3_1_slp"
13585   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13586         (rotatert:QI (match_dup 0)
13587                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13588    (clobber (reg:CC FLAGS_REG))]
13589   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13590    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13591   "@
13592    ror{b}\t{%1, %0|%0, %1}
13593    ror{b}\t{%b1, %0|%0, %b1}"
13594   [(set_attr "type" "rotate1")
13595    (set_attr "mode" "QI")])
13596 \f
13597 ;; Bit set / bit test instructions
13598
13599 (define_expand "extv"
13600   [(set (match_operand:SI 0 "register_operand" "")
13601         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13602                          (match_operand:SI 2 "const8_operand" "")
13603                          (match_operand:SI 3 "const8_operand" "")))]
13604   ""
13605 {
13606   /* Handle extractions from %ah et al.  */
13607   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13608     FAIL;
13609
13610   /* From mips.md: extract_bit_field doesn't verify that our source
13611      matches the predicate, so check it again here.  */
13612   if (! ext_register_operand (operands[1], VOIDmode))
13613     FAIL;
13614 })
13615
13616 (define_expand "extzv"
13617   [(set (match_operand:SI 0 "register_operand" "")
13618         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13619                          (match_operand:SI 2 "const8_operand" "")
13620                          (match_operand:SI 3 "const8_operand" "")))]
13621   ""
13622 {
13623   /* Handle extractions from %ah et al.  */
13624   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13625     FAIL;
13626
13627   /* From mips.md: extract_bit_field doesn't verify that our source
13628      matches the predicate, so check it again here.  */
13629   if (! ext_register_operand (operands[1], VOIDmode))
13630     FAIL;
13631 })
13632
13633 (define_expand "insv"
13634   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13635                       (match_operand 1 "const8_operand" "")
13636                       (match_operand 2 "const8_operand" ""))
13637         (match_operand 3 "register_operand" ""))]
13638   ""
13639 {
13640   /* Handle insertions to %ah et al.  */
13641   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13642     FAIL;
13643
13644   /* From mips.md: insert_bit_field doesn't verify that our source
13645      matches the predicate, so check it again here.  */
13646   if (! ext_register_operand (operands[0], VOIDmode))
13647     FAIL;
13648
13649   if (TARGET_64BIT)
13650     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13651   else
13652     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13653
13654   DONE;
13655 })
13656
13657 ;; %%% bts, btr, btc, bt.
13658 ;; In general these instructions are *slow* when applied to memory,
13659 ;; since they enforce atomic operation.  When applied to registers,
13660 ;; it depends on the cpu implementation.  They're never faster than
13661 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13662 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13663 ;; within the instruction itself, so operating on bits in the high
13664 ;; 32-bits of a register becomes easier.
13665 ;;
13666 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13667 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13668 ;; negdf respectively, so they can never be disabled entirely.
13669
13670 (define_insn "*btsq"
13671   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13672                          (const_int 1)
13673                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13674         (const_int 1))
13675    (clobber (reg:CC FLAGS_REG))]
13676   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13677   "bts{q}\t{%1, %0|%0, %1}"
13678   [(set_attr "type" "alu1")])
13679
13680 (define_insn "*btrq"
13681   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13682                          (const_int 1)
13683                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13684         (const_int 0))
13685    (clobber (reg:CC FLAGS_REG))]
13686   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13687   "btr{q}\t{%1, %0|%0, %1}"
13688   [(set_attr "type" "alu1")])
13689
13690 (define_insn "*btcq"
13691   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13692                          (const_int 1)
13693                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13694         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13695    (clobber (reg:CC FLAGS_REG))]
13696   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13697   "btc{q}\t{%1, %0|%0, %1}"
13698   [(set_attr "type" "alu1")])
13699
13700 ;; Allow Nocona to avoid these instructions if a register is available.
13701
13702 (define_peephole2
13703   [(match_scratch:DI 2 "r")
13704    (parallel [(set (zero_extract:DI
13705                      (match_operand:DI 0 "register_operand" "")
13706                      (const_int 1)
13707                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13708                    (const_int 1))
13709               (clobber (reg:CC FLAGS_REG))])]
13710   "TARGET_64BIT && !TARGET_USE_BT"
13711   [(const_int 0)]
13712 {
13713   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13714   rtx op1;
13715
13716   if (HOST_BITS_PER_WIDE_INT >= 64)
13717     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13718   else if (i < HOST_BITS_PER_WIDE_INT)
13719     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13720   else
13721     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13722
13723   op1 = immed_double_const (lo, hi, DImode);
13724   if (i >= 31)
13725     {
13726       emit_move_insn (operands[2], op1);
13727       op1 = operands[2];
13728     }
13729
13730   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13731   DONE;
13732 })
13733
13734 (define_peephole2
13735   [(match_scratch:DI 2 "r")
13736    (parallel [(set (zero_extract:DI
13737                      (match_operand:DI 0 "register_operand" "")
13738                      (const_int 1)
13739                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13740                    (const_int 0))
13741               (clobber (reg:CC FLAGS_REG))])]
13742   "TARGET_64BIT && !TARGET_USE_BT"
13743   [(const_int 0)]
13744 {
13745   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13746   rtx op1;
13747
13748   if (HOST_BITS_PER_WIDE_INT >= 64)
13749     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13750   else if (i < HOST_BITS_PER_WIDE_INT)
13751     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13752   else
13753     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13754
13755   op1 = immed_double_const (~lo, ~hi, DImode);
13756   if (i >= 32)
13757     {
13758       emit_move_insn (operands[2], op1);
13759       op1 = operands[2];
13760     }
13761
13762   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13763   DONE;
13764 })
13765
13766 (define_peephole2
13767   [(match_scratch:DI 2 "r")
13768    (parallel [(set (zero_extract:DI
13769                      (match_operand:DI 0 "register_operand" "")
13770                      (const_int 1)
13771                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13772               (not:DI (zero_extract:DI
13773                         (match_dup 0) (const_int 1) (match_dup 1))))
13774               (clobber (reg:CC FLAGS_REG))])]
13775   "TARGET_64BIT && !TARGET_USE_BT"
13776   [(const_int 0)]
13777 {
13778   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13779   rtx op1;
13780
13781   if (HOST_BITS_PER_WIDE_INT >= 64)
13782     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13783   else if (i < HOST_BITS_PER_WIDE_INT)
13784     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13785   else
13786     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13787
13788   op1 = immed_double_const (lo, hi, DImode);
13789   if (i >= 31)
13790     {
13791       emit_move_insn (operands[2], op1);
13792       op1 = operands[2];
13793     }
13794
13795   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13796   DONE;
13797 })
13798
13799 (define_insn "*btdi_rex64"
13800   [(set (reg:CCC FLAGS_REG)
13801         (compare:CCC
13802           (zero_extract:DI
13803             (match_operand:DI 0 "register_operand" "r")
13804             (const_int 1)
13805             (match_operand:DI 1 "nonmemory_operand" "rN"))
13806           (const_int 0)))]
13807   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13808   "bt{q}\t{%1, %0|%0, %1}"
13809   [(set_attr "type" "alu1")])
13810
13811 (define_insn "*btsi"
13812   [(set (reg:CCC FLAGS_REG)
13813         (compare:CCC
13814           (zero_extract:SI
13815             (match_operand:SI 0 "register_operand" "r")
13816             (const_int 1)
13817             (match_operand:SI 1 "nonmemory_operand" "rN"))
13818           (const_int 0)))]
13819   "TARGET_USE_BT || optimize_size"
13820   "bt{l}\t{%1, %0|%0, %1}"
13821   [(set_attr "type" "alu1")])
13822 \f
13823 ;; Store-flag instructions.
13824
13825 ;; For all sCOND expanders, also expand the compare or test insn that
13826 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13827
13828 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13829 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13830 ;; way, which can later delete the movzx if only QImode is needed.
13831
13832 (define_expand "s<code>"
13833   [(set (match_operand:QI 0 "register_operand" "")
13834         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13835   ""
13836   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13837
13838 (define_expand "s<code>"
13839   [(set (match_operand:QI 0 "register_operand" "")
13840         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13841   "TARGET_80387 || TARGET_SSE"
13842   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13843
13844 (define_insn "*setcc_1"
13845   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13846         (match_operator:QI 1 "ix86_comparison_operator"
13847           [(reg FLAGS_REG) (const_int 0)]))]
13848   ""
13849   "set%C1\t%0"
13850   [(set_attr "type" "setcc")
13851    (set_attr "mode" "QI")])
13852
13853 (define_insn "*setcc_2"
13854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13855         (match_operator:QI 1 "ix86_comparison_operator"
13856           [(reg FLAGS_REG) (const_int 0)]))]
13857   ""
13858   "set%C1\t%0"
13859   [(set_attr "type" "setcc")
13860    (set_attr "mode" "QI")])
13861
13862 ;; In general it is not safe to assume too much about CCmode registers,
13863 ;; so simplify-rtx stops when it sees a second one.  Under certain
13864 ;; conditions this is safe on x86, so help combine not create
13865 ;;
13866 ;;      seta    %al
13867 ;;      testb   %al, %al
13868 ;;      sete    %al
13869
13870 (define_split
13871   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13872         (ne:QI (match_operator 1 "ix86_comparison_operator"
13873                  [(reg FLAGS_REG) (const_int 0)])
13874             (const_int 0)))]
13875   ""
13876   [(set (match_dup 0) (match_dup 1))]
13877 {
13878   PUT_MODE (operands[1], QImode);
13879 })
13880
13881 (define_split
13882   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13883         (ne:QI (match_operator 1 "ix86_comparison_operator"
13884                  [(reg FLAGS_REG) (const_int 0)])
13885             (const_int 0)))]
13886   ""
13887   [(set (match_dup 0) (match_dup 1))]
13888 {
13889   PUT_MODE (operands[1], QImode);
13890 })
13891
13892 (define_split
13893   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13894         (eq:QI (match_operator 1 "ix86_comparison_operator"
13895                  [(reg FLAGS_REG) (const_int 0)])
13896             (const_int 0)))]
13897   ""
13898   [(set (match_dup 0) (match_dup 1))]
13899 {
13900   rtx new_op1 = copy_rtx (operands[1]);
13901   operands[1] = new_op1;
13902   PUT_MODE (new_op1, QImode);
13903   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13904                                              GET_MODE (XEXP (new_op1, 0))));
13905
13906   /* Make sure that (a) the CCmode we have for the flags is strong
13907      enough for the reversed compare or (b) we have a valid FP compare.  */
13908   if (! ix86_comparison_operator (new_op1, VOIDmode))
13909     FAIL;
13910 })
13911
13912 (define_split
13913   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13914         (eq:QI (match_operator 1 "ix86_comparison_operator"
13915                  [(reg FLAGS_REG) (const_int 0)])
13916             (const_int 0)))]
13917   ""
13918   [(set (match_dup 0) (match_dup 1))]
13919 {
13920   rtx new_op1 = copy_rtx (operands[1]);
13921   operands[1] = new_op1;
13922   PUT_MODE (new_op1, QImode);
13923   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13924                                              GET_MODE (XEXP (new_op1, 0))));
13925
13926   /* Make sure that (a) the CCmode we have for the flags is strong
13927      enough for the reversed compare or (b) we have a valid FP compare.  */
13928   if (! ix86_comparison_operator (new_op1, VOIDmode))
13929     FAIL;
13930 })
13931
13932 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13933 ;; subsequent logical operations are used to imitate conditional moves.
13934 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13935 ;; it directly.
13936
13937 (define_insn "*sse_setcc<mode>"
13938   [(set (match_operand:MODEF 0 "register_operand" "=x")
13939         (match_operator:MODEF 1 "sse_comparison_operator"
13940           [(match_operand:MODEF 2 "register_operand" "0")
13941            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13942   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13943   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13944   [(set_attr "type" "ssecmp")
13945    (set_attr "mode" "<MODE>")])
13946
13947 (define_insn "*sse5_setcc<mode>"
13948   [(set (match_operand:MODEF 0 "register_operand" "=x")
13949         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13950           [(match_operand:MODEF 2 "register_operand" "x")
13951            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13952   "TARGET_SSE5"
13953   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13954   [(set_attr "type" "sse4arg")
13955    (set_attr "mode" "<MODE>")])
13956
13957 \f
13958 ;; Basic conditional jump instructions.
13959 ;; We ignore the overflow flag for signed branch instructions.
13960
13961 ;; For all bCOND expanders, also expand the compare or test insn that
13962 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13963
13964 (define_expand "b<code>"
13965   [(set (pc)
13966         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13967                                    (const_int 0))
13968                       (label_ref (match_operand 0 ""))
13969                       (pc)))]
13970   ""
13971   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13972
13973 (define_expand "b<code>"
13974   [(set (pc)
13975         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13976                                   (const_int 0))
13977                       (label_ref (match_operand 0 ""))
13978                       (pc)))]
13979   "TARGET_80387 || TARGET_SSE_MATH"
13980   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13981
13982 (define_insn "*jcc_1"
13983   [(set (pc)
13984         (if_then_else (match_operator 1 "ix86_comparison_operator"
13985                                       [(reg FLAGS_REG) (const_int 0)])
13986                       (label_ref (match_operand 0 "" ""))
13987                       (pc)))]
13988   ""
13989   "%+j%C1\t%l0"
13990   [(set_attr "type" "ibr")
13991    (set_attr "modrm" "0")
13992    (set (attr "length")
13993            (if_then_else (and (ge (minus (match_dup 0) (pc))
13994                                   (const_int -126))
13995                               (lt (minus (match_dup 0) (pc))
13996                                   (const_int 128)))
13997              (const_int 2)
13998              (const_int 6)))])
13999
14000 (define_insn "*jcc_2"
14001   [(set (pc)
14002         (if_then_else (match_operator 1 "ix86_comparison_operator"
14003                                       [(reg FLAGS_REG) (const_int 0)])
14004                       (pc)
14005                       (label_ref (match_operand 0 "" ""))))]
14006   ""
14007   "%+j%c1\t%l0"
14008   [(set_attr "type" "ibr")
14009    (set_attr "modrm" "0")
14010    (set (attr "length")
14011            (if_then_else (and (ge (minus (match_dup 0) (pc))
14012                                   (const_int -126))
14013                               (lt (minus (match_dup 0) (pc))
14014                                   (const_int 128)))
14015              (const_int 2)
14016              (const_int 6)))])
14017
14018 ;; ??? Handle alignment requirements for compare and branch fused macro-op;
14019 ;; the branch instruction does not start at a 16-byte boundary or cross
14020 ;; a 16-byte boundary.
14021
14022 (define_insn "*jcc_fused_1"
14023   [(set (pc)
14024         (if_then_else (match_operator 1 "comparison_operator"
14025                         [(match_operand:SWI 2 "register_operand" "<r>")
14026                          (match_operand:SWI 3 "const0_operand" "")])
14027          (label_ref (match_operand 0 "" ""))
14028          (pc)))]
14029   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
14030 {
14031   return "test{<imodesuffix>}\t%2, %2\n\t"
14032          "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
14033 }
14034   [(set_attr "type" "multi")
14035    (set_attr "mode" "<MODE>")])
14036
14037 (define_insn "*jcc_fused_2"
14038   [(set (pc)
14039         (if_then_else (match_operator 1 "comparison_operator"
14040                         [(match_operand:SWI 2 "register_operand" "<r>")
14041                          (match_operand:SWI 3 "const0_operand" "")])
14042          (pc)
14043          (label_ref (match_operand 0 "" ""))))]
14044   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
14045 {
14046   return "test{<imodesuffix>}\t%2, %2\n\t"
14047          "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
14048 }
14049   [(set_attr "type" "multi")
14050    (set_attr "mode" "<MODE>")])
14051
14052 (define_insn "*jcc_fused_3"
14053   [(set (pc)
14054         (if_then_else
14055           (match_operator 1 "ix86_comparison_uns_operator"
14056             [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
14057              (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
14058          (label_ref (match_operand 0 "" ""))
14059          (pc)))]
14060   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
14061    && !(MEM_P (operands[2])
14062         && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
14063 {
14064   return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
14065          "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
14066 }
14067   [(set_attr "type" "multi")
14068    (set_attr "mode" "<MODE>")])
14069
14070 (define_insn "*jcc_fused_4"
14071   [(set (pc)
14072         (if_then_else
14073           (match_operator 1 "ix86_comparison_uns_operator"
14074             [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
14075              (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
14076          (pc)
14077          (label_ref (match_operand 0 "" ""))))]
14078   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
14079    && !(MEM_P (operands[2])
14080         && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
14081 {
14082   return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
14083          "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
14084 }
14085   [(set_attr "type" "multi")
14086    (set_attr "mode" "<MODE>")])
14087
14088 ;; In general it is not safe to assume too much about CCmode registers,
14089 ;; so simplify-rtx stops when it sees a second one.  Under certain
14090 ;; conditions this is safe on x86, so help combine not create
14091 ;;
14092 ;;      seta    %al
14093 ;;      testb   %al, %al
14094 ;;      je      Lfoo
14095
14096 (define_split
14097   [(set (pc)
14098         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14099                                       [(reg FLAGS_REG) (const_int 0)])
14100                           (const_int 0))
14101                       (label_ref (match_operand 1 "" ""))
14102                       (pc)))]
14103   ""
14104   [(set (pc)
14105         (if_then_else (match_dup 0)
14106                       (label_ref (match_dup 1))
14107                       (pc)))]
14108 {
14109   PUT_MODE (operands[0], VOIDmode);
14110 })
14111
14112 (define_split
14113   [(set (pc)
14114         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14115                                       [(reg FLAGS_REG) (const_int 0)])
14116                           (const_int 0))
14117                       (label_ref (match_operand 1 "" ""))
14118                       (pc)))]
14119   ""
14120   [(set (pc)
14121         (if_then_else (match_dup 0)
14122                       (label_ref (match_dup 1))
14123                       (pc)))]
14124 {
14125   rtx new_op0 = copy_rtx (operands[0]);
14126   operands[0] = new_op0;
14127   PUT_MODE (new_op0, VOIDmode);
14128   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14129                                              GET_MODE (XEXP (new_op0, 0))));
14130
14131   /* Make sure that (a) the CCmode we have for the flags is strong
14132      enough for the reversed compare or (b) we have a valid FP compare.  */
14133   if (! ix86_comparison_operator (new_op0, VOIDmode))
14134     FAIL;
14135 })
14136
14137 ;; zero_extend in SImode is correct, since this is what combine pass
14138 ;; generates from shift insn with QImode operand.  Actually, the mode of
14139 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14140 ;; appropriate modulo of the bit offset value.
14141
14142 (define_insn_and_split "*jcc_btdi_rex64"
14143   [(set (pc)
14144         (if_then_else (match_operator 0 "bt_comparison_operator"
14145                         [(zero_extract:DI
14146                            (match_operand:DI 1 "register_operand" "r")
14147                            (const_int 1)
14148                            (zero_extend:SI
14149                              (match_operand:QI 2 "register_operand" "r")))
14150                          (const_int 0)])
14151                       (label_ref (match_operand 3 "" ""))
14152                       (pc)))]
14153   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
14154   "#"
14155   "&& 1"
14156   [(set (reg:CCC FLAGS_REG)
14157         (compare:CCC
14158           (zero_extract:DI
14159             (match_dup 1)
14160             (const_int 1)
14161             (match_dup 2))
14162           (const_int 0)))
14163    (set (pc)
14164         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14165                       (label_ref (match_dup 3))
14166                       (pc)))]
14167 {
14168   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14169
14170   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14171 })
14172
14173 ;; avoid useless masking of bit offset operand
14174 (define_insn_and_split "*jcc_btdi_mask_rex64"
14175   [(set (pc)
14176         (if_then_else (match_operator 0 "bt_comparison_operator"
14177                         [(zero_extract:DI
14178                            (match_operand:DI 1 "register_operand" "r")
14179                            (const_int 1)
14180                            (and:SI
14181                              (match_operand:SI 2 "register_operand" "r")
14182                              (match_operand:SI 3 "const_int_operand" "n")))])
14183                       (label_ref (match_operand 4 "" ""))
14184                       (pc)))]
14185   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
14186    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14187   "#"
14188   "&& 1"
14189   [(set (reg:CCC FLAGS_REG)
14190         (compare:CCC
14191           (zero_extract:DI
14192             (match_dup 1)
14193             (const_int 1)
14194             (match_dup 2))
14195           (const_int 0)))
14196    (set (pc)
14197         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14198                       (label_ref (match_dup 4))
14199                       (pc)))]
14200 {
14201   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14202
14203   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14204 })
14205
14206 (define_insn_and_split "*jcc_btsi"
14207   [(set (pc)
14208         (if_then_else (match_operator 0 "bt_comparison_operator"
14209                         [(zero_extract:SI
14210                            (match_operand:SI 1 "register_operand" "r")
14211                            (const_int 1)
14212                            (zero_extend:SI
14213                              (match_operand:QI 2 "register_operand" "r")))
14214                          (const_int 0)])
14215                       (label_ref (match_operand 3 "" ""))
14216                       (pc)))]
14217   "TARGET_USE_BT || optimize_size"
14218   "#"
14219   "&& 1"
14220   [(set (reg:CCC FLAGS_REG)
14221         (compare:CCC
14222           (zero_extract:SI
14223             (match_dup 1)
14224             (const_int 1)
14225             (match_dup 2))
14226           (const_int 0)))
14227    (set (pc)
14228         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14229                       (label_ref (match_dup 3))
14230                       (pc)))]
14231 {
14232   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14233
14234   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14235 })
14236
14237 ;; avoid useless masking of bit offset operand
14238 (define_insn_and_split "*jcc_btsi_mask"
14239   [(set (pc)
14240         (if_then_else (match_operator 0 "bt_comparison_operator"
14241                         [(zero_extract:SI
14242                            (match_operand:SI 1 "register_operand" "r")
14243                            (const_int 1)
14244                            (and:SI
14245                              (match_operand:SI 2 "register_operand" "r")
14246                              (match_operand:SI 3 "const_int_operand" "n")))])
14247                       (label_ref (match_operand 4 "" ""))
14248                       (pc)))]
14249   "(TARGET_USE_BT || optimize_size)
14250    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14251   "#"
14252   "&& 1"
14253   [(set (reg:CCC FLAGS_REG)
14254         (compare:CCC
14255           (zero_extract:SI
14256             (match_dup 1)
14257             (const_int 1)
14258             (match_dup 2))
14259           (const_int 0)))
14260    (set (pc)
14261         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14262                       (label_ref (match_dup 4))
14263                       (pc)))]
14264   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14265
14266 (define_insn_and_split "*jcc_btsi_1"
14267   [(set (pc)
14268         (if_then_else (match_operator 0 "bt_comparison_operator"
14269                         [(and:SI
14270                            (lshiftrt:SI
14271                              (match_operand:SI 1 "register_operand" "r")
14272                              (match_operand:QI 2 "register_operand" "r"))
14273                            (const_int 1))
14274                          (const_int 0)])
14275                       (label_ref (match_operand 3 "" ""))
14276                       (pc)))]
14277   "TARGET_USE_BT || optimize_size"
14278   "#"
14279   "&& 1"
14280   [(set (reg:CCC FLAGS_REG)
14281         (compare:CCC
14282           (zero_extract:SI
14283             (match_dup 1)
14284             (const_int 1)
14285             (match_dup 2))
14286           (const_int 0)))
14287    (set (pc)
14288         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14289                       (label_ref (match_dup 3))
14290                       (pc)))]
14291 {
14292   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14293
14294   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14295 })
14296
14297 ;; avoid useless masking of bit offset operand
14298 (define_insn_and_split "*jcc_btsi_mask_1"
14299   [(set (pc)
14300         (if_then_else
14301           (match_operator 0 "bt_comparison_operator"
14302             [(and:SI
14303                (lshiftrt:SI
14304                  (match_operand:SI 1 "register_operand" "r")
14305                  (subreg:QI
14306                    (and:SI
14307                      (match_operand:SI 2 "register_operand" "r")
14308                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14309                (const_int 1))
14310              (const_int 0)])
14311           (label_ref (match_operand 4 "" ""))
14312           (pc)))]
14313   "(TARGET_USE_BT || optimize_size)
14314    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14315   "#"
14316   "&& 1"
14317   [(set (reg:CCC FLAGS_REG)
14318         (compare:CCC
14319           (zero_extract:SI
14320             (match_dup 1)
14321             (const_int 1)
14322             (match_dup 2))
14323           (const_int 0)))
14324    (set (pc)
14325         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14326                       (label_ref (match_dup 4))
14327                       (pc)))]
14328   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14329
14330 ;; Define combination compare-and-branch fp compare instructions to use
14331 ;; during early optimization.  Splitting the operation apart early makes
14332 ;; for bad code when we want to reverse the operation.
14333
14334 (define_insn "*fp_jcc_1_mixed"
14335   [(set (pc)
14336         (if_then_else (match_operator 0 "comparison_operator"
14337                         [(match_operand 1 "register_operand" "f,x")
14338                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14339           (label_ref (match_operand 3 "" ""))
14340           (pc)))
14341    (clobber (reg:CCFP FPSR_REG))
14342    (clobber (reg:CCFP FLAGS_REG))]
14343   "TARGET_MIX_SSE_I387
14344    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14345    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14346    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14347   "#")
14348
14349 (define_insn "*fp_jcc_1_sse"
14350   [(set (pc)
14351         (if_then_else (match_operator 0 "comparison_operator"
14352                         [(match_operand 1 "register_operand" "x")
14353                          (match_operand 2 "nonimmediate_operand" "xm")])
14354           (label_ref (match_operand 3 "" ""))
14355           (pc)))
14356    (clobber (reg:CCFP FPSR_REG))
14357    (clobber (reg:CCFP FLAGS_REG))]
14358   "TARGET_SSE_MATH
14359    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14360    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14361    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14362   "#")
14363
14364 (define_insn "*fp_jcc_1_387"
14365   [(set (pc)
14366         (if_then_else (match_operator 0 "comparison_operator"
14367                         [(match_operand 1 "register_operand" "f")
14368                          (match_operand 2 "register_operand" "f")])
14369           (label_ref (match_operand 3 "" ""))
14370           (pc)))
14371    (clobber (reg:CCFP FPSR_REG))
14372    (clobber (reg:CCFP FLAGS_REG))]
14373   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14374    && TARGET_CMOVE
14375    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14376    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14377   "#")
14378
14379 (define_insn "*fp_jcc_2_mixed"
14380   [(set (pc)
14381         (if_then_else (match_operator 0 "comparison_operator"
14382                         [(match_operand 1 "register_operand" "f,x")
14383                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14384           (pc)
14385           (label_ref (match_operand 3 "" ""))))
14386    (clobber (reg:CCFP FPSR_REG))
14387    (clobber (reg:CCFP FLAGS_REG))]
14388   "TARGET_MIX_SSE_I387
14389    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14390    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14391    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14392   "#")
14393
14394 (define_insn "*fp_jcc_2_sse"
14395   [(set (pc)
14396         (if_then_else (match_operator 0 "comparison_operator"
14397                         [(match_operand 1 "register_operand" "x")
14398                          (match_operand 2 "nonimmediate_operand" "xm")])
14399           (pc)
14400           (label_ref (match_operand 3 "" ""))))
14401    (clobber (reg:CCFP FPSR_REG))
14402    (clobber (reg:CCFP FLAGS_REG))]
14403   "TARGET_SSE_MATH
14404    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14405    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14406    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14407   "#")
14408
14409 (define_insn "*fp_jcc_2_387"
14410   [(set (pc)
14411         (if_then_else (match_operator 0 "comparison_operator"
14412                         [(match_operand 1 "register_operand" "f")
14413                          (match_operand 2 "register_operand" "f")])
14414           (pc)
14415           (label_ref (match_operand 3 "" ""))))
14416    (clobber (reg:CCFP FPSR_REG))
14417    (clobber (reg:CCFP FLAGS_REG))]
14418   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14419    && TARGET_CMOVE
14420    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14421    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14422   "#")
14423
14424 (define_insn "*fp_jcc_3_387"
14425   [(set (pc)
14426         (if_then_else (match_operator 0 "comparison_operator"
14427                         [(match_operand 1 "register_operand" "f")
14428                          (match_operand 2 "nonimmediate_operand" "fm")])
14429           (label_ref (match_operand 3 "" ""))
14430           (pc)))
14431    (clobber (reg:CCFP FPSR_REG))
14432    (clobber (reg:CCFP FLAGS_REG))
14433    (clobber (match_scratch:HI 4 "=a"))]
14434   "TARGET_80387
14435    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14436    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14437    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14438    && SELECT_CC_MODE (GET_CODE (operands[0]),
14439                       operands[1], operands[2]) == CCFPmode
14440    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14441   "#")
14442
14443 (define_insn "*fp_jcc_4_387"
14444   [(set (pc)
14445         (if_then_else (match_operator 0 "comparison_operator"
14446                         [(match_operand 1 "register_operand" "f")
14447                          (match_operand 2 "nonimmediate_operand" "fm")])
14448           (pc)
14449           (label_ref (match_operand 3 "" ""))))
14450    (clobber (reg:CCFP FPSR_REG))
14451    (clobber (reg:CCFP FLAGS_REG))
14452    (clobber (match_scratch:HI 4 "=a"))]
14453   "TARGET_80387
14454    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14455    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14456    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14457    && SELECT_CC_MODE (GET_CODE (operands[0]),
14458                       operands[1], operands[2]) == CCFPmode
14459    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14460   "#")
14461
14462 (define_insn "*fp_jcc_5_387"
14463   [(set (pc)
14464         (if_then_else (match_operator 0 "comparison_operator"
14465                         [(match_operand 1 "register_operand" "f")
14466                          (match_operand 2 "register_operand" "f")])
14467           (label_ref (match_operand 3 "" ""))
14468           (pc)))
14469    (clobber (reg:CCFP FPSR_REG))
14470    (clobber (reg:CCFP FLAGS_REG))
14471    (clobber (match_scratch:HI 4 "=a"))]
14472   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14473    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14474    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14475   "#")
14476
14477 (define_insn "*fp_jcc_6_387"
14478   [(set (pc)
14479         (if_then_else (match_operator 0 "comparison_operator"
14480                         [(match_operand 1 "register_operand" "f")
14481                          (match_operand 2 "register_operand" "f")])
14482           (pc)
14483           (label_ref (match_operand 3 "" ""))))
14484    (clobber (reg:CCFP FPSR_REG))
14485    (clobber (reg:CCFP FLAGS_REG))
14486    (clobber (match_scratch:HI 4 "=a"))]
14487   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14488    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14489    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14490   "#")
14491
14492 (define_insn "*fp_jcc_7_387"
14493   [(set (pc)
14494         (if_then_else (match_operator 0 "comparison_operator"
14495                         [(match_operand 1 "register_operand" "f")
14496                          (match_operand 2 "const0_operand" "")])
14497           (label_ref (match_operand 3 "" ""))
14498           (pc)))
14499    (clobber (reg:CCFP FPSR_REG))
14500    (clobber (reg:CCFP FLAGS_REG))
14501    (clobber (match_scratch:HI 4 "=a"))]
14502   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14503    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14504    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14505    && SELECT_CC_MODE (GET_CODE (operands[0]),
14506                       operands[1], operands[2]) == CCFPmode
14507    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14508   "#")
14509
14510 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14511 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14512 ;; with a precedence over other operators and is always put in the first
14513 ;; place. Swap condition and operands to match ficom instruction.
14514
14515 (define_insn "*fp_jcc_8<mode>_387"
14516   [(set (pc)
14517         (if_then_else (match_operator 0 "comparison_operator"
14518                         [(match_operator 1 "float_operator"
14519                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14520                            (match_operand 3 "register_operand" "f,f")])
14521           (label_ref (match_operand 4 "" ""))
14522           (pc)))
14523    (clobber (reg:CCFP FPSR_REG))
14524    (clobber (reg:CCFP FLAGS_REG))
14525    (clobber (match_scratch:HI 5 "=a,a"))]
14526   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14527    && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14528    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14529    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14530    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14531    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14532   "#")
14533
14534 (define_split
14535   [(set (pc)
14536         (if_then_else (match_operator 0 "comparison_operator"
14537                         [(match_operand 1 "register_operand" "")
14538                          (match_operand 2 "nonimmediate_operand" "")])
14539           (match_operand 3 "" "")
14540           (match_operand 4 "" "")))
14541    (clobber (reg:CCFP FPSR_REG))
14542    (clobber (reg:CCFP FLAGS_REG))]
14543   "reload_completed"
14544   [(const_int 0)]
14545 {
14546   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14547                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14548   DONE;
14549 })
14550
14551 (define_split
14552   [(set (pc)
14553         (if_then_else (match_operator 0 "comparison_operator"
14554                         [(match_operand 1 "register_operand" "")
14555                          (match_operand 2 "general_operand" "")])
14556           (match_operand 3 "" "")
14557           (match_operand 4 "" "")))
14558    (clobber (reg:CCFP FPSR_REG))
14559    (clobber (reg:CCFP FLAGS_REG))
14560    (clobber (match_scratch:HI 5 "=a"))]
14561   "reload_completed"
14562   [(const_int 0)]
14563 {
14564   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14565                         operands[3], operands[4], operands[5], NULL_RTX);
14566   DONE;
14567 })
14568
14569 (define_split
14570   [(set (pc)
14571         (if_then_else (match_operator 0 "comparison_operator"
14572                         [(match_operator 1 "float_operator"
14573                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14574                            (match_operand 3 "register_operand" "")])
14575           (match_operand 4 "" "")
14576           (match_operand 5 "" "")))
14577    (clobber (reg:CCFP FPSR_REG))
14578    (clobber (reg:CCFP FLAGS_REG))
14579    (clobber (match_scratch:HI 6 "=a"))]
14580   "reload_completed"
14581   [(const_int 0)]
14582 {
14583   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14584   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14585                         operands[3], operands[7],
14586                         operands[4], operands[5], operands[6], NULL_RTX);
14587   DONE;
14588 })
14589
14590 ;; %%% Kill this when reload knows how to do it.
14591 (define_split
14592   [(set (pc)
14593         (if_then_else (match_operator 0 "comparison_operator"
14594                         [(match_operator 1 "float_operator"
14595                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14596                            (match_operand 3 "register_operand" "")])
14597           (match_operand 4 "" "")
14598           (match_operand 5 "" "")))
14599    (clobber (reg:CCFP FPSR_REG))
14600    (clobber (reg:CCFP FLAGS_REG))
14601    (clobber (match_scratch:HI 6 "=a"))]
14602   "reload_completed"
14603   [(const_int 0)]
14604 {
14605   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14606   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14607   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14608                         operands[3], operands[7],
14609                         operands[4], operands[5], operands[6], operands[2]);
14610   DONE;
14611 })
14612 \f
14613 ;; Unconditional and other jump instructions
14614
14615 (define_insn "jump"
14616   [(set (pc)
14617         (label_ref (match_operand 0 "" "")))]
14618   ""
14619   "jmp\t%l0"
14620   [(set_attr "type" "ibr")
14621    (set (attr "length")
14622            (if_then_else (and (ge (minus (match_dup 0) (pc))
14623                                   (const_int -126))
14624                               (lt (minus (match_dup 0) (pc))
14625                                   (const_int 128)))
14626              (const_int 2)
14627              (const_int 5)))
14628    (set_attr "modrm" "0")])
14629
14630 (define_expand "indirect_jump"
14631   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14632   ""
14633   "")
14634
14635 (define_insn "*indirect_jump"
14636   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14637   ""
14638   "jmp\t%A0"
14639   [(set_attr "type" "ibr")
14640    (set_attr "length_immediate" "0")])
14641
14642 (define_expand "tablejump"
14643   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14644               (use (label_ref (match_operand 1 "" "")))])]
14645   ""
14646 {
14647   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14648      relative.  Convert the relative address to an absolute address.  */
14649   if (flag_pic)
14650     {
14651       rtx op0, op1;
14652       enum rtx_code code;
14653
14654       /* We can't use @GOTOFF for text labels on VxWorks;
14655          see gotoff_operand.  */
14656       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14657         {
14658           code = PLUS;
14659           op0 = operands[0];
14660           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14661         }
14662       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14663         {
14664           code = PLUS;
14665           op0 = operands[0];
14666           op1 = pic_offset_table_rtx;
14667         }
14668       else
14669         {
14670           code = MINUS;
14671           op0 = pic_offset_table_rtx;
14672           op1 = operands[0];
14673         }
14674
14675       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14676                                          OPTAB_DIRECT);
14677     }
14678 })
14679
14680 (define_insn "*tablejump_1"
14681   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14682    (use (label_ref (match_operand 1 "" "")))]
14683   ""
14684   "jmp\t%A0"
14685   [(set_attr "type" "ibr")
14686    (set_attr "length_immediate" "0")])
14687 \f
14688 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14689
14690 (define_peephole2
14691   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14692    (set (match_operand:QI 1 "register_operand" "")
14693         (match_operator:QI 2 "ix86_comparison_operator"
14694           [(reg FLAGS_REG) (const_int 0)]))
14695    (set (match_operand 3 "q_regs_operand" "")
14696         (zero_extend (match_dup 1)))]
14697   "(peep2_reg_dead_p (3, operands[1])
14698     || operands_match_p (operands[1], operands[3]))
14699    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14700   [(set (match_dup 4) (match_dup 0))
14701    (set (strict_low_part (match_dup 5))
14702         (match_dup 2))]
14703 {
14704   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14705   operands[5] = gen_lowpart (QImode, operands[3]);
14706   ix86_expand_clear (operands[3]);
14707 })
14708
14709 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14710
14711 (define_peephole2
14712   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14713    (set (match_operand:QI 1 "register_operand" "")
14714         (match_operator:QI 2 "ix86_comparison_operator"
14715           [(reg FLAGS_REG) (const_int 0)]))
14716    (parallel [(set (match_operand 3 "q_regs_operand" "")
14717                    (zero_extend (match_dup 1)))
14718               (clobber (reg:CC FLAGS_REG))])]
14719   "(peep2_reg_dead_p (3, operands[1])
14720     || operands_match_p (operands[1], operands[3]))
14721    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14722   [(set (match_dup 4) (match_dup 0))
14723    (set (strict_low_part (match_dup 5))
14724         (match_dup 2))]
14725 {
14726   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14727   operands[5] = gen_lowpart (QImode, operands[3]);
14728   ix86_expand_clear (operands[3]);
14729 })
14730 \f
14731 ;; Call instructions.
14732
14733 ;; The predicates normally associated with named expanders are not properly
14734 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14735 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14736
14737 ;; Call subroutine returning no value.
14738
14739 (define_expand "call_pop"
14740   [(parallel [(call (match_operand:QI 0 "" "")
14741                     (match_operand:SI 1 "" ""))
14742               (set (reg:SI SP_REG)
14743                    (plus:SI (reg:SI SP_REG)
14744                             (match_operand:SI 3 "" "")))])]
14745   "!TARGET_64BIT"
14746 {
14747   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14748   DONE;
14749 })
14750
14751 (define_insn "*call_pop_0"
14752   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14753          (match_operand:SI 1 "" ""))
14754    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14755                             (match_operand:SI 2 "immediate_operand" "")))]
14756   "!TARGET_64BIT"
14757 {
14758   if (SIBLING_CALL_P (insn))
14759     return "jmp\t%P0";
14760   else
14761     return "call\t%P0";
14762 }
14763   [(set_attr "type" "call")])
14764
14765 (define_insn "*call_pop_1"
14766   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14767          (match_operand:SI 1 "" ""))
14768    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14769                             (match_operand:SI 2 "immediate_operand" "i")))]
14770   "!TARGET_64BIT"
14771 {
14772   if (constant_call_address_operand (operands[0], Pmode))
14773     {
14774       if (SIBLING_CALL_P (insn))
14775         return "jmp\t%P0";
14776       else
14777         return "call\t%P0";
14778     }
14779   if (SIBLING_CALL_P (insn))
14780     return "jmp\t%A0";
14781   else
14782     return "call\t%A0";
14783 }
14784   [(set_attr "type" "call")])
14785
14786 (define_expand "call"
14787   [(call (match_operand:QI 0 "" "")
14788          (match_operand 1 "" ""))
14789    (use (match_operand 2 "" ""))]
14790   ""
14791 {
14792   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14793   DONE;
14794 })
14795
14796 (define_expand "sibcall"
14797   [(call (match_operand:QI 0 "" "")
14798          (match_operand 1 "" ""))
14799    (use (match_operand 2 "" ""))]
14800   ""
14801 {
14802   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14803   DONE;
14804 })
14805
14806 (define_insn "*call_0"
14807   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14808          (match_operand 1 "" ""))]
14809   ""
14810 {
14811   if (SIBLING_CALL_P (insn))
14812     return "jmp\t%P0";
14813   else
14814     return "call\t%P0";
14815 }
14816   [(set_attr "type" "call")])
14817
14818 (define_insn "*call_1"
14819   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14820          (match_operand 1 "" ""))]
14821   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14822 {
14823   if (constant_call_address_operand (operands[0], Pmode))
14824     return "call\t%P0";
14825   return "call\t%A0";
14826 }
14827   [(set_attr "type" "call")])
14828
14829 (define_insn "*sibcall_1"
14830   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14831          (match_operand 1 "" ""))]
14832   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14833 {
14834   if (constant_call_address_operand (operands[0], Pmode))
14835     return "jmp\t%P0";
14836   return "jmp\t%A0";
14837 }
14838   [(set_attr "type" "call")])
14839
14840 (define_insn "*call_1_rex64"
14841   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14842          (match_operand 1 "" ""))]
14843   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14844    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14845 {
14846   if (constant_call_address_operand (operands[0], Pmode))
14847     return "call\t%P0";
14848   return "call\t%A0";
14849 }
14850   [(set_attr "type" "call")])
14851
14852 (define_insn "*call_1_rex64_large"
14853   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14854          (match_operand 1 "" ""))]
14855   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14856   "call\t%A0"
14857   [(set_attr "type" "call")])
14858
14859 (define_insn "*sibcall_1_rex64"
14860   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14861          (match_operand 1 "" ""))]
14862   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14863   "jmp\t%P0"
14864   [(set_attr "type" "call")])
14865
14866 (define_insn "*sibcall_1_rex64_v"
14867   [(call (mem:QI (reg:DI R11_REG))
14868          (match_operand 0 "" ""))]
14869   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14870   "jmp\t{*%%}r11"
14871   [(set_attr "type" "call")])
14872
14873
14874 ;; Call subroutine, returning value in operand 0
14875
14876 (define_expand "call_value_pop"
14877   [(parallel [(set (match_operand 0 "" "")
14878                    (call (match_operand:QI 1 "" "")
14879                          (match_operand:SI 2 "" "")))
14880               (set (reg:SI SP_REG)
14881                    (plus:SI (reg:SI SP_REG)
14882                             (match_operand:SI 4 "" "")))])]
14883   "!TARGET_64BIT"
14884 {
14885   ix86_expand_call (operands[0], operands[1], operands[2],
14886                     operands[3], operands[4], 0);
14887   DONE;
14888 })
14889
14890 (define_expand "call_value"
14891   [(set (match_operand 0 "" "")
14892         (call (match_operand:QI 1 "" "")
14893               (match_operand:SI 2 "" "")))
14894    (use (match_operand:SI 3 "" ""))]
14895   ;; Operand 2 not used on the i386.
14896   ""
14897 {
14898   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14899   DONE;
14900 })
14901
14902 (define_expand "sibcall_value"
14903   [(set (match_operand 0 "" "")
14904         (call (match_operand:QI 1 "" "")
14905               (match_operand:SI 2 "" "")))
14906    (use (match_operand:SI 3 "" ""))]
14907   ;; Operand 2 not used on the i386.
14908   ""
14909 {
14910   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14911   DONE;
14912 })
14913
14914 ;; Call subroutine returning any type.
14915
14916 (define_expand "untyped_call"
14917   [(parallel [(call (match_operand 0 "" "")
14918                     (const_int 0))
14919               (match_operand 1 "" "")
14920               (match_operand 2 "" "")])]
14921   ""
14922 {
14923   int i;
14924
14925   /* In order to give reg-stack an easier job in validating two
14926      coprocessor registers as containing a possible return value,
14927      simply pretend the untyped call returns a complex long double
14928      value.  */
14929
14930   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14931                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14932                     operands[0], const0_rtx,
14933                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14934                                                       : X64_SSE_REGPARM_MAX)
14935                              - 1),
14936                     NULL, 0);
14937
14938   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14939     {
14940       rtx set = XVECEXP (operands[2], 0, i);
14941       emit_move_insn (SET_DEST (set), SET_SRC (set));
14942     }
14943
14944   /* The optimizer does not know that the call sets the function value
14945      registers we stored in the result block.  We avoid problems by
14946      claiming that all hard registers are used and clobbered at this
14947      point.  */
14948   emit_insn (gen_blockage ());
14949
14950   DONE;
14951 })
14952 \f
14953 ;; Prologue and epilogue instructions
14954
14955 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14956 ;; all of memory.  This blocks insns from being moved across this point.
14957
14958 (define_insn "blockage"
14959   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14960   ""
14961   ""
14962   [(set_attr "length" "0")])
14963
14964 ;; As USE insns aren't meaningful after reload, this is used instead
14965 ;; to prevent deleting instructions setting registers for PIC code
14966 (define_insn "prologue_use"
14967   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14968   ""
14969   ""
14970   [(set_attr "length" "0")])
14971
14972 ;; Insn emitted into the body of a function to return from a function.
14973 ;; This is only done if the function's epilogue is known to be simple.
14974 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14975
14976 (define_expand "return"
14977   [(return)]
14978   "ix86_can_use_return_insn_p ()"
14979 {
14980   if (crtl->args.pops_args)
14981     {
14982       rtx popc = GEN_INT (crtl->args.pops_args);
14983       emit_jump_insn (gen_return_pop_internal (popc));
14984       DONE;
14985     }
14986 })
14987
14988 (define_insn "return_internal"
14989   [(return)]
14990   "reload_completed"
14991   "ret"
14992   [(set_attr "length" "1")
14993    (set_attr "length_immediate" "0")
14994    (set_attr "modrm" "0")])
14995
14996 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14997 ;; instruction Athlon and K8 have.
14998
14999 (define_insn "return_internal_long"
15000   [(return)
15001    (unspec [(const_int 0)] UNSPEC_REP)]
15002   "reload_completed"
15003   "rep\;ret"
15004   [(set_attr "length" "1")
15005    (set_attr "length_immediate" "0")
15006    (set_attr "prefix_rep" "1")
15007    (set_attr "modrm" "0")])
15008
15009 (define_insn "return_pop_internal"
15010   [(return)
15011    (use (match_operand:SI 0 "const_int_operand" ""))]
15012   "reload_completed"
15013   "ret\t%0"
15014   [(set_attr "length" "3")
15015    (set_attr "length_immediate" "2")
15016    (set_attr "modrm" "0")])
15017
15018 (define_insn "return_indirect_internal"
15019   [(return)
15020    (use (match_operand:SI 0 "register_operand" "r"))]
15021   "reload_completed"
15022   "jmp\t%A0"
15023   [(set_attr "type" "ibr")
15024    (set_attr "length_immediate" "0")])
15025
15026 (define_insn "nop"
15027   [(const_int 0)]
15028   ""
15029   "nop"
15030   [(set_attr "length" "1")
15031    (set_attr "length_immediate" "0")
15032    (set_attr "modrm" "0")])
15033
15034 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15035 ;; branch prediction penalty for the third jump in a 16-byte
15036 ;; block on K8.
15037
15038 (define_insn "align"
15039   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15040   ""
15041 {
15042 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15043   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15044 #else
15045   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15046      The align insn is used to avoid 3 jump instructions in the row to improve
15047      branch prediction and the benefits hardly outweigh the cost of extra 8
15048      nops on the average inserted by full alignment pseudo operation.  */
15049 #endif
15050   return "";
15051 }
15052   [(set_attr "length" "16")])
15053
15054 (define_expand "prologue"
15055   [(const_int 0)]
15056   ""
15057   "ix86_expand_prologue (); DONE;")
15058
15059 (define_insn "set_got"
15060   [(set (match_operand:SI 0 "register_operand" "=r")
15061         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15062    (clobber (reg:CC FLAGS_REG))]
15063   "!TARGET_64BIT"
15064   { return output_set_got (operands[0], NULL_RTX); }
15065   [(set_attr "type" "multi")
15066    (set_attr "length" "12")])
15067
15068 (define_insn "set_got_labelled"
15069   [(set (match_operand:SI 0 "register_operand" "=r")
15070         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15071          UNSPEC_SET_GOT))
15072    (clobber (reg:CC FLAGS_REG))]
15073   "!TARGET_64BIT"
15074   { return output_set_got (operands[0], operands[1]); }
15075   [(set_attr "type" "multi")
15076    (set_attr "length" "12")])
15077
15078 (define_insn "set_got_rex64"
15079   [(set (match_operand:DI 0 "register_operand" "=r")
15080         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15081   "TARGET_64BIT"
15082   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15083   [(set_attr "type" "lea")
15084    (set_attr "length" "6")])
15085
15086 (define_insn "set_rip_rex64"
15087   [(set (match_operand:DI 0 "register_operand" "=r")
15088         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15089   "TARGET_64BIT"
15090   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15091   [(set_attr "type" "lea")
15092    (set_attr "length" "6")])
15093
15094 (define_insn "set_got_offset_rex64"
15095   [(set (match_operand:DI 0 "register_operand" "=r")
15096         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15097   "TARGET_64BIT"
15098   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15099   [(set_attr "type" "imov")
15100    (set_attr "length" "11")])
15101
15102 (define_expand "epilogue"
15103   [(const_int 0)]
15104   ""
15105   "ix86_expand_epilogue (1); DONE;")
15106
15107 (define_expand "sibcall_epilogue"
15108   [(const_int 0)]
15109   ""
15110   "ix86_expand_epilogue (0); DONE;")
15111
15112 (define_expand "eh_return"
15113   [(use (match_operand 0 "register_operand" ""))]
15114   ""
15115 {
15116   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15117
15118   /* Tricky bit: we write the address of the handler to which we will
15119      be returning into someone else's stack frame, one word below the
15120      stack address we wish to restore.  */
15121   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15122   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15123   tmp = gen_rtx_MEM (Pmode, tmp);
15124   emit_move_insn (tmp, ra);
15125
15126   if (Pmode == SImode)
15127     emit_jump_insn (gen_eh_return_si (sa));
15128   else
15129     emit_jump_insn (gen_eh_return_di (sa));
15130   emit_barrier ();
15131   DONE;
15132 })
15133
15134 (define_insn_and_split "eh_return_<mode>"
15135   [(set (pc)
15136         (unspec [(match_operand:P 0 "register_operand" "c")]
15137                  UNSPEC_EH_RETURN))]
15138   ""
15139   "#"
15140   "reload_completed"
15141   [(const_int 0)]
15142   "ix86_expand_epilogue (2); DONE;")
15143
15144 (define_insn "leave"
15145   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15146    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15147    (clobber (mem:BLK (scratch)))]
15148   "!TARGET_64BIT"
15149   "leave"
15150   [(set_attr "type" "leave")])
15151
15152 (define_insn "leave_rex64"
15153   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15154    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15155    (clobber (mem:BLK (scratch)))]
15156   "TARGET_64BIT"
15157   "leave"
15158   [(set_attr "type" "leave")])
15159 \f
15160 (define_expand "ffssi2"
15161   [(parallel
15162      [(set (match_operand:SI 0 "register_operand" "")
15163            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15164       (clobber (match_scratch:SI 2 ""))
15165       (clobber (reg:CC FLAGS_REG))])]
15166   ""
15167 {
15168   if (TARGET_CMOVE)
15169     {
15170       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15171       DONE;
15172     }
15173 })
15174
15175 (define_expand "ffs_cmove"
15176   [(set (match_dup 2) (const_int -1))
15177    (parallel [(set (reg:CCZ FLAGS_REG)
15178                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15179                                 (const_int 0)))
15180               (set (match_operand:SI 0 "nonimmediate_operand" "")
15181                    (ctz:SI (match_dup 1)))])
15182    (set (match_dup 0) (if_then_else:SI
15183                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15184                         (match_dup 2)
15185                         (match_dup 0)))
15186    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15187               (clobber (reg:CC FLAGS_REG))])]
15188   "TARGET_CMOVE"
15189   "operands[2] = gen_reg_rtx (SImode);")
15190
15191 (define_insn_and_split "*ffs_no_cmove"
15192   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15193         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15194    (clobber (match_scratch:SI 2 "=&q"))
15195    (clobber (reg:CC FLAGS_REG))]
15196   "!TARGET_CMOVE"
15197   "#"
15198   "&& reload_completed"
15199   [(parallel [(set (reg:CCZ FLAGS_REG)
15200                    (compare:CCZ (match_dup 1) (const_int 0)))
15201               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15202    (set (strict_low_part (match_dup 3))
15203         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15204    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15205               (clobber (reg:CC FLAGS_REG))])
15206    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15207               (clobber (reg:CC FLAGS_REG))])
15208    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15209               (clobber (reg:CC FLAGS_REG))])]
15210 {
15211   operands[3] = gen_lowpart (QImode, operands[2]);
15212   ix86_expand_clear (operands[2]);
15213 })
15214
15215 (define_insn "*ffssi_1"
15216   [(set (reg:CCZ FLAGS_REG)
15217         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15218                      (const_int 0)))
15219    (set (match_operand:SI 0 "register_operand" "=r")
15220         (ctz:SI (match_dup 1)))]
15221   ""
15222   "bsf{l}\t{%1, %0|%0, %1}"
15223   [(set_attr "prefix_0f" "1")])
15224
15225 (define_expand "ffsdi2"
15226   [(set (match_dup 2) (const_int -1))
15227    (parallel [(set (reg:CCZ FLAGS_REG)
15228                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15229                                 (const_int 0)))
15230               (set (match_operand:DI 0 "nonimmediate_operand" "")
15231                    (ctz:DI (match_dup 1)))])
15232    (set (match_dup 0) (if_then_else:DI
15233                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15234                         (match_dup 2)
15235                         (match_dup 0)))
15236    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15237               (clobber (reg:CC FLAGS_REG))])]
15238   "TARGET_64BIT"
15239   "operands[2] = gen_reg_rtx (DImode);")
15240
15241 (define_insn "*ffsdi_1"
15242   [(set (reg:CCZ FLAGS_REG)
15243         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15244                      (const_int 0)))
15245    (set (match_operand:DI 0 "register_operand" "=r")
15246         (ctz:DI (match_dup 1)))]
15247   "TARGET_64BIT"
15248   "bsf{q}\t{%1, %0|%0, %1}"
15249   [(set_attr "prefix_0f" "1")])
15250
15251 (define_insn "ctzsi2"
15252   [(set (match_operand:SI 0 "register_operand" "=r")
15253         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15254    (clobber (reg:CC FLAGS_REG))]
15255   ""
15256   "bsf{l}\t{%1, %0|%0, %1}"
15257   [(set_attr "prefix_0f" "1")])
15258
15259 (define_insn "ctzdi2"
15260   [(set (match_operand:DI 0 "register_operand" "=r")
15261         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15262    (clobber (reg:CC FLAGS_REG))]
15263   "TARGET_64BIT"
15264   "bsf{q}\t{%1, %0|%0, %1}"
15265   [(set_attr "prefix_0f" "1")])
15266
15267 (define_expand "clzsi2"
15268   [(parallel
15269      [(set (match_operand:SI 0 "register_operand" "")
15270            (minus:SI (const_int 31)
15271                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15272       (clobber (reg:CC FLAGS_REG))])
15273    (parallel
15274      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15275       (clobber (reg:CC FLAGS_REG))])]
15276   ""
15277 {
15278   if (TARGET_ABM)
15279     {
15280       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15281       DONE;
15282     }
15283 })
15284
15285 (define_insn "clzsi2_abm"
15286   [(set (match_operand:SI 0 "register_operand" "=r")
15287         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15288    (clobber (reg:CC FLAGS_REG))]
15289   "TARGET_ABM"
15290   "lzcnt{l}\t{%1, %0|%0, %1}"
15291   [(set_attr "prefix_rep" "1")
15292    (set_attr "type" "bitmanip")
15293    (set_attr "mode" "SI")])
15294
15295 (define_insn "*bsr"
15296   [(set (match_operand:SI 0 "register_operand" "=r")
15297         (minus:SI (const_int 31)
15298                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15299    (clobber (reg:CC FLAGS_REG))]
15300   ""
15301   "bsr{l}\t{%1, %0|%0, %1}"
15302   [(set_attr "prefix_0f" "1")
15303    (set_attr "mode" "SI")])
15304
15305 (define_insn "popcountsi2"
15306   [(set (match_operand:SI 0 "register_operand" "=r")
15307         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15308    (clobber (reg:CC FLAGS_REG))]
15309   "TARGET_POPCNT"
15310   "popcnt{l}\t{%1, %0|%0, %1}"
15311   [(set_attr "prefix_rep" "1")
15312    (set_attr "type" "bitmanip")
15313    (set_attr "mode" "SI")])
15314
15315 (define_insn "*popcountsi2_cmp"
15316   [(set (reg FLAGS_REG)
15317         (compare
15318           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15319           (const_int 0)))
15320    (set (match_operand:SI 0 "register_operand" "=r")
15321         (popcount:SI (match_dup 1)))]
15322   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15323   "popcnt{l}\t{%1, %0|%0, %1}"
15324   [(set_attr "prefix_rep" "1")
15325    (set_attr "type" "bitmanip")
15326    (set_attr "mode" "SI")])
15327
15328 (define_insn "*popcountsi2_cmp_zext"
15329   [(set (reg FLAGS_REG)
15330         (compare
15331           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15332           (const_int 0)))
15333    (set (match_operand:DI 0 "register_operand" "=r")
15334         (zero_extend:DI(popcount:SI (match_dup 1))))]
15335   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15336   "popcnt{l}\t{%1, %0|%0, %1}"
15337   [(set_attr "prefix_rep" "1")
15338    (set_attr "type" "bitmanip")
15339    (set_attr "mode" "SI")])
15340
15341 (define_expand "bswapsi2"
15342   [(set (match_operand:SI 0 "register_operand" "")
15343         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15344   ""
15345 {
15346   if (!TARGET_BSWAP)
15347     {
15348       rtx x = operands[0];
15349
15350       emit_move_insn (x, operands[1]);
15351       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15352       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15353       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15354       DONE;
15355     }
15356 })
15357
15358 (define_insn "*bswapsi_1"
15359   [(set (match_operand:SI 0 "register_operand" "=r")
15360         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15361   "TARGET_BSWAP"
15362   "bswap\t%0"
15363   [(set_attr "prefix_0f" "1")
15364    (set_attr "length" "2")])
15365
15366 (define_insn "*bswaphi_lowpart_1"
15367   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15368         (bswap:HI (match_dup 0)))
15369    (clobber (reg:CC FLAGS_REG))]
15370   "TARGET_USE_XCHGB || optimize_size"
15371   "@
15372     xchg{b}\t{%h0, %b0|%b0, %h0}
15373     rol{w}\t{$8, %0|%0, 8}"
15374   [(set_attr "length" "2,4")
15375    (set_attr "mode" "QI,HI")])
15376
15377 (define_insn "bswaphi_lowpart"
15378   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15379         (bswap:HI (match_dup 0)))
15380    (clobber (reg:CC FLAGS_REG))]
15381   ""
15382   "rol{w}\t{$8, %0|%0, 8}"
15383   [(set_attr "length" "4")
15384    (set_attr "mode" "HI")])
15385
15386 (define_insn "bswapdi2"
15387   [(set (match_operand:DI 0 "register_operand" "=r")
15388         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15389   "TARGET_64BIT"
15390   "bswap\t%0"
15391   [(set_attr "prefix_0f" "1")
15392    (set_attr "length" "3")])
15393
15394 (define_expand "clzdi2"
15395   [(parallel
15396      [(set (match_operand:DI 0 "register_operand" "")
15397            (minus:DI (const_int 63)
15398                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15399       (clobber (reg:CC FLAGS_REG))])
15400    (parallel
15401      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15402       (clobber (reg:CC FLAGS_REG))])]
15403   "TARGET_64BIT"
15404 {
15405   if (TARGET_ABM)
15406     {
15407       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15408       DONE;
15409     }
15410 })
15411
15412 (define_insn "clzdi2_abm"
15413   [(set (match_operand:DI 0 "register_operand" "=r")
15414         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15415    (clobber (reg:CC FLAGS_REG))]
15416   "TARGET_64BIT && TARGET_ABM"
15417   "lzcnt{q}\t{%1, %0|%0, %1}"
15418   [(set_attr "prefix_rep" "1")
15419    (set_attr "type" "bitmanip")
15420    (set_attr "mode" "DI")])
15421
15422 (define_insn "*bsr_rex64"
15423   [(set (match_operand:DI 0 "register_operand" "=r")
15424         (minus:DI (const_int 63)
15425                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15426    (clobber (reg:CC FLAGS_REG))]
15427   "TARGET_64BIT"
15428   "bsr{q}\t{%1, %0|%0, %1}"
15429   [(set_attr "prefix_0f" "1")
15430    (set_attr "mode" "DI")])
15431
15432 (define_insn "popcountdi2"
15433   [(set (match_operand:DI 0 "register_operand" "=r")
15434         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15435    (clobber (reg:CC FLAGS_REG))]
15436   "TARGET_64BIT && TARGET_POPCNT"
15437   "popcnt{q}\t{%1, %0|%0, %1}"
15438   [(set_attr "prefix_rep" "1")
15439    (set_attr "type" "bitmanip")
15440    (set_attr "mode" "DI")])
15441
15442 (define_insn "*popcountdi2_cmp"
15443   [(set (reg FLAGS_REG)
15444         (compare
15445           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15446           (const_int 0)))
15447    (set (match_operand:DI 0 "register_operand" "=r")
15448         (popcount:DI (match_dup 1)))]
15449   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15450   "popcnt{q}\t{%1, %0|%0, %1}"
15451   [(set_attr "prefix_rep" "1")
15452    (set_attr "type" "bitmanip")
15453    (set_attr "mode" "DI")])
15454
15455 (define_expand "clzhi2"
15456   [(parallel
15457      [(set (match_operand:HI 0 "register_operand" "")
15458            (minus:HI (const_int 15)
15459                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15460       (clobber (reg:CC FLAGS_REG))])
15461    (parallel
15462      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15463       (clobber (reg:CC FLAGS_REG))])]
15464   ""
15465 {
15466   if (TARGET_ABM)
15467     {
15468       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15469       DONE;
15470     }
15471 })
15472
15473 (define_insn "clzhi2_abm"
15474   [(set (match_operand:HI 0 "register_operand" "=r")
15475         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15476    (clobber (reg:CC FLAGS_REG))]
15477   "TARGET_ABM"
15478   "lzcnt{w}\t{%1, %0|%0, %1}"
15479   [(set_attr "prefix_rep" "1")
15480    (set_attr "type" "bitmanip")
15481    (set_attr "mode" "HI")])
15482
15483 (define_insn "*bsrhi"
15484   [(set (match_operand:HI 0 "register_operand" "=r")
15485         (minus:HI (const_int 15)
15486                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15487    (clobber (reg:CC FLAGS_REG))]
15488   ""
15489   "bsr{w}\t{%1, %0|%0, %1}"
15490   [(set_attr "prefix_0f" "1")
15491    (set_attr "mode" "HI")])
15492
15493 (define_insn "popcounthi2"
15494   [(set (match_operand:HI 0 "register_operand" "=r")
15495         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15496    (clobber (reg:CC FLAGS_REG))]
15497   "TARGET_POPCNT"
15498   "popcnt{w}\t{%1, %0|%0, %1}"
15499   [(set_attr "prefix_rep" "1")
15500    (set_attr "type" "bitmanip")
15501    (set_attr "mode" "HI")])
15502
15503 (define_insn "*popcounthi2_cmp"
15504   [(set (reg FLAGS_REG)
15505         (compare
15506           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15507           (const_int 0)))
15508    (set (match_operand:HI 0 "register_operand" "=r")
15509         (popcount:HI (match_dup 1)))]
15510   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15511   "popcnt{w}\t{%1, %0|%0, %1}"
15512   [(set_attr "prefix_rep" "1")
15513    (set_attr "type" "bitmanip")
15514    (set_attr "mode" "HI")])
15515
15516 (define_expand "paritydi2"
15517   [(set (match_operand:DI 0 "register_operand" "")
15518         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15519   "! TARGET_POPCNT"
15520 {
15521   rtx scratch = gen_reg_rtx (QImode);
15522   rtx cond;
15523
15524   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15525                                 NULL_RTX, operands[1]));
15526
15527   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15528                          gen_rtx_REG (CCmode, FLAGS_REG),
15529                          const0_rtx);
15530   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15531
15532   if (TARGET_64BIT)
15533     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15534   else
15535     {
15536       rtx tmp = gen_reg_rtx (SImode);
15537
15538       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15539       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15540     }
15541   DONE;
15542 })
15543
15544 (define_insn_and_split "paritydi2_cmp"
15545   [(set (reg:CC FLAGS_REG)
15546         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15547    (clobber (match_scratch:DI 0 "=r"))
15548    (clobber (match_scratch:SI 1 "=&r"))
15549    (clobber (match_scratch:HI 2 "=Q"))]
15550   "! TARGET_POPCNT"
15551   "#"
15552   "&& reload_completed"
15553   [(parallel
15554      [(set (match_dup 1)
15555            (xor:SI (match_dup 1) (match_dup 4)))
15556       (clobber (reg:CC FLAGS_REG))])
15557    (parallel
15558      [(set (reg:CC FLAGS_REG)
15559            (parity:CC (match_dup 1)))
15560       (clobber (match_dup 1))
15561       (clobber (match_dup 2))])]
15562 {
15563   operands[4] = gen_lowpart (SImode, operands[3]);
15564
15565   if (TARGET_64BIT)
15566     {
15567       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15568       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15569     }
15570   else
15571     operands[1] = gen_highpart (SImode, operands[3]);
15572 })
15573
15574 (define_expand "paritysi2"
15575   [(set (match_operand:SI 0 "register_operand" "")
15576         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15577   "! TARGET_POPCNT"
15578 {
15579   rtx scratch = gen_reg_rtx (QImode);
15580   rtx cond;
15581
15582   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15583
15584   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15585                          gen_rtx_REG (CCmode, FLAGS_REG),
15586                          const0_rtx);
15587   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15588
15589   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15590   DONE;
15591 })
15592
15593 (define_insn_and_split "paritysi2_cmp"
15594   [(set (reg:CC FLAGS_REG)
15595         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15596    (clobber (match_scratch:SI 0 "=r"))
15597    (clobber (match_scratch:HI 1 "=&Q"))]
15598   "! TARGET_POPCNT"
15599   "#"
15600   "&& reload_completed"
15601   [(parallel
15602      [(set (match_dup 1)
15603            (xor:HI (match_dup 1) (match_dup 3)))
15604       (clobber (reg:CC FLAGS_REG))])
15605    (parallel
15606      [(set (reg:CC FLAGS_REG)
15607            (parity:CC (match_dup 1)))
15608       (clobber (match_dup 1))])]
15609 {
15610   operands[3] = gen_lowpart (HImode, operands[2]);
15611
15612   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15613   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15614 })
15615
15616 (define_insn "*parityhi2_cmp"
15617   [(set (reg:CC FLAGS_REG)
15618         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15619    (clobber (match_scratch:HI 0 "=Q"))]
15620   "! TARGET_POPCNT"
15621   "xor{b}\t{%h0, %b0|%b0, %h0}"
15622   [(set_attr "length" "2")
15623    (set_attr "mode" "HI")])
15624
15625 (define_insn "*parityqi2_cmp"
15626   [(set (reg:CC FLAGS_REG)
15627         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15628   "! TARGET_POPCNT"
15629   "test{b}\t%0, %0"
15630   [(set_attr "length" "2")
15631    (set_attr "mode" "QI")])
15632 \f
15633 ;; Thread-local storage patterns for ELF.
15634 ;;
15635 ;; Note that these code sequences must appear exactly as shown
15636 ;; in order to allow linker relaxation.
15637
15638 (define_insn "*tls_global_dynamic_32_gnu"
15639   [(set (match_operand:SI 0 "register_operand" "=a")
15640         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15641                     (match_operand:SI 2 "tls_symbolic_operand" "")
15642                     (match_operand:SI 3 "call_insn_operand" "")]
15643                     UNSPEC_TLS_GD))
15644    (clobber (match_scratch:SI 4 "=d"))
15645    (clobber (match_scratch:SI 5 "=c"))
15646    (clobber (reg:CC FLAGS_REG))]
15647   "!TARGET_64BIT && TARGET_GNU_TLS"
15648   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15649   [(set_attr "type" "multi")
15650    (set_attr "length" "12")])
15651
15652 (define_insn "*tls_global_dynamic_32_sun"
15653   [(set (match_operand:SI 0 "register_operand" "=a")
15654         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15655                     (match_operand:SI 2 "tls_symbolic_operand" "")
15656                     (match_operand:SI 3 "call_insn_operand" "")]
15657                     UNSPEC_TLS_GD))
15658    (clobber (match_scratch:SI 4 "=d"))
15659    (clobber (match_scratch:SI 5 "=c"))
15660    (clobber (reg:CC FLAGS_REG))]
15661   "!TARGET_64BIT && TARGET_SUN_TLS"
15662   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15663         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15664   [(set_attr "type" "multi")
15665    (set_attr "length" "14")])
15666
15667 (define_expand "tls_global_dynamic_32"
15668   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15669                    (unspec:SI
15670                     [(match_dup 2)
15671                      (match_operand:SI 1 "tls_symbolic_operand" "")
15672                      (match_dup 3)]
15673                     UNSPEC_TLS_GD))
15674               (clobber (match_scratch:SI 4 ""))
15675               (clobber (match_scratch:SI 5 ""))
15676               (clobber (reg:CC FLAGS_REG))])]
15677   ""
15678 {
15679   if (flag_pic)
15680     operands[2] = pic_offset_table_rtx;
15681   else
15682     {
15683       operands[2] = gen_reg_rtx (Pmode);
15684       emit_insn (gen_set_got (operands[2]));
15685     }
15686   if (TARGET_GNU2_TLS)
15687     {
15688        emit_insn (gen_tls_dynamic_gnu2_32
15689                   (operands[0], operands[1], operands[2]));
15690        DONE;
15691     }
15692   operands[3] = ix86_tls_get_addr ();
15693 })
15694
15695 (define_insn "*tls_global_dynamic_64"
15696   [(set (match_operand:DI 0 "register_operand" "=a")
15697         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15698                  (match_operand:DI 3 "" "")))
15699    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15700               UNSPEC_TLS_GD)]
15701   "TARGET_64BIT"
15702   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15703   [(set_attr "type" "multi")
15704    (set_attr "length" "16")])
15705
15706 (define_expand "tls_global_dynamic_64"
15707   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15708                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15709               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15710                          UNSPEC_TLS_GD)])]
15711   ""
15712 {
15713   if (TARGET_GNU2_TLS)
15714     {
15715        emit_insn (gen_tls_dynamic_gnu2_64
15716                   (operands[0], operands[1]));
15717        DONE;
15718     }
15719   operands[2] = ix86_tls_get_addr ();
15720 })
15721
15722 (define_insn "*tls_local_dynamic_base_32_gnu"
15723   [(set (match_operand:SI 0 "register_operand" "=a")
15724         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15725                     (match_operand:SI 2 "call_insn_operand" "")]
15726                    UNSPEC_TLS_LD_BASE))
15727    (clobber (match_scratch:SI 3 "=d"))
15728    (clobber (match_scratch:SI 4 "=c"))
15729    (clobber (reg:CC FLAGS_REG))]
15730   "!TARGET_64BIT && TARGET_GNU_TLS"
15731   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15732   [(set_attr "type" "multi")
15733    (set_attr "length" "11")])
15734
15735 (define_insn "*tls_local_dynamic_base_32_sun"
15736   [(set (match_operand:SI 0 "register_operand" "=a")
15737         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15738                     (match_operand:SI 2 "call_insn_operand" "")]
15739                    UNSPEC_TLS_LD_BASE))
15740    (clobber (match_scratch:SI 3 "=d"))
15741    (clobber (match_scratch:SI 4 "=c"))
15742    (clobber (reg:CC FLAGS_REG))]
15743   "!TARGET_64BIT && TARGET_SUN_TLS"
15744   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15745         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15746   [(set_attr "type" "multi")
15747    (set_attr "length" "13")])
15748
15749 (define_expand "tls_local_dynamic_base_32"
15750   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15751                    (unspec:SI [(match_dup 1) (match_dup 2)]
15752                               UNSPEC_TLS_LD_BASE))
15753               (clobber (match_scratch:SI 3 ""))
15754               (clobber (match_scratch:SI 4 ""))
15755               (clobber (reg:CC FLAGS_REG))])]
15756   ""
15757 {
15758   if (flag_pic)
15759     operands[1] = pic_offset_table_rtx;
15760   else
15761     {
15762       operands[1] = gen_reg_rtx (Pmode);
15763       emit_insn (gen_set_got (operands[1]));
15764     }
15765   if (TARGET_GNU2_TLS)
15766     {
15767        emit_insn (gen_tls_dynamic_gnu2_32
15768                   (operands[0], ix86_tls_module_base (), operands[1]));
15769        DONE;
15770     }
15771   operands[2] = ix86_tls_get_addr ();
15772 })
15773
15774 (define_insn "*tls_local_dynamic_base_64"
15775   [(set (match_operand:DI 0 "register_operand" "=a")
15776         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15777                  (match_operand:DI 2 "" "")))
15778    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15779   "TARGET_64BIT"
15780   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15781   [(set_attr "type" "multi")
15782    (set_attr "length" "12")])
15783
15784 (define_expand "tls_local_dynamic_base_64"
15785   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15786                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15787               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15788   ""
15789 {
15790   if (TARGET_GNU2_TLS)
15791     {
15792        emit_insn (gen_tls_dynamic_gnu2_64
15793                   (operands[0], ix86_tls_module_base ()));
15794        DONE;
15795     }
15796   operands[1] = ix86_tls_get_addr ();
15797 })
15798
15799 ;; Local dynamic of a single variable is a lose.  Show combine how
15800 ;; to convert that back to global dynamic.
15801
15802 (define_insn_and_split "*tls_local_dynamic_32_once"
15803   [(set (match_operand:SI 0 "register_operand" "=a")
15804         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15805                              (match_operand:SI 2 "call_insn_operand" "")]
15806                             UNSPEC_TLS_LD_BASE)
15807                  (const:SI (unspec:SI
15808                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15809                             UNSPEC_DTPOFF))))
15810    (clobber (match_scratch:SI 4 "=d"))
15811    (clobber (match_scratch:SI 5 "=c"))
15812    (clobber (reg:CC FLAGS_REG))]
15813   ""
15814   "#"
15815   ""
15816   [(parallel [(set (match_dup 0)
15817                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15818                               UNSPEC_TLS_GD))
15819               (clobber (match_dup 4))
15820               (clobber (match_dup 5))
15821               (clobber (reg:CC FLAGS_REG))])]
15822   "")
15823
15824 ;; Load and add the thread base pointer from %gs:0.
15825
15826 (define_insn "*load_tp_si"
15827   [(set (match_operand:SI 0 "register_operand" "=r")
15828         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15829   "!TARGET_64BIT"
15830   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15831   [(set_attr "type" "imov")
15832    (set_attr "modrm" "0")
15833    (set_attr "length" "7")
15834    (set_attr "memory" "load")
15835    (set_attr "imm_disp" "false")])
15836
15837 (define_insn "*add_tp_si"
15838   [(set (match_operand:SI 0 "register_operand" "=r")
15839         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15840                  (match_operand:SI 1 "register_operand" "0")))
15841    (clobber (reg:CC FLAGS_REG))]
15842   "!TARGET_64BIT"
15843   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15844   [(set_attr "type" "alu")
15845    (set_attr "modrm" "0")
15846    (set_attr "length" "7")
15847    (set_attr "memory" "load")
15848    (set_attr "imm_disp" "false")])
15849
15850 (define_insn "*load_tp_di"
15851   [(set (match_operand:DI 0 "register_operand" "=r")
15852         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15853   "TARGET_64BIT"
15854   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15855   [(set_attr "type" "imov")
15856    (set_attr "modrm" "0")
15857    (set_attr "length" "7")
15858    (set_attr "memory" "load")
15859    (set_attr "imm_disp" "false")])
15860
15861 (define_insn "*add_tp_di"
15862   [(set (match_operand:DI 0 "register_operand" "=r")
15863         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15864                  (match_operand:DI 1 "register_operand" "0")))
15865    (clobber (reg:CC FLAGS_REG))]
15866   "TARGET_64BIT"
15867   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15868   [(set_attr "type" "alu")
15869    (set_attr "modrm" "0")
15870    (set_attr "length" "7")
15871    (set_attr "memory" "load")
15872    (set_attr "imm_disp" "false")])
15873
15874 ;; GNU2 TLS patterns can be split.
15875
15876 (define_expand "tls_dynamic_gnu2_32"
15877   [(set (match_dup 3)
15878         (plus:SI (match_operand:SI 2 "register_operand" "")
15879                  (const:SI
15880                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15881                              UNSPEC_TLSDESC))))
15882    (parallel
15883     [(set (match_operand:SI 0 "register_operand" "")
15884           (unspec:SI [(match_dup 1) (match_dup 3)
15885                       (match_dup 2) (reg:SI SP_REG)]
15886                       UNSPEC_TLSDESC))
15887      (clobber (reg:CC FLAGS_REG))])]
15888   "!TARGET_64BIT && TARGET_GNU2_TLS"
15889 {
15890   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15891   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15892 })
15893
15894 (define_insn "*tls_dynamic_lea_32"
15895   [(set (match_operand:SI 0 "register_operand" "=r")
15896         (plus:SI (match_operand:SI 1 "register_operand" "b")
15897                  (const:SI
15898                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15899                               UNSPEC_TLSDESC))))]
15900   "!TARGET_64BIT && TARGET_GNU2_TLS"
15901   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15902   [(set_attr "type" "lea")
15903    (set_attr "mode" "SI")
15904    (set_attr "length" "6")
15905    (set_attr "length_address" "4")])
15906
15907 (define_insn "*tls_dynamic_call_32"
15908   [(set (match_operand:SI 0 "register_operand" "=a")
15909         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15910                     (match_operand:SI 2 "register_operand" "0")
15911                     ;; we have to make sure %ebx still points to the GOT
15912                     (match_operand:SI 3 "register_operand" "b")
15913                     (reg:SI SP_REG)]
15914                    UNSPEC_TLSDESC))
15915    (clobber (reg:CC FLAGS_REG))]
15916   "!TARGET_64BIT && TARGET_GNU2_TLS"
15917   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15918   [(set_attr "type" "call")
15919    (set_attr "length" "2")
15920    (set_attr "length_address" "0")])
15921
15922 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15923   [(set (match_operand:SI 0 "register_operand" "=&a")
15924         (plus:SI
15925          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15926                      (match_operand:SI 4 "" "")
15927                      (match_operand:SI 2 "register_operand" "b")
15928                      (reg:SI SP_REG)]
15929                     UNSPEC_TLSDESC)
15930          (const:SI (unspec:SI
15931                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15932                     UNSPEC_DTPOFF))))
15933    (clobber (reg:CC FLAGS_REG))]
15934   "!TARGET_64BIT && TARGET_GNU2_TLS"
15935   "#"
15936   ""
15937   [(set (match_dup 0) (match_dup 5))]
15938 {
15939   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15940   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15941 })
15942
15943 (define_expand "tls_dynamic_gnu2_64"
15944   [(set (match_dup 2)
15945         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15946                    UNSPEC_TLSDESC))
15947    (parallel
15948     [(set (match_operand:DI 0 "register_operand" "")
15949           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15950                      UNSPEC_TLSDESC))
15951      (clobber (reg:CC FLAGS_REG))])]
15952   "TARGET_64BIT && TARGET_GNU2_TLS"
15953 {
15954   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15955   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15956 })
15957
15958 (define_insn "*tls_dynamic_lea_64"
15959   [(set (match_operand:DI 0 "register_operand" "=r")
15960         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15961                    UNSPEC_TLSDESC))]
15962   "TARGET_64BIT && TARGET_GNU2_TLS"
15963   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15964   [(set_attr "type" "lea")
15965    (set_attr "mode" "DI")
15966    (set_attr "length" "7")
15967    (set_attr "length_address" "4")])
15968
15969 (define_insn "*tls_dynamic_call_64"
15970   [(set (match_operand:DI 0 "register_operand" "=a")
15971         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15972                     (match_operand:DI 2 "register_operand" "0")
15973                     (reg:DI SP_REG)]
15974                    UNSPEC_TLSDESC))
15975    (clobber (reg:CC FLAGS_REG))]
15976   "TARGET_64BIT && TARGET_GNU2_TLS"
15977   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15978   [(set_attr "type" "call")
15979    (set_attr "length" "2")
15980    (set_attr "length_address" "0")])
15981
15982 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15983   [(set (match_operand:DI 0 "register_operand" "=&a")
15984         (plus:DI
15985          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15986                      (match_operand:DI 3 "" "")
15987                      (reg:DI SP_REG)]
15988                     UNSPEC_TLSDESC)
15989          (const:DI (unspec:DI
15990                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15991                     UNSPEC_DTPOFF))))
15992    (clobber (reg:CC FLAGS_REG))]
15993   "TARGET_64BIT && TARGET_GNU2_TLS"
15994   "#"
15995   ""
15996   [(set (match_dup 0) (match_dup 4))]
15997 {
15998   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15999   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16000 })
16001
16002 ;;
16003 \f
16004 ;; These patterns match the binary 387 instructions for addM3, subM3,
16005 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16006 ;; SFmode.  The first is the normal insn, the second the same insn but
16007 ;; with one operand a conversion, and the third the same insn but with
16008 ;; the other operand a conversion.  The conversion may be SFmode or
16009 ;; SImode if the target mode DFmode, but only SImode if the target mode
16010 ;; is SFmode.
16011
16012 ;; Gcc is slightly more smart about handling normal two address instructions
16013 ;; so use special patterns for add and mull.
16014
16015 (define_insn "*fop_<mode>_comm_mixed"
16016   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16017         (match_operator:MODEF 3 "binary_fp_operator"
16018           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16019            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16020   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16021    && COMMUTATIVE_ARITH_P (operands[3])
16022    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16023   "* return output_387_binary_op (insn, operands);"
16024   [(set (attr "type")
16025         (if_then_else (eq_attr "alternative" "1")
16026            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16027               (const_string "ssemul")
16028               (const_string "sseadd"))
16029            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16030               (const_string "fmul")
16031               (const_string "fop"))))
16032    (set_attr "mode" "<MODE>")])
16033
16034 (define_insn "*fop_<mode>_comm_sse"
16035   [(set (match_operand:MODEF 0 "register_operand" "=x")
16036         (match_operator:MODEF 3 "binary_fp_operator"
16037           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16038            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16039   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16040    && COMMUTATIVE_ARITH_P (operands[3])
16041    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16042   "* return output_387_binary_op (insn, operands);"
16043   [(set (attr "type")
16044         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16045            (const_string "ssemul")
16046            (const_string "sseadd")))
16047    (set_attr "mode" "<MODE>")])
16048
16049 (define_insn "*fop_<mode>_comm_i387"
16050   [(set (match_operand:MODEF 0 "register_operand" "=f")
16051         (match_operator:MODEF 3 "binary_fp_operator"
16052           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16053            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16054   "TARGET_80387
16055    && COMMUTATIVE_ARITH_P (operands[3])
16056    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16057   "* return output_387_binary_op (insn, operands);"
16058   [(set (attr "type")
16059         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16060            (const_string "fmul")
16061            (const_string "fop")))
16062    (set_attr "mode" "<MODE>")])
16063
16064 (define_insn "*fop_<mode>_1_mixed"
16065   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16066         (match_operator:MODEF 3 "binary_fp_operator"
16067           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16068            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16069   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16070    && !COMMUTATIVE_ARITH_P (operands[3])
16071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16072   "* return output_387_binary_op (insn, operands);"
16073   [(set (attr "type")
16074         (cond [(and (eq_attr "alternative" "2")
16075                     (match_operand:MODEF 3 "mult_operator" ""))
16076                  (const_string "ssemul")
16077                (and (eq_attr "alternative" "2")
16078                     (match_operand:MODEF 3 "div_operator" ""))
16079                  (const_string "ssediv")
16080                (eq_attr "alternative" "2")
16081                  (const_string "sseadd")
16082                (match_operand:MODEF 3 "mult_operator" "")
16083                  (const_string "fmul")
16084                (match_operand:MODEF 3 "div_operator" "")
16085                  (const_string "fdiv")
16086               ]
16087               (const_string "fop")))
16088    (set_attr "mode" "<MODE>")])
16089
16090 (define_insn "*rcpsf2_sse"
16091   [(set (match_operand:SF 0 "register_operand" "=x")
16092         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16093                    UNSPEC_RCP))]
16094   "TARGET_SSE_MATH"
16095   "rcpss\t{%1, %0|%0, %1}"
16096   [(set_attr "type" "sse")
16097    (set_attr "mode" "SF")])
16098
16099 (define_insn "*fop_<mode>_1_sse"
16100   [(set (match_operand:MODEF 0 "register_operand" "=x")
16101         (match_operator:MODEF 3 "binary_fp_operator"
16102           [(match_operand:MODEF 1 "register_operand" "0")
16103            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16104   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16105    && !COMMUTATIVE_ARITH_P (operands[3])"
16106   "* return output_387_binary_op (insn, operands);"
16107   [(set (attr "type")
16108         (cond [(match_operand:MODEF 3 "mult_operator" "")
16109                  (const_string "ssemul")
16110                (match_operand:MODEF 3 "div_operator" "")
16111                  (const_string "ssediv")
16112               ]
16113               (const_string "sseadd")))
16114    (set_attr "mode" "<MODE>")])
16115
16116 ;; This pattern is not fully shadowed by the pattern above.
16117 (define_insn "*fop_<mode>_1_i387"
16118   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16119         (match_operator:MODEF 3 "binary_fp_operator"
16120           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16121            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16122   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16123    && !COMMUTATIVE_ARITH_P (operands[3])
16124    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16125   "* return output_387_binary_op (insn, operands);"
16126   [(set (attr "type")
16127         (cond [(match_operand:MODEF 3 "mult_operator" "")
16128                  (const_string "fmul")
16129                (match_operand:MODEF 3 "div_operator" "")
16130                  (const_string "fdiv")
16131               ]
16132               (const_string "fop")))
16133    (set_attr "mode" "<MODE>")])
16134
16135 ;; ??? Add SSE splitters for these!
16136 (define_insn "*fop_<MODEF:mode>_2_i387"
16137   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16138         (match_operator:MODEF 3 "binary_fp_operator"
16139           [(float:MODEF
16140              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16141            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16142   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16143    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16144   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16145   [(set (attr "type")
16146         (cond [(match_operand:MODEF 3 "mult_operator" "")
16147                  (const_string "fmul")
16148                (match_operand:MODEF 3 "div_operator" "")
16149                  (const_string "fdiv")
16150               ]
16151               (const_string "fop")))
16152    (set_attr "fp_int_src" "true")
16153    (set_attr "mode" "<X87MODEI12:MODE>")])
16154
16155 (define_insn "*fop_<MODEF:mode>_3_i387"
16156   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16157         (match_operator:MODEF 3 "binary_fp_operator"
16158           [(match_operand:MODEF 1 "register_operand" "0,0")
16159            (float:MODEF
16160              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16161   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16162    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16163   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16164   [(set (attr "type")
16165         (cond [(match_operand:MODEF 3 "mult_operator" "")
16166                  (const_string "fmul")
16167                (match_operand:MODEF 3 "div_operator" "")
16168                  (const_string "fdiv")
16169               ]
16170               (const_string "fop")))
16171    (set_attr "fp_int_src" "true")
16172    (set_attr "mode" "<MODE>")])
16173
16174 (define_insn "*fop_df_4_i387"
16175   [(set (match_operand:DF 0 "register_operand" "=f,f")
16176         (match_operator:DF 3 "binary_fp_operator"
16177            [(float_extend:DF
16178              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16179             (match_operand:DF 2 "register_operand" "0,f")]))]
16180   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16181    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16182   "* return output_387_binary_op (insn, operands);"
16183   [(set (attr "type")
16184         (cond [(match_operand:DF 3 "mult_operator" "")
16185                  (const_string "fmul")
16186                (match_operand:DF 3 "div_operator" "")
16187                  (const_string "fdiv")
16188               ]
16189               (const_string "fop")))
16190    (set_attr "mode" "SF")])
16191
16192 (define_insn "*fop_df_5_i387"
16193   [(set (match_operand:DF 0 "register_operand" "=f,f")
16194         (match_operator:DF 3 "binary_fp_operator"
16195           [(match_operand:DF 1 "register_operand" "0,f")
16196            (float_extend:DF
16197             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16198   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16199   "* return output_387_binary_op (insn, operands);"
16200   [(set (attr "type")
16201         (cond [(match_operand:DF 3 "mult_operator" "")
16202                  (const_string "fmul")
16203                (match_operand:DF 3 "div_operator" "")
16204                  (const_string "fdiv")
16205               ]
16206               (const_string "fop")))
16207    (set_attr "mode" "SF")])
16208
16209 (define_insn "*fop_df_6_i387"
16210   [(set (match_operand:DF 0 "register_operand" "=f,f")
16211         (match_operator:DF 3 "binary_fp_operator"
16212           [(float_extend:DF
16213             (match_operand:SF 1 "register_operand" "0,f"))
16214            (float_extend:DF
16215             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16216   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16217   "* return output_387_binary_op (insn, operands);"
16218   [(set (attr "type")
16219         (cond [(match_operand:DF 3 "mult_operator" "")
16220                  (const_string "fmul")
16221                (match_operand:DF 3 "div_operator" "")
16222                  (const_string "fdiv")
16223               ]
16224               (const_string "fop")))
16225    (set_attr "mode" "SF")])
16226
16227 (define_insn "*fop_xf_comm_i387"
16228   [(set (match_operand:XF 0 "register_operand" "=f")
16229         (match_operator:XF 3 "binary_fp_operator"
16230                         [(match_operand:XF 1 "register_operand" "%0")
16231                          (match_operand:XF 2 "register_operand" "f")]))]
16232   "TARGET_80387
16233    && COMMUTATIVE_ARITH_P (operands[3])"
16234   "* return output_387_binary_op (insn, operands);"
16235   [(set (attr "type")
16236         (if_then_else (match_operand:XF 3 "mult_operator" "")
16237            (const_string "fmul")
16238            (const_string "fop")))
16239    (set_attr "mode" "XF")])
16240
16241 (define_insn "*fop_xf_1_i387"
16242   [(set (match_operand:XF 0 "register_operand" "=f,f")
16243         (match_operator:XF 3 "binary_fp_operator"
16244                         [(match_operand:XF 1 "register_operand" "0,f")
16245                          (match_operand:XF 2 "register_operand" "f,0")]))]
16246   "TARGET_80387
16247    && !COMMUTATIVE_ARITH_P (operands[3])"
16248   "* return output_387_binary_op (insn, operands);"
16249   [(set (attr "type")
16250         (cond [(match_operand:XF 3 "mult_operator" "")
16251                  (const_string "fmul")
16252                (match_operand:XF 3 "div_operator" "")
16253                  (const_string "fdiv")
16254               ]
16255               (const_string "fop")))
16256    (set_attr "mode" "XF")])
16257
16258 (define_insn "*fop_xf_2_i387"
16259   [(set (match_operand:XF 0 "register_operand" "=f,f")
16260         (match_operator:XF 3 "binary_fp_operator"
16261           [(float:XF
16262              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16263            (match_operand:XF 2 "register_operand" "0,0")]))]
16264   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16265   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16266   [(set (attr "type")
16267         (cond [(match_operand:XF 3 "mult_operator" "")
16268                  (const_string "fmul")
16269                (match_operand:XF 3 "div_operator" "")
16270                  (const_string "fdiv")
16271               ]
16272               (const_string "fop")))
16273    (set_attr "fp_int_src" "true")
16274    (set_attr "mode" "<MODE>")])
16275
16276 (define_insn "*fop_xf_3_i387"
16277   [(set (match_operand:XF 0 "register_operand" "=f,f")
16278         (match_operator:XF 3 "binary_fp_operator"
16279           [(match_operand:XF 1 "register_operand" "0,0")
16280            (float:XF
16281              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16282   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16283   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16284   [(set (attr "type")
16285         (cond [(match_operand:XF 3 "mult_operator" "")
16286                  (const_string "fmul")
16287                (match_operand:XF 3 "div_operator" "")
16288                  (const_string "fdiv")
16289               ]
16290               (const_string "fop")))
16291    (set_attr "fp_int_src" "true")
16292    (set_attr "mode" "<MODE>")])
16293
16294 (define_insn "*fop_xf_4_i387"
16295   [(set (match_operand:XF 0 "register_operand" "=f,f")
16296         (match_operator:XF 3 "binary_fp_operator"
16297            [(float_extend:XF
16298               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16299             (match_operand:XF 2 "register_operand" "0,f")]))]
16300   "TARGET_80387"
16301   "* return output_387_binary_op (insn, operands);"
16302   [(set (attr "type")
16303         (cond [(match_operand:XF 3 "mult_operator" "")
16304                  (const_string "fmul")
16305                (match_operand:XF 3 "div_operator" "")
16306                  (const_string "fdiv")
16307               ]
16308               (const_string "fop")))
16309    (set_attr "mode" "<MODE>")])
16310
16311 (define_insn "*fop_xf_5_i387"
16312   [(set (match_operand:XF 0 "register_operand" "=f,f")
16313         (match_operator:XF 3 "binary_fp_operator"
16314           [(match_operand:XF 1 "register_operand" "0,f")
16315            (float_extend:XF
16316              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16317   "TARGET_80387"
16318   "* return output_387_binary_op (insn, operands);"
16319   [(set (attr "type")
16320         (cond [(match_operand:XF 3 "mult_operator" "")
16321                  (const_string "fmul")
16322                (match_operand:XF 3 "div_operator" "")
16323                  (const_string "fdiv")
16324               ]
16325               (const_string "fop")))
16326    (set_attr "mode" "<MODE>")])
16327
16328 (define_insn "*fop_xf_6_i387"
16329   [(set (match_operand:XF 0 "register_operand" "=f,f")
16330         (match_operator:XF 3 "binary_fp_operator"
16331           [(float_extend:XF
16332              (match_operand:MODEF 1 "register_operand" "0,f"))
16333            (float_extend:XF
16334              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16335   "TARGET_80387"
16336   "* return output_387_binary_op (insn, operands);"
16337   [(set (attr "type")
16338         (cond [(match_operand:XF 3 "mult_operator" "")
16339                  (const_string "fmul")
16340                (match_operand:XF 3 "div_operator" "")
16341                  (const_string "fdiv")
16342               ]
16343               (const_string "fop")))
16344    (set_attr "mode" "<MODE>")])
16345
16346 (define_split
16347   [(set (match_operand 0 "register_operand" "")
16348         (match_operator 3 "binary_fp_operator"
16349            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16350             (match_operand 2 "register_operand" "")]))]
16351   "reload_completed
16352    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16353   [(const_int 0)]
16354 {
16355   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16356   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16357   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16358                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16359                                           GET_MODE (operands[3]),
16360                                           operands[4],
16361                                           operands[2])));
16362   ix86_free_from_memory (GET_MODE (operands[1]));
16363   DONE;
16364 })
16365
16366 (define_split
16367   [(set (match_operand 0 "register_operand" "")
16368         (match_operator 3 "binary_fp_operator"
16369            [(match_operand 1 "register_operand" "")
16370             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16371   "reload_completed
16372    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16373   [(const_int 0)]
16374 {
16375   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16376   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16377   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16378                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16379                                           GET_MODE (operands[3]),
16380                                           operands[1],
16381                                           operands[4])));
16382   ix86_free_from_memory (GET_MODE (operands[2]));
16383   DONE;
16384 })
16385 \f
16386 ;; FPU special functions.
16387
16388 ;; This pattern implements a no-op XFmode truncation for
16389 ;; all fancy i386 XFmode math functions.
16390
16391 (define_insn "truncxf<mode>2_i387_noop_unspec"
16392   [(set (match_operand:MODEF 0 "register_operand" "=f")
16393         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16394         UNSPEC_TRUNC_NOOP))]
16395   "TARGET_USE_FANCY_MATH_387"
16396   "* return output_387_reg_move (insn, operands);"
16397   [(set_attr "type" "fmov")
16398    (set_attr "mode" "<MODE>")])
16399
16400 (define_insn "sqrtxf2"
16401   [(set (match_operand:XF 0 "register_operand" "=f")
16402         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16403   "TARGET_USE_FANCY_MATH_387"
16404   "fsqrt"
16405   [(set_attr "type" "fpspc")
16406    (set_attr "mode" "XF")
16407    (set_attr "athlon_decode" "direct")
16408    (set_attr "amdfam10_decode" "direct")])
16409
16410 (define_insn "sqrt_extend<mode>xf2_i387"
16411   [(set (match_operand:XF 0 "register_operand" "=f")
16412         (sqrt:XF
16413           (float_extend:XF
16414             (match_operand:MODEF 1 "register_operand" "0"))))]
16415   "TARGET_USE_FANCY_MATH_387"
16416   "fsqrt"
16417   [(set_attr "type" "fpspc")
16418    (set_attr "mode" "XF")
16419    (set_attr "athlon_decode" "direct")
16420    (set_attr "amdfam10_decode" "direct")])
16421
16422 (define_insn "*rsqrtsf2_sse"
16423   [(set (match_operand:SF 0 "register_operand" "=x")
16424         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16425                    UNSPEC_RSQRT))]
16426   "TARGET_SSE_MATH"
16427   "rsqrtss\t{%1, %0|%0, %1}"
16428   [(set_attr "type" "sse")
16429    (set_attr "mode" "SF")])
16430
16431 (define_expand "rsqrtsf2"
16432   [(set (match_operand:SF 0 "register_operand" "")
16433         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16434                    UNSPEC_RSQRT))]
16435   "TARGET_SSE_MATH"
16436 {
16437   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16438   DONE;
16439 })
16440
16441 (define_insn "*sqrt<mode>2_sse"
16442   [(set (match_operand:MODEF 0 "register_operand" "=x")
16443         (sqrt:MODEF
16444           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16445   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16446   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16447   [(set_attr "type" "sse")
16448    (set_attr "mode" "<MODE>")
16449    (set_attr "athlon_decode" "*")
16450    (set_attr "amdfam10_decode" "*")])
16451
16452 (define_expand "sqrt<mode>2"
16453   [(set (match_operand:MODEF 0 "register_operand" "")
16454         (sqrt:MODEF
16455           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16456   "TARGET_USE_FANCY_MATH_387
16457    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16458 {
16459   if (<MODE>mode == SFmode
16460       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16461       && flag_finite_math_only && !flag_trapping_math
16462       && flag_unsafe_math_optimizations)
16463     {
16464       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16465       DONE;
16466     }
16467
16468   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16469     {
16470       rtx op0 = gen_reg_rtx (XFmode);
16471       rtx op1 = force_reg (<MODE>mode, operands[1]);
16472
16473       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16474       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16475       DONE;
16476    }
16477 })
16478
16479 (define_insn "fpremxf4_i387"
16480   [(set (match_operand:XF 0 "register_operand" "=f")
16481         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16482                     (match_operand:XF 3 "register_operand" "1")]
16483                    UNSPEC_FPREM_F))
16484    (set (match_operand:XF 1 "register_operand" "=u")
16485         (unspec:XF [(match_dup 2) (match_dup 3)]
16486                    UNSPEC_FPREM_U))
16487    (set (reg:CCFP FPSR_REG)
16488         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16489                      UNSPEC_C2_FLAG))]
16490   "TARGET_USE_FANCY_MATH_387"
16491   "fprem"
16492   [(set_attr "type" "fpspc")
16493    (set_attr "mode" "XF")])
16494
16495 (define_expand "fmodxf3"
16496   [(use (match_operand:XF 0 "register_operand" ""))
16497    (use (match_operand:XF 1 "general_operand" ""))
16498    (use (match_operand:XF 2 "general_operand" ""))]
16499   "TARGET_USE_FANCY_MATH_387"
16500 {
16501   rtx label = gen_label_rtx ();
16502
16503   rtx op1 = gen_reg_rtx (XFmode);
16504   rtx op2 = gen_reg_rtx (XFmode);
16505
16506   emit_move_insn (op2, operands[2]);
16507   emit_move_insn (op1, operands[1]);
16508
16509   emit_label (label);
16510   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16511   ix86_emit_fp_unordered_jump (label);
16512   LABEL_NUSES (label) = 1;
16513
16514   emit_move_insn (operands[0], op1);
16515   DONE;
16516 })
16517
16518 (define_expand "fmod<mode>3"
16519   [(use (match_operand:MODEF 0 "register_operand" ""))
16520    (use (match_operand:MODEF 1 "general_operand" ""))
16521    (use (match_operand:MODEF 2 "general_operand" ""))]
16522   "TARGET_USE_FANCY_MATH_387"
16523 {
16524   rtx label = gen_label_rtx ();
16525
16526   rtx op1 = gen_reg_rtx (XFmode);
16527   rtx op2 = gen_reg_rtx (XFmode);
16528
16529   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16530   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16531
16532   emit_label (label);
16533   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16534   ix86_emit_fp_unordered_jump (label);
16535   LABEL_NUSES (label) = 1;
16536
16537   /* Truncate the result properly for strict SSE math.  */
16538   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16539       && !TARGET_MIX_SSE_I387)
16540     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16541   else
16542     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16543
16544   DONE;
16545 })
16546
16547 (define_insn "fprem1xf4_i387"
16548   [(set (match_operand:XF 0 "register_operand" "=f")
16549         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16550                     (match_operand:XF 3 "register_operand" "1")]
16551                    UNSPEC_FPREM1_F))
16552    (set (match_operand:XF 1 "register_operand" "=u")
16553         (unspec:XF [(match_dup 2) (match_dup 3)]
16554                    UNSPEC_FPREM1_U))
16555    (set (reg:CCFP FPSR_REG)
16556         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16557                      UNSPEC_C2_FLAG))]
16558   "TARGET_USE_FANCY_MATH_387"
16559   "fprem1"
16560   [(set_attr "type" "fpspc")
16561    (set_attr "mode" "XF")])
16562
16563 (define_expand "remainderxf3"
16564   [(use (match_operand:XF 0 "register_operand" ""))
16565    (use (match_operand:XF 1 "general_operand" ""))
16566    (use (match_operand:XF 2 "general_operand" ""))]
16567   "TARGET_USE_FANCY_MATH_387"
16568 {
16569   rtx label = gen_label_rtx ();
16570
16571   rtx op1 = gen_reg_rtx (XFmode);
16572   rtx op2 = gen_reg_rtx (XFmode);
16573
16574   emit_move_insn (op2, operands[2]);
16575   emit_move_insn (op1, operands[1]);
16576
16577   emit_label (label);
16578   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16579   ix86_emit_fp_unordered_jump (label);
16580   LABEL_NUSES (label) = 1;
16581
16582   emit_move_insn (operands[0], op1);
16583   DONE;
16584 })
16585
16586 (define_expand "remainder<mode>3"
16587   [(use (match_operand:MODEF 0 "register_operand" ""))
16588    (use (match_operand:MODEF 1 "general_operand" ""))
16589    (use (match_operand:MODEF 2 "general_operand" ""))]
16590   "TARGET_USE_FANCY_MATH_387"
16591 {
16592   rtx label = gen_label_rtx ();
16593
16594   rtx op1 = gen_reg_rtx (XFmode);
16595   rtx op2 = gen_reg_rtx (XFmode);
16596
16597   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16598   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16599
16600   emit_label (label);
16601
16602   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16603   ix86_emit_fp_unordered_jump (label);
16604   LABEL_NUSES (label) = 1;
16605
16606   /* Truncate the result properly for strict SSE math.  */
16607   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16608       && !TARGET_MIX_SSE_I387)
16609     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16610   else
16611     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16612
16613   DONE;
16614 })
16615
16616 (define_insn "*sinxf2_i387"
16617   [(set (match_operand:XF 0 "register_operand" "=f")
16618         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16619   "TARGET_USE_FANCY_MATH_387
16620    && flag_unsafe_math_optimizations"
16621   "fsin"
16622   [(set_attr "type" "fpspc")
16623    (set_attr "mode" "XF")])
16624
16625 (define_insn "*sin_extend<mode>xf2_i387"
16626   [(set (match_operand:XF 0 "register_operand" "=f")
16627         (unspec:XF [(float_extend:XF
16628                       (match_operand:MODEF 1 "register_operand" "0"))]
16629                    UNSPEC_SIN))]
16630   "TARGET_USE_FANCY_MATH_387
16631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632        || TARGET_MIX_SSE_I387)
16633    && flag_unsafe_math_optimizations"
16634   "fsin"
16635   [(set_attr "type" "fpspc")
16636    (set_attr "mode" "XF")])
16637
16638 (define_insn "*cosxf2_i387"
16639   [(set (match_operand:XF 0 "register_operand" "=f")
16640         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16641   "TARGET_USE_FANCY_MATH_387
16642    && flag_unsafe_math_optimizations"
16643   "fcos"
16644   [(set_attr "type" "fpspc")
16645    (set_attr "mode" "XF")])
16646
16647 (define_insn "*cos_extend<mode>xf2_i387"
16648   [(set (match_operand:XF 0 "register_operand" "=f")
16649         (unspec:XF [(float_extend:XF
16650                       (match_operand:MODEF 1 "register_operand" "0"))]
16651                    UNSPEC_COS))]
16652   "TARGET_USE_FANCY_MATH_387
16653    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16654        || TARGET_MIX_SSE_I387)
16655    && flag_unsafe_math_optimizations"
16656   "fcos"
16657   [(set_attr "type" "fpspc")
16658    (set_attr "mode" "XF")])
16659
16660 ;; When sincos pattern is defined, sin and cos builtin functions will be
16661 ;; expanded to sincos pattern with one of its outputs left unused.
16662 ;; CSE pass will figure out if two sincos patterns can be combined,
16663 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16664 ;; depending on the unused output.
16665
16666 (define_insn "sincosxf3"
16667   [(set (match_operand:XF 0 "register_operand" "=f")
16668         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16669                    UNSPEC_SINCOS_COS))
16670    (set (match_operand:XF 1 "register_operand" "=u")
16671         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16672   "TARGET_USE_FANCY_MATH_387
16673    && flag_unsafe_math_optimizations"
16674   "fsincos"
16675   [(set_attr "type" "fpspc")
16676    (set_attr "mode" "XF")])
16677
16678 (define_split
16679   [(set (match_operand:XF 0 "register_operand" "")
16680         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16681                    UNSPEC_SINCOS_COS))
16682    (set (match_operand:XF 1 "register_operand" "")
16683         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16684   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16685    && !(reload_completed || reload_in_progress)"
16686   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16687   "")
16688
16689 (define_split
16690   [(set (match_operand:XF 0 "register_operand" "")
16691         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16692                    UNSPEC_SINCOS_COS))
16693    (set (match_operand:XF 1 "register_operand" "")
16694         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16695   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16696    && !(reload_completed || reload_in_progress)"
16697   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16698   "")
16699
16700 (define_insn "sincos_extend<mode>xf3_i387"
16701   [(set (match_operand:XF 0 "register_operand" "=f")
16702         (unspec:XF [(float_extend:XF
16703                       (match_operand:MODEF 2 "register_operand" "0"))]
16704                    UNSPEC_SINCOS_COS))
16705    (set (match_operand:XF 1 "register_operand" "=u")
16706         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16707   "TARGET_USE_FANCY_MATH_387
16708    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16709        || TARGET_MIX_SSE_I387)
16710    && flag_unsafe_math_optimizations"
16711   "fsincos"
16712   [(set_attr "type" "fpspc")
16713    (set_attr "mode" "XF")])
16714
16715 (define_split
16716   [(set (match_operand:XF 0 "register_operand" "")
16717         (unspec:XF [(float_extend:XF
16718                       (match_operand:MODEF 2 "register_operand" ""))]
16719                    UNSPEC_SINCOS_COS))
16720    (set (match_operand:XF 1 "register_operand" "")
16721         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16722   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16723    && !(reload_completed || reload_in_progress)"
16724   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16725   "")
16726
16727 (define_split
16728   [(set (match_operand:XF 0 "register_operand" "")
16729         (unspec:XF [(float_extend:XF
16730                       (match_operand:MODEF 2 "register_operand" ""))]
16731                    UNSPEC_SINCOS_COS))
16732    (set (match_operand:XF 1 "register_operand" "")
16733         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16734   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16735    && !(reload_completed || reload_in_progress)"
16736   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16737   "")
16738
16739 (define_expand "sincos<mode>3"
16740   [(use (match_operand:MODEF 0 "register_operand" ""))
16741    (use (match_operand:MODEF 1 "register_operand" ""))
16742    (use (match_operand:MODEF 2 "register_operand" ""))]
16743   "TARGET_USE_FANCY_MATH_387
16744    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16745        || TARGET_MIX_SSE_I387)
16746    && flag_unsafe_math_optimizations"
16747 {
16748   rtx op0 = gen_reg_rtx (XFmode);
16749   rtx op1 = gen_reg_rtx (XFmode);
16750
16751   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16752   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16753   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16754   DONE;
16755 })
16756
16757 (define_insn "fptanxf4_i387"
16758   [(set (match_operand:XF 0 "register_operand" "=f")
16759         (match_operand:XF 3 "const_double_operand" "F"))
16760    (set (match_operand:XF 1 "register_operand" "=u")
16761         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16762                    UNSPEC_TAN))]
16763   "TARGET_USE_FANCY_MATH_387
16764    && flag_unsafe_math_optimizations
16765    && standard_80387_constant_p (operands[3]) == 2"
16766   "fptan"
16767   [(set_attr "type" "fpspc")
16768    (set_attr "mode" "XF")])
16769
16770 (define_insn "fptan_extend<mode>xf4_i387"
16771   [(set (match_operand:MODEF 0 "register_operand" "=f")
16772         (match_operand:MODEF 3 "const_double_operand" "F"))
16773    (set (match_operand:XF 1 "register_operand" "=u")
16774         (unspec:XF [(float_extend:XF
16775                       (match_operand:MODEF 2 "register_operand" "0"))]
16776                    UNSPEC_TAN))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16779        || TARGET_MIX_SSE_I387)
16780    && flag_unsafe_math_optimizations
16781    && standard_80387_constant_p (operands[3]) == 2"
16782   "fptan"
16783   [(set_attr "type" "fpspc")
16784    (set_attr "mode" "XF")])
16785
16786 (define_expand "tanxf2"
16787   [(use (match_operand:XF 0 "register_operand" ""))
16788    (use (match_operand:XF 1 "register_operand" ""))]
16789   "TARGET_USE_FANCY_MATH_387
16790    && flag_unsafe_math_optimizations"
16791 {
16792   rtx one = gen_reg_rtx (XFmode);
16793   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16794
16795   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16796   DONE;
16797 })
16798
16799 (define_expand "tan<mode>2"
16800   [(use (match_operand:MODEF 0 "register_operand" ""))
16801    (use (match_operand:MODEF 1 "register_operand" ""))]
16802   "TARGET_USE_FANCY_MATH_387
16803    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16804        || TARGET_MIX_SSE_I387)
16805    && flag_unsafe_math_optimizations"
16806 {
16807   rtx op0 = gen_reg_rtx (XFmode);
16808
16809   rtx one = gen_reg_rtx (<MODE>mode);
16810   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16811
16812   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16813                                              operands[1], op2));
16814   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16815   DONE;
16816 })
16817
16818 (define_insn "*fpatanxf3_i387"
16819   [(set (match_operand:XF 0 "register_operand" "=f")
16820         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16821                     (match_operand:XF 2 "register_operand" "u")]
16822                    UNSPEC_FPATAN))
16823    (clobber (match_scratch:XF 3 "=2"))]
16824   "TARGET_USE_FANCY_MATH_387
16825    && flag_unsafe_math_optimizations"
16826   "fpatan"
16827   [(set_attr "type" "fpspc")
16828    (set_attr "mode" "XF")])
16829
16830 (define_insn "fpatan_extend<mode>xf3_i387"
16831   [(set (match_operand:XF 0 "register_operand" "=f")
16832         (unspec:XF [(float_extend:XF
16833                       (match_operand:MODEF 1 "register_operand" "0"))
16834                     (float_extend:XF
16835                       (match_operand:MODEF 2 "register_operand" "u"))]
16836                    UNSPEC_FPATAN))
16837    (clobber (match_scratch:XF 3 "=2"))]
16838   "TARGET_USE_FANCY_MATH_387
16839    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16840        || TARGET_MIX_SSE_I387)
16841    && flag_unsafe_math_optimizations"
16842   "fpatan"
16843   [(set_attr "type" "fpspc")
16844    (set_attr "mode" "XF")])
16845
16846 (define_expand "atan2xf3"
16847   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16848                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16849                                (match_operand:XF 1 "register_operand" "")]
16850                               UNSPEC_FPATAN))
16851               (clobber (match_scratch:XF 3 ""))])]
16852   "TARGET_USE_FANCY_MATH_387
16853    && flag_unsafe_math_optimizations"
16854   "")
16855
16856 (define_expand "atan2<mode>3"
16857   [(use (match_operand:MODEF 0 "register_operand" ""))
16858    (use (match_operand:MODEF 1 "register_operand" ""))
16859    (use (match_operand:MODEF 2 "register_operand" ""))]
16860   "TARGET_USE_FANCY_MATH_387
16861    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16862        || TARGET_MIX_SSE_I387)
16863    && flag_unsafe_math_optimizations"
16864 {
16865   rtx op0 = gen_reg_rtx (XFmode);
16866
16867   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16868   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16869   DONE;
16870 })
16871
16872 (define_expand "atanxf2"
16873   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16874                    (unspec:XF [(match_dup 2)
16875                                (match_operand:XF 1 "register_operand" "")]
16876                               UNSPEC_FPATAN))
16877               (clobber (match_scratch:XF 3 ""))])]
16878   "TARGET_USE_FANCY_MATH_387
16879    && flag_unsafe_math_optimizations"
16880 {
16881   operands[2] = gen_reg_rtx (XFmode);
16882   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16883 })
16884
16885 (define_expand "atan<mode>2"
16886   [(use (match_operand:MODEF 0 "register_operand" ""))
16887    (use (match_operand:MODEF 1 "register_operand" ""))]
16888   "TARGET_USE_FANCY_MATH_387
16889    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16890        || TARGET_MIX_SSE_I387)
16891    && flag_unsafe_math_optimizations"
16892 {
16893   rtx op0 = gen_reg_rtx (XFmode);
16894
16895   rtx op2 = gen_reg_rtx (<MODE>mode);
16896   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16897
16898   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16899   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16900   DONE;
16901 })
16902
16903 (define_expand "asinxf2"
16904   [(set (match_dup 2)
16905         (mult:XF (match_operand:XF 1 "register_operand" "")
16906                  (match_dup 1)))
16907    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16908    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16909    (parallel [(set (match_operand:XF 0 "register_operand" "")
16910                    (unspec:XF [(match_dup 5) (match_dup 1)]
16911                               UNSPEC_FPATAN))
16912               (clobber (match_scratch:XF 6 ""))])]
16913   "TARGET_USE_FANCY_MATH_387
16914    && flag_unsafe_math_optimizations && !optimize_size"
16915 {
16916   int i;
16917
16918   for (i = 2; i < 6; i++)
16919     operands[i] = gen_reg_rtx (XFmode);
16920
16921   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16922 })
16923
16924 (define_expand "asin<mode>2"
16925   [(use (match_operand:MODEF 0 "register_operand" ""))
16926    (use (match_operand:MODEF 1 "general_operand" ""))]
16927  "TARGET_USE_FANCY_MATH_387
16928    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16929        || TARGET_MIX_SSE_I387)
16930    && flag_unsafe_math_optimizations && !optimize_size"
16931 {
16932   rtx op0 = gen_reg_rtx (XFmode);
16933   rtx op1 = gen_reg_rtx (XFmode);
16934
16935   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16936   emit_insn (gen_asinxf2 (op0, op1));
16937   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16938   DONE;
16939 })
16940
16941 (define_expand "acosxf2"
16942   [(set (match_dup 2)
16943         (mult:XF (match_operand:XF 1 "register_operand" "")
16944                  (match_dup 1)))
16945    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16946    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16947    (parallel [(set (match_operand:XF 0 "register_operand" "")
16948                    (unspec:XF [(match_dup 1) (match_dup 5)]
16949                               UNSPEC_FPATAN))
16950               (clobber (match_scratch:XF 6 ""))])]
16951   "TARGET_USE_FANCY_MATH_387
16952    && flag_unsafe_math_optimizations && !optimize_size"
16953 {
16954   int i;
16955
16956   for (i = 2; i < 6; i++)
16957     operands[i] = gen_reg_rtx (XFmode);
16958
16959   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16960 })
16961
16962 (define_expand "acos<mode>2"
16963   [(use (match_operand:MODEF 0 "register_operand" ""))
16964    (use (match_operand:MODEF 1 "general_operand" ""))]
16965  "TARGET_USE_FANCY_MATH_387
16966    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16967        || TARGET_MIX_SSE_I387)
16968    && flag_unsafe_math_optimizations && !optimize_size"
16969 {
16970   rtx op0 = gen_reg_rtx (XFmode);
16971   rtx op1 = gen_reg_rtx (XFmode);
16972
16973   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16974   emit_insn (gen_acosxf2 (op0, op1));
16975   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16976   DONE;
16977 })
16978
16979 (define_insn "fyl2xxf3_i387"
16980   [(set (match_operand:XF 0 "register_operand" "=f")
16981         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16982                     (match_operand:XF 2 "register_operand" "u")]
16983                    UNSPEC_FYL2X))
16984    (clobber (match_scratch:XF 3 "=2"))]
16985   "TARGET_USE_FANCY_MATH_387
16986    && flag_unsafe_math_optimizations"
16987   "fyl2x"
16988   [(set_attr "type" "fpspc")
16989    (set_attr "mode" "XF")])
16990
16991 (define_insn "fyl2x_extend<mode>xf3_i387"
16992   [(set (match_operand:XF 0 "register_operand" "=f")
16993         (unspec:XF [(float_extend:XF
16994                       (match_operand:MODEF 1 "register_operand" "0"))
16995                     (match_operand:XF 2 "register_operand" "u")]
16996                    UNSPEC_FYL2X))
16997    (clobber (match_scratch:XF 3 "=2"))]
16998   "TARGET_USE_FANCY_MATH_387
16999    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17000        || TARGET_MIX_SSE_I387)
17001    && flag_unsafe_math_optimizations"
17002   "fyl2x"
17003   [(set_attr "type" "fpspc")
17004    (set_attr "mode" "XF")])
17005
17006 (define_expand "logxf2"
17007   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17008                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17009                                (match_dup 2)] UNSPEC_FYL2X))
17010               (clobber (match_scratch:XF 3 ""))])]
17011   "TARGET_USE_FANCY_MATH_387
17012    && flag_unsafe_math_optimizations"
17013 {
17014   operands[2] = gen_reg_rtx (XFmode);
17015   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17016 })
17017
17018 (define_expand "log<mode>2"
17019   [(use (match_operand:MODEF 0 "register_operand" ""))
17020    (use (match_operand:MODEF 1 "register_operand" ""))]
17021   "TARGET_USE_FANCY_MATH_387
17022    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17023        || TARGET_MIX_SSE_I387)
17024    && flag_unsafe_math_optimizations"
17025 {
17026   rtx op0 = gen_reg_rtx (XFmode);
17027
17028   rtx op2 = gen_reg_rtx (XFmode);
17029   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17030
17031   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17032   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17033   DONE;
17034 })
17035
17036 (define_expand "log10xf2"
17037   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17038                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17039                                (match_dup 2)] UNSPEC_FYL2X))
17040               (clobber (match_scratch:XF 3 ""))])]
17041   "TARGET_USE_FANCY_MATH_387
17042    && flag_unsafe_math_optimizations"
17043 {
17044   operands[2] = gen_reg_rtx (XFmode);
17045   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17046 })
17047
17048 (define_expand "log10<mode>2"
17049   [(use (match_operand:MODEF 0 "register_operand" ""))
17050    (use (match_operand:MODEF 1 "register_operand" ""))]
17051   "TARGET_USE_FANCY_MATH_387
17052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053        || TARGET_MIX_SSE_I387)
17054    && flag_unsafe_math_optimizations"
17055 {
17056   rtx op0 = gen_reg_rtx (XFmode);
17057
17058   rtx op2 = gen_reg_rtx (XFmode);
17059   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17060
17061   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17062   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17063   DONE;
17064 })
17065
17066 (define_expand "log2xf2"
17067   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17068                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17069                                (match_dup 2)] UNSPEC_FYL2X))
17070               (clobber (match_scratch:XF 3 ""))])]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17073 {
17074   operands[2] = gen_reg_rtx (XFmode);
17075   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17076 })
17077
17078 (define_expand "log2<mode>2"
17079   [(use (match_operand:MODEF 0 "register_operand" ""))
17080    (use (match_operand:MODEF 1 "register_operand" ""))]
17081   "TARGET_USE_FANCY_MATH_387
17082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17083        || TARGET_MIX_SSE_I387)
17084    && flag_unsafe_math_optimizations"
17085 {
17086   rtx op0 = gen_reg_rtx (XFmode);
17087
17088   rtx op2 = gen_reg_rtx (XFmode);
17089   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17090
17091   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17093   DONE;
17094 })
17095
17096 (define_insn "fyl2xp1xf3_i387"
17097   [(set (match_operand:XF 0 "register_operand" "=f")
17098         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17099                     (match_operand:XF 2 "register_operand" "u")]
17100                    UNSPEC_FYL2XP1))
17101    (clobber (match_scratch:XF 3 "=2"))]
17102   "TARGET_USE_FANCY_MATH_387
17103    && flag_unsafe_math_optimizations"
17104   "fyl2xp1"
17105   [(set_attr "type" "fpspc")
17106    (set_attr "mode" "XF")])
17107
17108 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17109   [(set (match_operand:XF 0 "register_operand" "=f")
17110         (unspec:XF [(float_extend:XF
17111                       (match_operand:MODEF 1 "register_operand" "0"))
17112                     (match_operand:XF 2 "register_operand" "u")]
17113                    UNSPEC_FYL2XP1))
17114    (clobber (match_scratch:XF 3 "=2"))]
17115   "TARGET_USE_FANCY_MATH_387
17116    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17117        || TARGET_MIX_SSE_I387)
17118    && flag_unsafe_math_optimizations"
17119   "fyl2xp1"
17120   [(set_attr "type" "fpspc")
17121    (set_attr "mode" "XF")])
17122
17123 (define_expand "log1pxf2"
17124   [(use (match_operand:XF 0 "register_operand" ""))
17125    (use (match_operand:XF 1 "register_operand" ""))]
17126   "TARGET_USE_FANCY_MATH_387
17127    && flag_unsafe_math_optimizations && !optimize_size"
17128 {
17129   ix86_emit_i387_log1p (operands[0], operands[1]);
17130   DONE;
17131 })
17132
17133 (define_expand "log1p<mode>2"
17134   [(use (match_operand:MODEF 0 "register_operand" ""))
17135    (use (match_operand:MODEF 1 "register_operand" ""))]
17136   "TARGET_USE_FANCY_MATH_387
17137    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17138        || TARGET_MIX_SSE_I387)
17139    && flag_unsafe_math_optimizations && !optimize_size"
17140 {
17141   rtx op0 = gen_reg_rtx (XFmode);
17142
17143   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17144
17145   ix86_emit_i387_log1p (op0, operands[1]);
17146   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17147   DONE;
17148 })
17149
17150 (define_insn "fxtractxf3_i387"
17151   [(set (match_operand:XF 0 "register_operand" "=f")
17152         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17153                    UNSPEC_XTRACT_FRACT))
17154    (set (match_operand:XF 1 "register_operand" "=u")
17155         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17156   "TARGET_USE_FANCY_MATH_387
17157    && flag_unsafe_math_optimizations"
17158   "fxtract"
17159   [(set_attr "type" "fpspc")
17160    (set_attr "mode" "XF")])
17161
17162 (define_insn "fxtract_extend<mode>xf3_i387"
17163   [(set (match_operand:XF 0 "register_operand" "=f")
17164         (unspec:XF [(float_extend:XF
17165                       (match_operand:MODEF 2 "register_operand" "0"))]
17166                    UNSPEC_XTRACT_FRACT))
17167    (set (match_operand:XF 1 "register_operand" "=u")
17168         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17169   "TARGET_USE_FANCY_MATH_387
17170    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17171        || TARGET_MIX_SSE_I387)
17172    && flag_unsafe_math_optimizations"
17173   "fxtract"
17174   [(set_attr "type" "fpspc")
17175    (set_attr "mode" "XF")])
17176
17177 (define_expand "logbxf2"
17178   [(parallel [(set (match_dup 2)
17179                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17180                               UNSPEC_XTRACT_FRACT))
17181               (set (match_operand:XF 0 "register_operand" "")
17182                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17183   "TARGET_USE_FANCY_MATH_387
17184    && flag_unsafe_math_optimizations"
17185 {
17186   operands[2] = gen_reg_rtx (XFmode);
17187 })
17188
17189 (define_expand "logb<mode>2"
17190   [(use (match_operand:MODEF 0 "register_operand" ""))
17191    (use (match_operand:MODEF 1 "register_operand" ""))]
17192   "TARGET_USE_FANCY_MATH_387
17193    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17194        || TARGET_MIX_SSE_I387)
17195    && flag_unsafe_math_optimizations"
17196 {
17197   rtx op0 = gen_reg_rtx (XFmode);
17198   rtx op1 = gen_reg_rtx (XFmode);
17199
17200   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17201   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17202   DONE;
17203 })
17204
17205 (define_expand "ilogbxf2"
17206   [(use (match_operand:SI 0 "register_operand" ""))
17207    (use (match_operand:XF 1 "register_operand" ""))]
17208   "TARGET_USE_FANCY_MATH_387
17209    && flag_unsafe_math_optimizations && !optimize_size"
17210 {
17211   rtx op0 = gen_reg_rtx (XFmode);
17212   rtx op1 = gen_reg_rtx (XFmode);
17213
17214   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17215   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17216   DONE;
17217 })
17218
17219 (define_expand "ilogb<mode>2"
17220   [(use (match_operand:SI 0 "register_operand" ""))
17221    (use (match_operand:MODEF 1 "register_operand" ""))]
17222   "TARGET_USE_FANCY_MATH_387
17223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224        || TARGET_MIX_SSE_I387)
17225    && flag_unsafe_math_optimizations && !optimize_size"
17226 {
17227   rtx op0 = gen_reg_rtx (XFmode);
17228   rtx op1 = gen_reg_rtx (XFmode);
17229
17230   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17231   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17232   DONE;
17233 })
17234
17235 (define_insn "*f2xm1xf2_i387"
17236   [(set (match_operand:XF 0 "register_operand" "=f")
17237         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17238                    UNSPEC_F2XM1))]
17239   "TARGET_USE_FANCY_MATH_387
17240    && flag_unsafe_math_optimizations"
17241   "f2xm1"
17242   [(set_attr "type" "fpspc")
17243    (set_attr "mode" "XF")])
17244
17245 (define_insn "*fscalexf4_i387"
17246   [(set (match_operand:XF 0 "register_operand" "=f")
17247         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17248                     (match_operand:XF 3 "register_operand" "1")]
17249                    UNSPEC_FSCALE_FRACT))
17250    (set (match_operand:XF 1 "register_operand" "=u")
17251         (unspec:XF [(match_dup 2) (match_dup 3)]
17252                    UNSPEC_FSCALE_EXP))]
17253   "TARGET_USE_FANCY_MATH_387
17254    && flag_unsafe_math_optimizations"
17255   "fscale"
17256   [(set_attr "type" "fpspc")
17257    (set_attr "mode" "XF")])
17258
17259 (define_expand "expNcorexf3"
17260   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17261                                (match_operand:XF 2 "register_operand" "")))
17262    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17263    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17264    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17265    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17266    (parallel [(set (match_operand:XF 0 "register_operand" "")
17267                    (unspec:XF [(match_dup 8) (match_dup 4)]
17268                               UNSPEC_FSCALE_FRACT))
17269               (set (match_dup 9)
17270                    (unspec:XF [(match_dup 8) (match_dup 4)]
17271                               UNSPEC_FSCALE_EXP))])]
17272   "TARGET_USE_FANCY_MATH_387
17273    && flag_unsafe_math_optimizations && !optimize_size"
17274 {
17275   int i;
17276
17277   for (i = 3; i < 10; i++)
17278     operands[i] = gen_reg_rtx (XFmode);
17279
17280   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17281 })
17282
17283 (define_expand "expxf2"
17284   [(use (match_operand:XF 0 "register_operand" ""))
17285    (use (match_operand:XF 1 "register_operand" ""))]
17286   "TARGET_USE_FANCY_MATH_387
17287    && flag_unsafe_math_optimizations && !optimize_size"
17288 {
17289   rtx op2 = gen_reg_rtx (XFmode);
17290   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17291
17292   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17293   DONE;
17294 })
17295
17296 (define_expand "exp<mode>2"
17297   [(use (match_operand:MODEF 0 "register_operand" ""))
17298    (use (match_operand:MODEF 1 "general_operand" ""))]
17299  "TARGET_USE_FANCY_MATH_387
17300    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17301        || TARGET_MIX_SSE_I387)
17302    && flag_unsafe_math_optimizations && !optimize_size"
17303 {
17304   rtx op0 = gen_reg_rtx (XFmode);
17305   rtx op1 = gen_reg_rtx (XFmode);
17306
17307   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17308   emit_insn (gen_expxf2 (op0, op1));
17309   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17310   DONE;
17311 })
17312
17313 (define_expand "exp10xf2"
17314   [(use (match_operand:XF 0 "register_operand" ""))
17315    (use (match_operand:XF 1 "register_operand" ""))]
17316   "TARGET_USE_FANCY_MATH_387
17317    && flag_unsafe_math_optimizations && !optimize_size"
17318 {
17319   rtx op2 = gen_reg_rtx (XFmode);
17320   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17321
17322   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17323   DONE;
17324 })
17325
17326 (define_expand "exp10<mode>2"
17327   [(use (match_operand:MODEF 0 "register_operand" ""))
17328    (use (match_operand:MODEF 1 "general_operand" ""))]
17329  "TARGET_USE_FANCY_MATH_387
17330    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17331        || TARGET_MIX_SSE_I387)
17332    && flag_unsafe_math_optimizations && !optimize_size"
17333 {
17334   rtx op0 = gen_reg_rtx (XFmode);
17335   rtx op1 = gen_reg_rtx (XFmode);
17336
17337   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17338   emit_insn (gen_exp10xf2 (op0, op1));
17339   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17340   DONE;
17341 })
17342
17343 (define_expand "exp2xf2"
17344   [(use (match_operand:XF 0 "register_operand" ""))
17345    (use (match_operand:XF 1 "register_operand" ""))]
17346   "TARGET_USE_FANCY_MATH_387
17347    && flag_unsafe_math_optimizations && !optimize_size"
17348 {
17349   rtx op2 = gen_reg_rtx (XFmode);
17350   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17351
17352   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17353   DONE;
17354 })
17355
17356 (define_expand "exp2<mode>2"
17357   [(use (match_operand:MODEF 0 "register_operand" ""))
17358    (use (match_operand:MODEF 1 "general_operand" ""))]
17359  "TARGET_USE_FANCY_MATH_387
17360    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17361        || TARGET_MIX_SSE_I387)
17362    && flag_unsafe_math_optimizations && !optimize_size"
17363 {
17364   rtx op0 = gen_reg_rtx (XFmode);
17365   rtx op1 = gen_reg_rtx (XFmode);
17366
17367   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17368   emit_insn (gen_exp2xf2 (op0, op1));
17369   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17370   DONE;
17371 })
17372
17373 (define_expand "expm1xf2"
17374   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17375                                (match_dup 2)))
17376    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17377    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17378    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17379    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17380    (parallel [(set (match_dup 7)
17381                    (unspec:XF [(match_dup 6) (match_dup 4)]
17382                               UNSPEC_FSCALE_FRACT))
17383               (set (match_dup 8)
17384                    (unspec:XF [(match_dup 6) (match_dup 4)]
17385                               UNSPEC_FSCALE_EXP))])
17386    (parallel [(set (match_dup 10)
17387                    (unspec:XF [(match_dup 9) (match_dup 8)]
17388                               UNSPEC_FSCALE_FRACT))
17389               (set (match_dup 11)
17390                    (unspec:XF [(match_dup 9) (match_dup 8)]
17391                               UNSPEC_FSCALE_EXP))])
17392    (set (match_dup 12) (minus:XF (match_dup 10)
17393                                  (float_extend:XF (match_dup 13))))
17394    (set (match_operand:XF 0 "register_operand" "")
17395         (plus:XF (match_dup 12) (match_dup 7)))]
17396   "TARGET_USE_FANCY_MATH_387
17397    && flag_unsafe_math_optimizations && !optimize_size"
17398 {
17399   int i;
17400
17401   for (i = 2; i < 13; i++)
17402     operands[i] = gen_reg_rtx (XFmode);
17403
17404   operands[13]
17405     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17406
17407   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17408 })
17409
17410 (define_expand "expm1<mode>2"
17411   [(use (match_operand:MODEF 0 "register_operand" ""))
17412    (use (match_operand:MODEF 1 "general_operand" ""))]
17413  "TARGET_USE_FANCY_MATH_387
17414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17415        || TARGET_MIX_SSE_I387)
17416    && flag_unsafe_math_optimizations && !optimize_size"
17417 {
17418   rtx op0 = gen_reg_rtx (XFmode);
17419   rtx op1 = gen_reg_rtx (XFmode);
17420
17421   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17422   emit_insn (gen_expm1xf2 (op0, op1));
17423   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17424   DONE;
17425 })
17426
17427 (define_expand "ldexpxf3"
17428   [(set (match_dup 3)
17429         (float:XF (match_operand:SI 2 "register_operand" "")))
17430    (parallel [(set (match_operand:XF 0 " register_operand" "")
17431                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17432                                (match_dup 3)]
17433                               UNSPEC_FSCALE_FRACT))
17434               (set (match_dup 4)
17435                    (unspec:XF [(match_dup 1) (match_dup 3)]
17436                               UNSPEC_FSCALE_EXP))])]
17437   "TARGET_USE_FANCY_MATH_387
17438    && flag_unsafe_math_optimizations && !optimize_size"
17439 {
17440   operands[3] = gen_reg_rtx (XFmode);
17441   operands[4] = gen_reg_rtx (XFmode);
17442 })
17443
17444 (define_expand "ldexp<mode>3"
17445   [(use (match_operand:MODEF 0 "register_operand" ""))
17446    (use (match_operand:MODEF 1 "general_operand" ""))
17447    (use (match_operand:SI 2 "register_operand" ""))]
17448  "TARGET_USE_FANCY_MATH_387
17449    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17450        || TARGET_MIX_SSE_I387)
17451    && flag_unsafe_math_optimizations && !optimize_size"
17452 {
17453   rtx op0 = gen_reg_rtx (XFmode);
17454   rtx op1 = gen_reg_rtx (XFmode);
17455
17456   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17457   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17458   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17459   DONE;
17460 })
17461
17462 (define_expand "scalbxf3"
17463   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17464                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17465                                (match_operand:XF 2 "register_operand" "")]
17466                               UNSPEC_FSCALE_FRACT))
17467               (set (match_dup 3)
17468                    (unspec:XF [(match_dup 1) (match_dup 2)]
17469                               UNSPEC_FSCALE_EXP))])]
17470   "TARGET_USE_FANCY_MATH_387
17471    && flag_unsafe_math_optimizations && !optimize_size"
17472 {
17473   operands[3] = gen_reg_rtx (XFmode);
17474 })
17475
17476 (define_expand "scalb<mode>3"
17477   [(use (match_operand:MODEF 0 "register_operand" ""))
17478    (use (match_operand:MODEF 1 "general_operand" ""))
17479    (use (match_operand:MODEF 2 "register_operand" ""))]
17480  "TARGET_USE_FANCY_MATH_387
17481    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17482        || TARGET_MIX_SSE_I387)
17483    && flag_unsafe_math_optimizations && !optimize_size"
17484 {
17485   rtx op0 = gen_reg_rtx (XFmode);
17486   rtx op1 = gen_reg_rtx (XFmode);
17487   rtx op2 = gen_reg_rtx (XFmode);
17488
17489   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17490   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17491   emit_insn (gen_scalbxf3 (op0, op1, op2));
17492   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17493   DONE;
17494 })
17495 \f
17496
17497 (define_insn "sse4_1_round<mode>2"
17498   [(set (match_operand:MODEF 0 "register_operand" "=x")
17499         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17500                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17501                       UNSPEC_ROUND))]
17502   "TARGET_ROUND"
17503   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17504   [(set_attr "type" "ssecvt")
17505    (set_attr "prefix_extra" "1")
17506    (set_attr "mode" "<MODE>")])
17507
17508 (define_insn "rintxf2"
17509   [(set (match_operand:XF 0 "register_operand" "=f")
17510         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17511                    UNSPEC_FRNDINT))]
17512   "TARGET_USE_FANCY_MATH_387
17513    && flag_unsafe_math_optimizations"
17514   "frndint"
17515   [(set_attr "type" "fpspc")
17516    (set_attr "mode" "XF")])
17517
17518 (define_expand "rint<mode>2"
17519   [(use (match_operand:MODEF 0 "register_operand" ""))
17520    (use (match_operand:MODEF 1 "register_operand" ""))]
17521   "(TARGET_USE_FANCY_MATH_387
17522     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17523         || TARGET_MIX_SSE_I387)
17524     && flag_unsafe_math_optimizations)
17525    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17526        && !flag_trapping_math
17527        && (TARGET_ROUND || !optimize_size))"
17528 {
17529   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17530       && !flag_trapping_math
17531       && (TARGET_ROUND || !optimize_size))
17532     {
17533       if (TARGET_ROUND)
17534         emit_insn (gen_sse4_1_round<mode>2
17535                    (operands[0], operands[1], GEN_INT (0x04)));
17536       else
17537         ix86_expand_rint (operand0, operand1);
17538     }
17539   else
17540     {
17541       rtx op0 = gen_reg_rtx (XFmode);
17542       rtx op1 = gen_reg_rtx (XFmode);
17543
17544       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17545       emit_insn (gen_rintxf2 (op0, op1));
17546
17547       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17548     }
17549   DONE;
17550 })
17551
17552 (define_expand "round<mode>2"
17553   [(match_operand:MODEF 0 "register_operand" "")
17554    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17555   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17556    && !flag_trapping_math && !flag_rounding_math
17557    && !optimize_size"
17558 {
17559   if (TARGET_64BIT || (<MODE>mode != DFmode))
17560     ix86_expand_round (operand0, operand1);
17561   else
17562     ix86_expand_rounddf_32 (operand0, operand1);
17563   DONE;
17564 })
17565
17566 (define_insn_and_split "*fistdi2_1"
17567   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17568         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17569                    UNSPEC_FIST))]
17570   "TARGET_USE_FANCY_MATH_387
17571    && !(reload_completed || reload_in_progress)"
17572   "#"
17573   "&& 1"
17574   [(const_int 0)]
17575 {
17576   if (memory_operand (operands[0], VOIDmode))
17577     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17578   else
17579     {
17580       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17581       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17582                                          operands[2]));
17583     }
17584   DONE;
17585 }
17586   [(set_attr "type" "fpspc")
17587    (set_attr "mode" "DI")])
17588
17589 (define_insn "fistdi2"
17590   [(set (match_operand:DI 0 "memory_operand" "=m")
17591         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17592                    UNSPEC_FIST))
17593    (clobber (match_scratch:XF 2 "=&1f"))]
17594   "TARGET_USE_FANCY_MATH_387"
17595   "* return output_fix_trunc (insn, operands, 0);"
17596   [(set_attr "type" "fpspc")
17597    (set_attr "mode" "DI")])
17598
17599 (define_insn "fistdi2_with_temp"
17600   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17601         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17602                    UNSPEC_FIST))
17603    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17604    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17605   "TARGET_USE_FANCY_MATH_387"
17606   "#"
17607   [(set_attr "type" "fpspc")
17608    (set_attr "mode" "DI")])
17609
17610 (define_split
17611   [(set (match_operand:DI 0 "register_operand" "")
17612         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17613                    UNSPEC_FIST))
17614    (clobber (match_operand:DI 2 "memory_operand" ""))
17615    (clobber (match_scratch 3 ""))]
17616   "reload_completed"
17617   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17618               (clobber (match_dup 3))])
17619    (set (match_dup 0) (match_dup 2))]
17620   "")
17621
17622 (define_split
17623   [(set (match_operand:DI 0 "memory_operand" "")
17624         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17625                    UNSPEC_FIST))
17626    (clobber (match_operand:DI 2 "memory_operand" ""))
17627    (clobber (match_scratch 3 ""))]
17628   "reload_completed"
17629   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17630               (clobber (match_dup 3))])]
17631   "")
17632
17633 (define_insn_and_split "*fist<mode>2_1"
17634   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17635         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17636                            UNSPEC_FIST))]
17637   "TARGET_USE_FANCY_MATH_387
17638    && !(reload_completed || reload_in_progress)"
17639   "#"
17640   "&& 1"
17641   [(const_int 0)]
17642 {
17643   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17644   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17645                                         operands[2]));
17646   DONE;
17647 }
17648   [(set_attr "type" "fpspc")
17649    (set_attr "mode" "<MODE>")])
17650
17651 (define_insn "fist<mode>2"
17652   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17653         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17654                            UNSPEC_FIST))]
17655   "TARGET_USE_FANCY_MATH_387"
17656   "* return output_fix_trunc (insn, operands, 0);"
17657   [(set_attr "type" "fpspc")
17658    (set_attr "mode" "<MODE>")])
17659
17660 (define_insn "fist<mode>2_with_temp"
17661   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17662         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17663                            UNSPEC_FIST))
17664    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17665   "TARGET_USE_FANCY_MATH_387"
17666   "#"
17667   [(set_attr "type" "fpspc")
17668    (set_attr "mode" "<MODE>")])
17669
17670 (define_split
17671   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17672         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17673                            UNSPEC_FIST))
17674    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17675   "reload_completed"
17676   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17677    (set (match_dup 0) (match_dup 2))]
17678   "")
17679
17680 (define_split
17681   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17682         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17683                            UNSPEC_FIST))
17684    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17685   "reload_completed"
17686   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17687   "")
17688
17689 (define_expand "lrintxf<mode>2"
17690   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17691      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17692                       UNSPEC_FIST))]
17693   "TARGET_USE_FANCY_MATH_387"
17694   "")
17695
17696 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17697   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17698      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17699                         UNSPEC_FIX_NOTRUNC))]
17700   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17701    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17702   "")
17703
17704 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17705   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17706    (match_operand:MODEF 1 "register_operand" "")]
17707   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17708    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17709    && !flag_trapping_math && !flag_rounding_math
17710    && !optimize_size"
17711 {
17712   ix86_expand_lround (operand0, operand1);
17713   DONE;
17714 })
17715
17716 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17717 (define_insn_and_split "frndintxf2_floor"
17718   [(set (match_operand:XF 0 "register_operand" "")
17719         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17720          UNSPEC_FRNDINT_FLOOR))
17721    (clobber (reg:CC FLAGS_REG))]
17722   "TARGET_USE_FANCY_MATH_387
17723    && flag_unsafe_math_optimizations
17724    && !(reload_completed || reload_in_progress)"
17725   "#"
17726   "&& 1"
17727   [(const_int 0)]
17728 {
17729   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17730
17731   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17732   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17733
17734   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17735                                         operands[2], operands[3]));
17736   DONE;
17737 }
17738   [(set_attr "type" "frndint")
17739    (set_attr "i387_cw" "floor")
17740    (set_attr "mode" "XF")])
17741
17742 (define_insn "frndintxf2_floor_i387"
17743   [(set (match_operand:XF 0 "register_operand" "=f")
17744         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17745          UNSPEC_FRNDINT_FLOOR))
17746    (use (match_operand:HI 2 "memory_operand" "m"))
17747    (use (match_operand:HI 3 "memory_operand" "m"))]
17748   "TARGET_USE_FANCY_MATH_387
17749    && flag_unsafe_math_optimizations"
17750   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17751   [(set_attr "type" "frndint")
17752    (set_attr "i387_cw" "floor")
17753    (set_attr "mode" "XF")])
17754
17755 (define_expand "floorxf2"
17756   [(use (match_operand:XF 0 "register_operand" ""))
17757    (use (match_operand:XF 1 "register_operand" ""))]
17758   "TARGET_USE_FANCY_MATH_387
17759    && flag_unsafe_math_optimizations && !optimize_size"
17760 {
17761   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17762   DONE;
17763 })
17764
17765 (define_expand "floor<mode>2"
17766   [(use (match_operand:MODEF 0 "register_operand" ""))
17767    (use (match_operand:MODEF 1 "register_operand" ""))]
17768   "(TARGET_USE_FANCY_MATH_387
17769     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17770         || TARGET_MIX_SSE_I387)
17771     && flag_unsafe_math_optimizations && !optimize_size)
17772    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17773        && !flag_trapping_math
17774        && (TARGET_ROUND || !optimize_size))"
17775 {
17776   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17777       && !flag_trapping_math
17778       && (TARGET_ROUND || !optimize_size))
17779     {
17780       if (TARGET_ROUND)
17781         emit_insn (gen_sse4_1_round<mode>2
17782                    (operands[0], operands[1], GEN_INT (0x01)));
17783       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17784         ix86_expand_floorceil (operand0, operand1, true);
17785       else
17786         ix86_expand_floorceildf_32 (operand0, operand1, true);
17787     }
17788   else
17789     {
17790       rtx op0 = gen_reg_rtx (XFmode);
17791       rtx op1 = gen_reg_rtx (XFmode);
17792
17793       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17794       emit_insn (gen_frndintxf2_floor (op0, op1));
17795
17796       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17797     }
17798   DONE;
17799 })
17800
17801 (define_insn_and_split "*fist<mode>2_floor_1"
17802   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17803         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17804          UNSPEC_FIST_FLOOR))
17805    (clobber (reg:CC FLAGS_REG))]
17806   "TARGET_USE_FANCY_MATH_387
17807    && flag_unsafe_math_optimizations
17808    && !(reload_completed || reload_in_progress)"
17809   "#"
17810   "&& 1"
17811   [(const_int 0)]
17812 {
17813   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17814
17815   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17816   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17817   if (memory_operand (operands[0], VOIDmode))
17818     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17819                                       operands[2], operands[3]));
17820   else
17821     {
17822       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17823       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17824                                                   operands[2], operands[3],
17825                                                   operands[4]));
17826     }
17827   DONE;
17828 }
17829   [(set_attr "type" "fistp")
17830    (set_attr "i387_cw" "floor")
17831    (set_attr "mode" "<MODE>")])
17832
17833 (define_insn "fistdi2_floor"
17834   [(set (match_operand:DI 0 "memory_operand" "=m")
17835         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17836          UNSPEC_FIST_FLOOR))
17837    (use (match_operand:HI 2 "memory_operand" "m"))
17838    (use (match_operand:HI 3 "memory_operand" "m"))
17839    (clobber (match_scratch:XF 4 "=&1f"))]
17840   "TARGET_USE_FANCY_MATH_387
17841    && flag_unsafe_math_optimizations"
17842   "* return output_fix_trunc (insn, operands, 0);"
17843   [(set_attr "type" "fistp")
17844    (set_attr "i387_cw" "floor")
17845    (set_attr "mode" "DI")])
17846
17847 (define_insn "fistdi2_floor_with_temp"
17848   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17849         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17850          UNSPEC_FIST_FLOOR))
17851    (use (match_operand:HI 2 "memory_operand" "m,m"))
17852    (use (match_operand:HI 3 "memory_operand" "m,m"))
17853    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17854    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17855   "TARGET_USE_FANCY_MATH_387
17856    && flag_unsafe_math_optimizations"
17857   "#"
17858   [(set_attr "type" "fistp")
17859    (set_attr "i387_cw" "floor")
17860    (set_attr "mode" "DI")])
17861
17862 (define_split
17863   [(set (match_operand:DI 0 "register_operand" "")
17864         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17865          UNSPEC_FIST_FLOOR))
17866    (use (match_operand:HI 2 "memory_operand" ""))
17867    (use (match_operand:HI 3 "memory_operand" ""))
17868    (clobber (match_operand:DI 4 "memory_operand" ""))
17869    (clobber (match_scratch 5 ""))]
17870   "reload_completed"
17871   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17872               (use (match_dup 2))
17873               (use (match_dup 3))
17874               (clobber (match_dup 5))])
17875    (set (match_dup 0) (match_dup 4))]
17876   "")
17877
17878 (define_split
17879   [(set (match_operand:DI 0 "memory_operand" "")
17880         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17881          UNSPEC_FIST_FLOOR))
17882    (use (match_operand:HI 2 "memory_operand" ""))
17883    (use (match_operand:HI 3 "memory_operand" ""))
17884    (clobber (match_operand:DI 4 "memory_operand" ""))
17885    (clobber (match_scratch 5 ""))]
17886   "reload_completed"
17887   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17888               (use (match_dup 2))
17889               (use (match_dup 3))
17890               (clobber (match_dup 5))])]
17891   "")
17892
17893 (define_insn "fist<mode>2_floor"
17894   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17895         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17896          UNSPEC_FIST_FLOOR))
17897    (use (match_operand:HI 2 "memory_operand" "m"))
17898    (use (match_operand:HI 3 "memory_operand" "m"))]
17899   "TARGET_USE_FANCY_MATH_387
17900    && flag_unsafe_math_optimizations"
17901   "* return output_fix_trunc (insn, operands, 0);"
17902   [(set_attr "type" "fistp")
17903    (set_attr "i387_cw" "floor")
17904    (set_attr "mode" "<MODE>")])
17905
17906 (define_insn "fist<mode>2_floor_with_temp"
17907   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17908         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17909          UNSPEC_FIST_FLOOR))
17910    (use (match_operand:HI 2 "memory_operand" "m,m"))
17911    (use (match_operand:HI 3 "memory_operand" "m,m"))
17912    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17913   "TARGET_USE_FANCY_MATH_387
17914    && flag_unsafe_math_optimizations"
17915   "#"
17916   [(set_attr "type" "fistp")
17917    (set_attr "i387_cw" "floor")
17918    (set_attr "mode" "<MODE>")])
17919
17920 (define_split
17921   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17922         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17923          UNSPEC_FIST_FLOOR))
17924    (use (match_operand:HI 2 "memory_operand" ""))
17925    (use (match_operand:HI 3 "memory_operand" ""))
17926    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17927   "reload_completed"
17928   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17929                                   UNSPEC_FIST_FLOOR))
17930               (use (match_dup 2))
17931               (use (match_dup 3))])
17932    (set (match_dup 0) (match_dup 4))]
17933   "")
17934
17935 (define_split
17936   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17937         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17938          UNSPEC_FIST_FLOOR))
17939    (use (match_operand:HI 2 "memory_operand" ""))
17940    (use (match_operand:HI 3 "memory_operand" ""))
17941    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17942   "reload_completed"
17943   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17944                                   UNSPEC_FIST_FLOOR))
17945               (use (match_dup 2))
17946               (use (match_dup 3))])]
17947   "")
17948
17949 (define_expand "lfloorxf<mode>2"
17950   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17951                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17952                     UNSPEC_FIST_FLOOR))
17953               (clobber (reg:CC FLAGS_REG))])]
17954   "TARGET_USE_FANCY_MATH_387
17955    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17956    && flag_unsafe_math_optimizations"
17957   "")
17958
17959 (define_expand "lfloor<mode>di2"
17960   [(match_operand:DI 0 "nonimmediate_operand" "")
17961    (match_operand:MODEF 1 "register_operand" "")]
17962   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17963    && !flag_trapping_math
17964    && !optimize_size"
17965 {
17966   ix86_expand_lfloorceil (operand0, operand1, true);
17967   DONE;
17968 })
17969
17970 (define_expand "lfloor<mode>si2"
17971   [(match_operand:SI 0 "nonimmediate_operand" "")
17972    (match_operand:MODEF 1 "register_operand" "")]
17973   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17974    && !flag_trapping_math
17975    && (!optimize_size || !TARGET_64BIT)"
17976 {
17977   ix86_expand_lfloorceil (operand0, operand1, true);
17978   DONE;
17979 })
17980
17981 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17982 (define_insn_and_split "frndintxf2_ceil"
17983   [(set (match_operand:XF 0 "register_operand" "")
17984         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17985          UNSPEC_FRNDINT_CEIL))
17986    (clobber (reg:CC FLAGS_REG))]
17987   "TARGET_USE_FANCY_MATH_387
17988    && flag_unsafe_math_optimizations
17989    && !(reload_completed || reload_in_progress)"
17990   "#"
17991   "&& 1"
17992   [(const_int 0)]
17993 {
17994   ix86_optimize_mode_switching[I387_CEIL] = 1;
17995
17996   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17997   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17998
17999   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18000                                        operands[2], operands[3]));
18001   DONE;
18002 }
18003   [(set_attr "type" "frndint")
18004    (set_attr "i387_cw" "ceil")
18005    (set_attr "mode" "XF")])
18006
18007 (define_insn "frndintxf2_ceil_i387"
18008   [(set (match_operand:XF 0 "register_operand" "=f")
18009         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18010          UNSPEC_FRNDINT_CEIL))
18011    (use (match_operand:HI 2 "memory_operand" "m"))
18012    (use (match_operand:HI 3 "memory_operand" "m"))]
18013   "TARGET_USE_FANCY_MATH_387
18014    && flag_unsafe_math_optimizations"
18015   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18016   [(set_attr "type" "frndint")
18017    (set_attr "i387_cw" "ceil")
18018    (set_attr "mode" "XF")])
18019
18020 (define_expand "ceilxf2"
18021   [(use (match_operand:XF 0 "register_operand" ""))
18022    (use (match_operand:XF 1 "register_operand" ""))]
18023   "TARGET_USE_FANCY_MATH_387
18024    && flag_unsafe_math_optimizations && !optimize_size"
18025 {
18026   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18027   DONE;
18028 })
18029
18030 (define_expand "ceil<mode>2"
18031   [(use (match_operand:MODEF 0 "register_operand" ""))
18032    (use (match_operand:MODEF 1 "register_operand" ""))]
18033   "(TARGET_USE_FANCY_MATH_387
18034     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18035         || TARGET_MIX_SSE_I387)
18036     && flag_unsafe_math_optimizations && !optimize_size)
18037    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18038        && !flag_trapping_math
18039        && (TARGET_ROUND || !optimize_size))"
18040 {
18041   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18042       && !flag_trapping_math
18043       && (TARGET_ROUND || !optimize_size))
18044     {
18045       if (TARGET_ROUND)
18046         emit_insn (gen_sse4_1_round<mode>2
18047                    (operands[0], operands[1], GEN_INT (0x02)));
18048       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18049         ix86_expand_floorceil (operand0, operand1, false);
18050       else
18051         ix86_expand_floorceildf_32 (operand0, operand1, false);
18052     }
18053   else
18054     {
18055       rtx op0 = gen_reg_rtx (XFmode);
18056       rtx op1 = gen_reg_rtx (XFmode);
18057
18058       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18059       emit_insn (gen_frndintxf2_ceil (op0, op1));
18060
18061       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18062     }
18063   DONE;
18064 })
18065
18066 (define_insn_and_split "*fist<mode>2_ceil_1"
18067   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18068         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18069          UNSPEC_FIST_CEIL))
18070    (clobber (reg:CC FLAGS_REG))]
18071   "TARGET_USE_FANCY_MATH_387
18072    && flag_unsafe_math_optimizations
18073    && !(reload_completed || reload_in_progress)"
18074   "#"
18075   "&& 1"
18076   [(const_int 0)]
18077 {
18078   ix86_optimize_mode_switching[I387_CEIL] = 1;
18079
18080   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18081   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18082   if (memory_operand (operands[0], VOIDmode))
18083     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18084                                      operands[2], operands[3]));
18085   else
18086     {
18087       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18088       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18089                                                  operands[2], operands[3],
18090                                                  operands[4]));
18091     }
18092   DONE;
18093 }
18094   [(set_attr "type" "fistp")
18095    (set_attr "i387_cw" "ceil")
18096    (set_attr "mode" "<MODE>")])
18097
18098 (define_insn "fistdi2_ceil"
18099   [(set (match_operand:DI 0 "memory_operand" "=m")
18100         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18101          UNSPEC_FIST_CEIL))
18102    (use (match_operand:HI 2 "memory_operand" "m"))
18103    (use (match_operand:HI 3 "memory_operand" "m"))
18104    (clobber (match_scratch:XF 4 "=&1f"))]
18105   "TARGET_USE_FANCY_MATH_387
18106    && flag_unsafe_math_optimizations"
18107   "* return output_fix_trunc (insn, operands, 0);"
18108   [(set_attr "type" "fistp")
18109    (set_attr "i387_cw" "ceil")
18110    (set_attr "mode" "DI")])
18111
18112 (define_insn "fistdi2_ceil_with_temp"
18113   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18114         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18115          UNSPEC_FIST_CEIL))
18116    (use (match_operand:HI 2 "memory_operand" "m,m"))
18117    (use (match_operand:HI 3 "memory_operand" "m,m"))
18118    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18119    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18120   "TARGET_USE_FANCY_MATH_387
18121    && flag_unsafe_math_optimizations"
18122   "#"
18123   [(set_attr "type" "fistp")
18124    (set_attr "i387_cw" "ceil")
18125    (set_attr "mode" "DI")])
18126
18127 (define_split
18128   [(set (match_operand:DI 0 "register_operand" "")
18129         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18130          UNSPEC_FIST_CEIL))
18131    (use (match_operand:HI 2 "memory_operand" ""))
18132    (use (match_operand:HI 3 "memory_operand" ""))
18133    (clobber (match_operand:DI 4 "memory_operand" ""))
18134    (clobber (match_scratch 5 ""))]
18135   "reload_completed"
18136   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18137               (use (match_dup 2))
18138               (use (match_dup 3))
18139               (clobber (match_dup 5))])
18140    (set (match_dup 0) (match_dup 4))]
18141   "")
18142
18143 (define_split
18144   [(set (match_operand:DI 0 "memory_operand" "")
18145         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18146          UNSPEC_FIST_CEIL))
18147    (use (match_operand:HI 2 "memory_operand" ""))
18148    (use (match_operand:HI 3 "memory_operand" ""))
18149    (clobber (match_operand:DI 4 "memory_operand" ""))
18150    (clobber (match_scratch 5 ""))]
18151   "reload_completed"
18152   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18153               (use (match_dup 2))
18154               (use (match_dup 3))
18155               (clobber (match_dup 5))])]
18156   "")
18157
18158 (define_insn "fist<mode>2_ceil"
18159   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18160         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18161          UNSPEC_FIST_CEIL))
18162    (use (match_operand:HI 2 "memory_operand" "m"))
18163    (use (match_operand:HI 3 "memory_operand" "m"))]
18164   "TARGET_USE_FANCY_MATH_387
18165    && flag_unsafe_math_optimizations"
18166   "* return output_fix_trunc (insn, operands, 0);"
18167   [(set_attr "type" "fistp")
18168    (set_attr "i387_cw" "ceil")
18169    (set_attr "mode" "<MODE>")])
18170
18171 (define_insn "fist<mode>2_ceil_with_temp"
18172   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18173         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18174          UNSPEC_FIST_CEIL))
18175    (use (match_operand:HI 2 "memory_operand" "m,m"))
18176    (use (match_operand:HI 3 "memory_operand" "m,m"))
18177    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18178   "TARGET_USE_FANCY_MATH_387
18179    && flag_unsafe_math_optimizations"
18180   "#"
18181   [(set_attr "type" "fistp")
18182    (set_attr "i387_cw" "ceil")
18183    (set_attr "mode" "<MODE>")])
18184
18185 (define_split
18186   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18187         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18188          UNSPEC_FIST_CEIL))
18189    (use (match_operand:HI 2 "memory_operand" ""))
18190    (use (match_operand:HI 3 "memory_operand" ""))
18191    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18192   "reload_completed"
18193   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18194                                   UNSPEC_FIST_CEIL))
18195               (use (match_dup 2))
18196               (use (match_dup 3))])
18197    (set (match_dup 0) (match_dup 4))]
18198   "")
18199
18200 (define_split
18201   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18202         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18203          UNSPEC_FIST_CEIL))
18204    (use (match_operand:HI 2 "memory_operand" ""))
18205    (use (match_operand:HI 3 "memory_operand" ""))
18206    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18207   "reload_completed"
18208   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18209                                   UNSPEC_FIST_CEIL))
18210               (use (match_dup 2))
18211               (use (match_dup 3))])]
18212   "")
18213
18214 (define_expand "lceilxf<mode>2"
18215   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18216                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18217                     UNSPEC_FIST_CEIL))
18218               (clobber (reg:CC FLAGS_REG))])]
18219   "TARGET_USE_FANCY_MATH_387
18220    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18221    && flag_unsafe_math_optimizations"
18222   "")
18223
18224 (define_expand "lceil<mode>di2"
18225   [(match_operand:DI 0 "nonimmediate_operand" "")
18226    (match_operand:MODEF 1 "register_operand" "")]
18227   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18228    && !flag_trapping_math"
18229 {
18230   ix86_expand_lfloorceil (operand0, operand1, false);
18231   DONE;
18232 })
18233
18234 (define_expand "lceil<mode>si2"
18235   [(match_operand:SI 0 "nonimmediate_operand" "")
18236    (match_operand:MODEF 1 "register_operand" "")]
18237   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18238    && !flag_trapping_math"
18239 {
18240   ix86_expand_lfloorceil (operand0, operand1, false);
18241   DONE;
18242 })
18243
18244 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18245 (define_insn_and_split "frndintxf2_trunc"
18246   [(set (match_operand:XF 0 "register_operand" "")
18247         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18248          UNSPEC_FRNDINT_TRUNC))
18249    (clobber (reg:CC FLAGS_REG))]
18250   "TARGET_USE_FANCY_MATH_387
18251    && flag_unsafe_math_optimizations
18252    && !(reload_completed || reload_in_progress)"
18253   "#"
18254   "&& 1"
18255   [(const_int 0)]
18256 {
18257   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18258
18259   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18260   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18261
18262   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18263                                         operands[2], operands[3]));
18264   DONE;
18265 }
18266   [(set_attr "type" "frndint")
18267    (set_attr "i387_cw" "trunc")
18268    (set_attr "mode" "XF")])
18269
18270 (define_insn "frndintxf2_trunc_i387"
18271   [(set (match_operand:XF 0 "register_operand" "=f")
18272         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18273          UNSPEC_FRNDINT_TRUNC))
18274    (use (match_operand:HI 2 "memory_operand" "m"))
18275    (use (match_operand:HI 3 "memory_operand" "m"))]
18276   "TARGET_USE_FANCY_MATH_387
18277    && flag_unsafe_math_optimizations"
18278   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18279   [(set_attr "type" "frndint")
18280    (set_attr "i387_cw" "trunc")
18281    (set_attr "mode" "XF")])
18282
18283 (define_expand "btruncxf2"
18284   [(use (match_operand:XF 0 "register_operand" ""))
18285    (use (match_operand:XF 1 "register_operand" ""))]
18286   "TARGET_USE_FANCY_MATH_387
18287    && flag_unsafe_math_optimizations && !optimize_size"
18288 {
18289   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18290   DONE;
18291 })
18292
18293 (define_expand "btrunc<mode>2"
18294   [(use (match_operand:MODEF 0 "register_operand" ""))
18295    (use (match_operand:MODEF 1 "register_operand" ""))]
18296   "(TARGET_USE_FANCY_MATH_387
18297     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18298         || TARGET_MIX_SSE_I387)
18299     && flag_unsafe_math_optimizations && !optimize_size)
18300    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18301        && !flag_trapping_math
18302        && (TARGET_ROUND || !optimize_size))"
18303 {
18304   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18305       && !flag_trapping_math
18306       && (TARGET_ROUND || !optimize_size))
18307     {
18308       if (TARGET_ROUND)
18309         emit_insn (gen_sse4_1_round<mode>2
18310                    (operands[0], operands[1], GEN_INT (0x03)));
18311       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18312         ix86_expand_trunc (operand0, operand1);
18313       else
18314         ix86_expand_truncdf_32 (operand0, operand1);
18315     }
18316   else
18317     {
18318       rtx op0 = gen_reg_rtx (XFmode);
18319       rtx op1 = gen_reg_rtx (XFmode);
18320
18321       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18322       emit_insn (gen_frndintxf2_trunc (op0, op1));
18323
18324       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18325     }
18326   DONE;
18327 })
18328
18329 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18330 (define_insn_and_split "frndintxf2_mask_pm"
18331   [(set (match_operand:XF 0 "register_operand" "")
18332         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18333          UNSPEC_FRNDINT_MASK_PM))
18334    (clobber (reg:CC FLAGS_REG))]
18335   "TARGET_USE_FANCY_MATH_387
18336    && flag_unsafe_math_optimizations
18337    && !(reload_completed || reload_in_progress)"
18338   "#"
18339   "&& 1"
18340   [(const_int 0)]
18341 {
18342   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18343
18344   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18345   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18346
18347   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18348                                           operands[2], operands[3]));
18349   DONE;
18350 }
18351   [(set_attr "type" "frndint")
18352    (set_attr "i387_cw" "mask_pm")
18353    (set_attr "mode" "XF")])
18354
18355 (define_insn "frndintxf2_mask_pm_i387"
18356   [(set (match_operand:XF 0 "register_operand" "=f")
18357         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18358          UNSPEC_FRNDINT_MASK_PM))
18359    (use (match_operand:HI 2 "memory_operand" "m"))
18360    (use (match_operand:HI 3 "memory_operand" "m"))]
18361   "TARGET_USE_FANCY_MATH_387
18362    && flag_unsafe_math_optimizations"
18363   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18364   [(set_attr "type" "frndint")
18365    (set_attr "i387_cw" "mask_pm")
18366    (set_attr "mode" "XF")])
18367
18368 (define_expand "nearbyintxf2"
18369   [(use (match_operand:XF 0 "register_operand" ""))
18370    (use (match_operand:XF 1 "register_operand" ""))]
18371   "TARGET_USE_FANCY_MATH_387
18372    && flag_unsafe_math_optimizations"
18373 {
18374   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18375
18376   DONE;
18377 })
18378
18379 (define_expand "nearbyint<mode>2"
18380   [(use (match_operand:MODEF 0 "register_operand" ""))
18381    (use (match_operand:MODEF 1 "register_operand" ""))]
18382   "TARGET_USE_FANCY_MATH_387
18383    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18384        || TARGET_MIX_SSE_I387)
18385    && flag_unsafe_math_optimizations"
18386 {
18387   rtx op0 = gen_reg_rtx (XFmode);
18388   rtx op1 = gen_reg_rtx (XFmode);
18389
18390   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18391   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18392
18393   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18394   DONE;
18395 })
18396
18397 (define_insn "fxam<mode>2_i387"
18398   [(set (match_operand:HI 0 "register_operand" "=a")
18399         (unspec:HI
18400           [(match_operand:X87MODEF 1 "register_operand" "f")]
18401           UNSPEC_FXAM))]
18402   "TARGET_USE_FANCY_MATH_387"
18403   "fxam\n\tfnstsw\t%0"
18404   [(set_attr "type" "multi")
18405    (set_attr "unit" "i387")
18406    (set_attr "mode" "<MODE>")])
18407
18408 (define_expand "isinf<mode>2"
18409   [(use (match_operand:SI 0 "register_operand" ""))
18410    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18411   "TARGET_USE_FANCY_MATH_387
18412    && TARGET_C99_FUNCTIONS
18413    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18414 {
18415   rtx mask = GEN_INT (0x45);
18416   rtx val = GEN_INT (0x05);
18417
18418   rtx cond;
18419
18420   rtx scratch = gen_reg_rtx (HImode);
18421   rtx res = gen_reg_rtx (QImode);
18422
18423   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18424   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18425   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18426   cond = gen_rtx_fmt_ee (EQ, QImode,
18427                          gen_rtx_REG (CCmode, FLAGS_REG),
18428                          const0_rtx);
18429   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18430   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18431   DONE;
18432 })
18433
18434 (define_expand "signbit<mode>2"
18435   [(use (match_operand:SI 0 "register_operand" ""))
18436    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18437   "TARGET_USE_FANCY_MATH_387
18438    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18439 {
18440   rtx mask = GEN_INT (0x0200);
18441
18442   rtx scratch = gen_reg_rtx (HImode);
18443
18444   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18445   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18446   DONE;
18447 })
18448 \f
18449 ;; Block operation instructions
18450
18451 (define_insn "cld"
18452   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18453   ""
18454   "cld"
18455   [(set_attr "length" "1")
18456    (set_attr "length_immediate" "0")
18457    (set_attr "modrm" "0")])
18458
18459 (define_expand "movmemsi"
18460   [(use (match_operand:BLK 0 "memory_operand" ""))
18461    (use (match_operand:BLK 1 "memory_operand" ""))
18462    (use (match_operand:SI 2 "nonmemory_operand" ""))
18463    (use (match_operand:SI 3 "const_int_operand" ""))
18464    (use (match_operand:SI 4 "const_int_operand" ""))
18465    (use (match_operand:SI 5 "const_int_operand" ""))]
18466   ""
18467 {
18468  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18469                          operands[4], operands[5]))
18470    DONE;
18471  else
18472    FAIL;
18473 })
18474
18475 (define_expand "movmemdi"
18476   [(use (match_operand:BLK 0 "memory_operand" ""))
18477    (use (match_operand:BLK 1 "memory_operand" ""))
18478    (use (match_operand:DI 2 "nonmemory_operand" ""))
18479    (use (match_operand:DI 3 "const_int_operand" ""))
18480    (use (match_operand:SI 4 "const_int_operand" ""))
18481    (use (match_operand:SI 5 "const_int_operand" ""))]
18482   "TARGET_64BIT"
18483 {
18484  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18485                          operands[4], operands[5]))
18486    DONE;
18487  else
18488    FAIL;
18489 })
18490
18491 ;; Most CPUs don't like single string operations
18492 ;; Handle this case here to simplify previous expander.
18493
18494 (define_expand "strmov"
18495   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18496    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18497    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18498               (clobber (reg:CC FLAGS_REG))])
18499    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18500               (clobber (reg:CC FLAGS_REG))])]
18501   ""
18502 {
18503   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18504
18505   /* If .md ever supports :P for Pmode, these can be directly
18506      in the pattern above.  */
18507   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18508   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18509
18510   /* Can't use this if the user has appropriated esi or edi.  */
18511   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18512       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18513     {
18514       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18515                                       operands[2], operands[3],
18516                                       operands[5], operands[6]));
18517       DONE;
18518     }
18519
18520   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18521 })
18522
18523 (define_expand "strmov_singleop"
18524   [(parallel [(set (match_operand 1 "memory_operand" "")
18525                    (match_operand 3 "memory_operand" ""))
18526               (set (match_operand 0 "register_operand" "")
18527                    (match_operand 4 "" ""))
18528               (set (match_operand 2 "register_operand" "")
18529                    (match_operand 5 "" ""))])]
18530   "TARGET_SINGLE_STRINGOP || optimize_size"
18531   "ix86_current_function_needs_cld = 1;")
18532
18533 (define_insn "*strmovdi_rex_1"
18534   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18535         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18536    (set (match_operand:DI 0 "register_operand" "=D")
18537         (plus:DI (match_dup 2)
18538                  (const_int 8)))
18539    (set (match_operand:DI 1 "register_operand" "=S")
18540         (plus:DI (match_dup 3)
18541                  (const_int 8)))]
18542   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18543   "movsq"
18544   [(set_attr "type" "str")
18545    (set_attr "mode" "DI")
18546    (set_attr "memory" "both")])
18547
18548 (define_insn "*strmovsi_1"
18549   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18550         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18551    (set (match_operand:SI 0 "register_operand" "=D")
18552         (plus:SI (match_dup 2)
18553                  (const_int 4)))
18554    (set (match_operand:SI 1 "register_operand" "=S")
18555         (plus:SI (match_dup 3)
18556                  (const_int 4)))]
18557   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18558   "movs{l|d}"
18559   [(set_attr "type" "str")
18560    (set_attr "mode" "SI")
18561    (set_attr "memory" "both")])
18562
18563 (define_insn "*strmovsi_rex_1"
18564   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18565         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18566    (set (match_operand:DI 0 "register_operand" "=D")
18567         (plus:DI (match_dup 2)
18568                  (const_int 4)))
18569    (set (match_operand:DI 1 "register_operand" "=S")
18570         (plus:DI (match_dup 3)
18571                  (const_int 4)))]
18572   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18573   "movs{l|d}"
18574   [(set_attr "type" "str")
18575    (set_attr "mode" "SI")
18576    (set_attr "memory" "both")])
18577
18578 (define_insn "*strmovhi_1"
18579   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18580         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18581    (set (match_operand:SI 0 "register_operand" "=D")
18582         (plus:SI (match_dup 2)
18583                  (const_int 2)))
18584    (set (match_operand:SI 1 "register_operand" "=S")
18585         (plus:SI (match_dup 3)
18586                  (const_int 2)))]
18587   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18588   "movsw"
18589   [(set_attr "type" "str")
18590    (set_attr "memory" "both")
18591    (set_attr "mode" "HI")])
18592
18593 (define_insn "*strmovhi_rex_1"
18594   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18595         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18596    (set (match_operand:DI 0 "register_operand" "=D")
18597         (plus:DI (match_dup 2)
18598                  (const_int 2)))
18599    (set (match_operand:DI 1 "register_operand" "=S")
18600         (plus:DI (match_dup 3)
18601                  (const_int 2)))]
18602   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18603   "movsw"
18604   [(set_attr "type" "str")
18605    (set_attr "memory" "both")
18606    (set_attr "mode" "HI")])
18607
18608 (define_insn "*strmovqi_1"
18609   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18610         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18611    (set (match_operand:SI 0 "register_operand" "=D")
18612         (plus:SI (match_dup 2)
18613                  (const_int 1)))
18614    (set (match_operand:SI 1 "register_operand" "=S")
18615         (plus:SI (match_dup 3)
18616                  (const_int 1)))]
18617   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18618   "movsb"
18619   [(set_attr "type" "str")
18620    (set_attr "memory" "both")
18621    (set_attr "mode" "QI")])
18622
18623 (define_insn "*strmovqi_rex_1"
18624   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18625         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18626    (set (match_operand:DI 0 "register_operand" "=D")
18627         (plus:DI (match_dup 2)
18628                  (const_int 1)))
18629    (set (match_operand:DI 1 "register_operand" "=S")
18630         (plus:DI (match_dup 3)
18631                  (const_int 1)))]
18632   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18633   "movsb"
18634   [(set_attr "type" "str")
18635    (set_attr "memory" "both")
18636    (set_attr "mode" "QI")])
18637
18638 (define_expand "rep_mov"
18639   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18640               (set (match_operand 0 "register_operand" "")
18641                    (match_operand 5 "" ""))
18642               (set (match_operand 2 "register_operand" "")
18643                    (match_operand 6 "" ""))
18644               (set (match_operand 1 "memory_operand" "")
18645                    (match_operand 3 "memory_operand" ""))
18646               (use (match_dup 4))])]
18647   ""
18648   "ix86_current_function_needs_cld = 1;")
18649
18650 (define_insn "*rep_movdi_rex64"
18651   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18652    (set (match_operand:DI 0 "register_operand" "=D")
18653         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18654                             (const_int 3))
18655                  (match_operand:DI 3 "register_operand" "0")))
18656    (set (match_operand:DI 1 "register_operand" "=S")
18657         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18658                  (match_operand:DI 4 "register_operand" "1")))
18659    (set (mem:BLK (match_dup 3))
18660         (mem:BLK (match_dup 4)))
18661    (use (match_dup 5))]
18662   "TARGET_64BIT"
18663   "rep movsq"
18664   [(set_attr "type" "str")
18665    (set_attr "prefix_rep" "1")
18666    (set_attr "memory" "both")
18667    (set_attr "mode" "DI")])
18668
18669 (define_insn "*rep_movsi"
18670   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18671    (set (match_operand:SI 0 "register_operand" "=D")
18672         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18673                             (const_int 2))
18674                  (match_operand:SI 3 "register_operand" "0")))
18675    (set (match_operand:SI 1 "register_operand" "=S")
18676         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18677                  (match_operand:SI 4 "register_operand" "1")))
18678    (set (mem:BLK (match_dup 3))
18679         (mem:BLK (match_dup 4)))
18680    (use (match_dup 5))]
18681   "!TARGET_64BIT"
18682   "rep movs{l|d}"
18683   [(set_attr "type" "str")
18684    (set_attr "prefix_rep" "1")
18685    (set_attr "memory" "both")
18686    (set_attr "mode" "SI")])
18687
18688 (define_insn "*rep_movsi_rex64"
18689   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18690    (set (match_operand:DI 0 "register_operand" "=D")
18691         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18692                             (const_int 2))
18693                  (match_operand:DI 3 "register_operand" "0")))
18694    (set (match_operand:DI 1 "register_operand" "=S")
18695         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18696                  (match_operand:DI 4 "register_operand" "1")))
18697    (set (mem:BLK (match_dup 3))
18698         (mem:BLK (match_dup 4)))
18699    (use (match_dup 5))]
18700   "TARGET_64BIT"
18701   "rep movs{l|d}"
18702   [(set_attr "type" "str")
18703    (set_attr "prefix_rep" "1")
18704    (set_attr "memory" "both")
18705    (set_attr "mode" "SI")])
18706
18707 (define_insn "*rep_movqi"
18708   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18709    (set (match_operand:SI 0 "register_operand" "=D")
18710         (plus:SI (match_operand:SI 3 "register_operand" "0")
18711                  (match_operand:SI 5 "register_operand" "2")))
18712    (set (match_operand:SI 1 "register_operand" "=S")
18713         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18714    (set (mem:BLK (match_dup 3))
18715         (mem:BLK (match_dup 4)))
18716    (use (match_dup 5))]
18717   "!TARGET_64BIT"
18718   "rep movsb"
18719   [(set_attr "type" "str")
18720    (set_attr "prefix_rep" "1")
18721    (set_attr "memory" "both")
18722    (set_attr "mode" "SI")])
18723
18724 (define_insn "*rep_movqi_rex64"
18725   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18726    (set (match_operand:DI 0 "register_operand" "=D")
18727         (plus:DI (match_operand:DI 3 "register_operand" "0")
18728                  (match_operand:DI 5 "register_operand" "2")))
18729    (set (match_operand:DI 1 "register_operand" "=S")
18730         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18731    (set (mem:BLK (match_dup 3))
18732         (mem:BLK (match_dup 4)))
18733    (use (match_dup 5))]
18734   "TARGET_64BIT"
18735   "rep movsb"
18736   [(set_attr "type" "str")
18737    (set_attr "prefix_rep" "1")
18738    (set_attr "memory" "both")
18739    (set_attr "mode" "SI")])
18740
18741 (define_expand "setmemsi"
18742    [(use (match_operand:BLK 0 "memory_operand" ""))
18743     (use (match_operand:SI 1 "nonmemory_operand" ""))
18744     (use (match_operand 2 "const_int_operand" ""))
18745     (use (match_operand 3 "const_int_operand" ""))
18746     (use (match_operand:SI 4 "const_int_operand" ""))
18747     (use (match_operand:SI 5 "const_int_operand" ""))]
18748   ""
18749 {
18750  if (ix86_expand_setmem (operands[0], operands[1],
18751                          operands[2], operands[3],
18752                          operands[4], operands[5]))
18753    DONE;
18754  else
18755    FAIL;
18756 })
18757
18758 (define_expand "setmemdi"
18759    [(use (match_operand:BLK 0 "memory_operand" ""))
18760     (use (match_operand:DI 1 "nonmemory_operand" ""))
18761     (use (match_operand 2 "const_int_operand" ""))
18762     (use (match_operand 3 "const_int_operand" ""))
18763     (use (match_operand 4 "const_int_operand" ""))
18764     (use (match_operand 5 "const_int_operand" ""))]
18765   "TARGET_64BIT"
18766 {
18767  if (ix86_expand_setmem (operands[0], operands[1],
18768                          operands[2], operands[3],
18769                          operands[4], operands[5]))
18770    DONE;
18771  else
18772    FAIL;
18773 })
18774
18775 ;; Most CPUs don't like single string operations
18776 ;; Handle this case here to simplify previous expander.
18777
18778 (define_expand "strset"
18779   [(set (match_operand 1 "memory_operand" "")
18780         (match_operand 2 "register_operand" ""))
18781    (parallel [(set (match_operand 0 "register_operand" "")
18782                    (match_dup 3))
18783               (clobber (reg:CC FLAGS_REG))])]
18784   ""
18785 {
18786   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18787     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18788
18789   /* If .md ever supports :P for Pmode, this can be directly
18790      in the pattern above.  */
18791   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18792                               GEN_INT (GET_MODE_SIZE (GET_MODE
18793                                                       (operands[2]))));
18794   if (TARGET_SINGLE_STRINGOP || optimize_size)
18795     {
18796       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18797                                       operands[3]));
18798       DONE;
18799     }
18800 })
18801
18802 (define_expand "strset_singleop"
18803   [(parallel [(set (match_operand 1 "memory_operand" "")
18804                    (match_operand 2 "register_operand" ""))
18805               (set (match_operand 0 "register_operand" "")
18806                    (match_operand 3 "" ""))])]
18807   "TARGET_SINGLE_STRINGOP || optimize_size"
18808   "ix86_current_function_needs_cld = 1;")
18809
18810 (define_insn "*strsetdi_rex_1"
18811   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18812         (match_operand:DI 2 "register_operand" "a"))
18813    (set (match_operand:DI 0 "register_operand" "=D")
18814         (plus:DI (match_dup 1)
18815                  (const_int 8)))]
18816   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18817   "stosq"
18818   [(set_attr "type" "str")
18819    (set_attr "memory" "store")
18820    (set_attr "mode" "DI")])
18821
18822 (define_insn "*strsetsi_1"
18823   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18824         (match_operand:SI 2 "register_operand" "a"))
18825    (set (match_operand:SI 0 "register_operand" "=D")
18826         (plus:SI (match_dup 1)
18827                  (const_int 4)))]
18828   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18829   "stos{l|d}"
18830   [(set_attr "type" "str")
18831    (set_attr "memory" "store")
18832    (set_attr "mode" "SI")])
18833
18834 (define_insn "*strsetsi_rex_1"
18835   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18836         (match_operand:SI 2 "register_operand" "a"))
18837    (set (match_operand:DI 0 "register_operand" "=D")
18838         (plus:DI (match_dup 1)
18839                  (const_int 4)))]
18840   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18841   "stos{l|d}"
18842   [(set_attr "type" "str")
18843    (set_attr "memory" "store")
18844    (set_attr "mode" "SI")])
18845
18846 (define_insn "*strsethi_1"
18847   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18848         (match_operand:HI 2 "register_operand" "a"))
18849    (set (match_operand:SI 0 "register_operand" "=D")
18850         (plus:SI (match_dup 1)
18851                  (const_int 2)))]
18852   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18853   "stosw"
18854   [(set_attr "type" "str")
18855    (set_attr "memory" "store")
18856    (set_attr "mode" "HI")])
18857
18858 (define_insn "*strsethi_rex_1"
18859   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18860         (match_operand:HI 2 "register_operand" "a"))
18861    (set (match_operand:DI 0 "register_operand" "=D")
18862         (plus:DI (match_dup 1)
18863                  (const_int 2)))]
18864   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18865   "stosw"
18866   [(set_attr "type" "str")
18867    (set_attr "memory" "store")
18868    (set_attr "mode" "HI")])
18869
18870 (define_insn "*strsetqi_1"
18871   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18872         (match_operand:QI 2 "register_operand" "a"))
18873    (set (match_operand:SI 0 "register_operand" "=D")
18874         (plus:SI (match_dup 1)
18875                  (const_int 1)))]
18876   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18877   "stosb"
18878   [(set_attr "type" "str")
18879    (set_attr "memory" "store")
18880    (set_attr "mode" "QI")])
18881
18882 (define_insn "*strsetqi_rex_1"
18883   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18884         (match_operand:QI 2 "register_operand" "a"))
18885    (set (match_operand:DI 0 "register_operand" "=D")
18886         (plus:DI (match_dup 1)
18887                  (const_int 1)))]
18888   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18889   "stosb"
18890   [(set_attr "type" "str")
18891    (set_attr "memory" "store")
18892    (set_attr "mode" "QI")])
18893
18894 (define_expand "rep_stos"
18895   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18896               (set (match_operand 0 "register_operand" "")
18897                    (match_operand 4 "" ""))
18898               (set (match_operand 2 "memory_operand" "") (const_int 0))
18899               (use (match_operand 3 "register_operand" ""))
18900               (use (match_dup 1))])]
18901   ""
18902   "ix86_current_function_needs_cld = 1;")
18903
18904 (define_insn "*rep_stosdi_rex64"
18905   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18906    (set (match_operand:DI 0 "register_operand" "=D")
18907         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18908                             (const_int 3))
18909                  (match_operand:DI 3 "register_operand" "0")))
18910    (set (mem:BLK (match_dup 3))
18911         (const_int 0))
18912    (use (match_operand:DI 2 "register_operand" "a"))
18913    (use (match_dup 4))]
18914   "TARGET_64BIT"
18915   "rep stosq"
18916   [(set_attr "type" "str")
18917    (set_attr "prefix_rep" "1")
18918    (set_attr "memory" "store")
18919    (set_attr "mode" "DI")])
18920
18921 (define_insn "*rep_stossi"
18922   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18923    (set (match_operand:SI 0 "register_operand" "=D")
18924         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18925                             (const_int 2))
18926                  (match_operand:SI 3 "register_operand" "0")))
18927    (set (mem:BLK (match_dup 3))
18928         (const_int 0))
18929    (use (match_operand:SI 2 "register_operand" "a"))
18930    (use (match_dup 4))]
18931   "!TARGET_64BIT"
18932   "rep stos{l|d}"
18933   [(set_attr "type" "str")
18934    (set_attr "prefix_rep" "1")
18935    (set_attr "memory" "store")
18936    (set_attr "mode" "SI")])
18937
18938 (define_insn "*rep_stossi_rex64"
18939   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18940    (set (match_operand:DI 0 "register_operand" "=D")
18941         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18942                             (const_int 2))
18943                  (match_operand:DI 3 "register_operand" "0")))
18944    (set (mem:BLK (match_dup 3))
18945         (const_int 0))
18946    (use (match_operand:SI 2 "register_operand" "a"))
18947    (use (match_dup 4))]
18948   "TARGET_64BIT"
18949   "rep stos{l|d}"
18950   [(set_attr "type" "str")
18951    (set_attr "prefix_rep" "1")
18952    (set_attr "memory" "store")
18953    (set_attr "mode" "SI")])
18954
18955 (define_insn "*rep_stosqi"
18956   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18957    (set (match_operand:SI 0 "register_operand" "=D")
18958         (plus:SI (match_operand:SI 3 "register_operand" "0")
18959                  (match_operand:SI 4 "register_operand" "1")))
18960    (set (mem:BLK (match_dup 3))
18961         (const_int 0))
18962    (use (match_operand:QI 2 "register_operand" "a"))
18963    (use (match_dup 4))]
18964   "!TARGET_64BIT"
18965   "rep stosb"
18966   [(set_attr "type" "str")
18967    (set_attr "prefix_rep" "1")
18968    (set_attr "memory" "store")
18969    (set_attr "mode" "QI")])
18970
18971 (define_insn "*rep_stosqi_rex64"
18972   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18973    (set (match_operand:DI 0 "register_operand" "=D")
18974         (plus:DI (match_operand:DI 3 "register_operand" "0")
18975                  (match_operand:DI 4 "register_operand" "1")))
18976    (set (mem:BLK (match_dup 3))
18977         (const_int 0))
18978    (use (match_operand:QI 2 "register_operand" "a"))
18979    (use (match_dup 4))]
18980   "TARGET_64BIT"
18981   "rep stosb"
18982   [(set_attr "type" "str")
18983    (set_attr "prefix_rep" "1")
18984    (set_attr "memory" "store")
18985    (set_attr "mode" "QI")])
18986
18987 (define_expand "cmpstrnsi"
18988   [(set (match_operand:SI 0 "register_operand" "")
18989         (compare:SI (match_operand:BLK 1 "general_operand" "")
18990                     (match_operand:BLK 2 "general_operand" "")))
18991    (use (match_operand 3 "general_operand" ""))
18992    (use (match_operand 4 "immediate_operand" ""))]
18993   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18994 {
18995   rtx addr1, addr2, out, outlow, count, countreg, align;
18996
18997   /* Can't use this if the user has appropriated esi or edi.  */
18998   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18999     FAIL;
19000
19001   out = operands[0];
19002   if (!REG_P (out))
19003     out = gen_reg_rtx (SImode);
19004
19005   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19006   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19007   if (addr1 != XEXP (operands[1], 0))
19008     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19009   if (addr2 != XEXP (operands[2], 0))
19010     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19011
19012   count = operands[3];
19013   countreg = ix86_zero_extend_to_Pmode (count);
19014
19015   /* %%% Iff we are testing strict equality, we can use known alignment
19016      to good advantage.  This may be possible with combine, particularly
19017      once cc0 is dead.  */
19018   align = operands[4];
19019
19020   if (CONST_INT_P (count))
19021     {
19022       if (INTVAL (count) == 0)
19023         {
19024           emit_move_insn (operands[0], const0_rtx);
19025           DONE;
19026         }
19027       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19028                                      operands[1], operands[2]));
19029     }
19030   else
19031     {
19032       if (TARGET_64BIT)
19033         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19034       else
19035         emit_insn (gen_cmpsi_1 (countreg, countreg));
19036       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19037                                   operands[1], operands[2]));
19038     }
19039
19040   outlow = gen_lowpart (QImode, out);
19041   emit_insn (gen_cmpintqi (outlow));
19042   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19043
19044   if (operands[0] != out)
19045     emit_move_insn (operands[0], out);
19046
19047   DONE;
19048 })
19049
19050 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19051
19052 (define_expand "cmpintqi"
19053   [(set (match_dup 1)
19054         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19055    (set (match_dup 2)
19056         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19057    (parallel [(set (match_operand:QI 0 "register_operand" "")
19058                    (minus:QI (match_dup 1)
19059                              (match_dup 2)))
19060               (clobber (reg:CC FLAGS_REG))])]
19061   ""
19062   "operands[1] = gen_reg_rtx (QImode);
19063    operands[2] = gen_reg_rtx (QImode);")
19064
19065 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19066 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19067
19068 (define_expand "cmpstrnqi_nz_1"
19069   [(parallel [(set (reg:CC FLAGS_REG)
19070                    (compare:CC (match_operand 4 "memory_operand" "")
19071                                (match_operand 5 "memory_operand" "")))
19072               (use (match_operand 2 "register_operand" ""))
19073               (use (match_operand:SI 3 "immediate_operand" ""))
19074               (clobber (match_operand 0 "register_operand" ""))
19075               (clobber (match_operand 1 "register_operand" ""))
19076               (clobber (match_dup 2))])]
19077   ""
19078   "ix86_current_function_needs_cld = 1;")
19079
19080 (define_insn "*cmpstrnqi_nz_1"
19081   [(set (reg:CC FLAGS_REG)
19082         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19083                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19084    (use (match_operand:SI 6 "register_operand" "2"))
19085    (use (match_operand:SI 3 "immediate_operand" "i"))
19086    (clobber (match_operand:SI 0 "register_operand" "=S"))
19087    (clobber (match_operand:SI 1 "register_operand" "=D"))
19088    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19089   "!TARGET_64BIT"
19090   "repz cmpsb"
19091   [(set_attr "type" "str")
19092    (set_attr "mode" "QI")
19093    (set_attr "prefix_rep" "1")])
19094
19095 (define_insn "*cmpstrnqi_nz_rex_1"
19096   [(set (reg:CC FLAGS_REG)
19097         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19098                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19099    (use (match_operand:DI 6 "register_operand" "2"))
19100    (use (match_operand:SI 3 "immediate_operand" "i"))
19101    (clobber (match_operand:DI 0 "register_operand" "=S"))
19102    (clobber (match_operand:DI 1 "register_operand" "=D"))
19103    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19104   "TARGET_64BIT"
19105   "repz cmpsb"
19106   [(set_attr "type" "str")
19107    (set_attr "mode" "QI")
19108    (set_attr "prefix_rep" "1")])
19109
19110 ;; The same, but the count is not known to not be zero.
19111
19112 (define_expand "cmpstrnqi_1"
19113   [(parallel [(set (reg:CC FLAGS_REG)
19114                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19115                                      (const_int 0))
19116                   (compare:CC (match_operand 4 "memory_operand" "")
19117                               (match_operand 5 "memory_operand" ""))
19118                   (const_int 0)))
19119               (use (match_operand:SI 3 "immediate_operand" ""))
19120               (use (reg:CC FLAGS_REG))
19121               (clobber (match_operand 0 "register_operand" ""))
19122               (clobber (match_operand 1 "register_operand" ""))
19123               (clobber (match_dup 2))])]
19124   ""
19125   "ix86_current_function_needs_cld = 1;")
19126
19127 (define_insn "*cmpstrnqi_1"
19128   [(set (reg:CC FLAGS_REG)
19129         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19130                              (const_int 0))
19131           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19132                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19133           (const_int 0)))
19134    (use (match_operand:SI 3 "immediate_operand" "i"))
19135    (use (reg:CC FLAGS_REG))
19136    (clobber (match_operand:SI 0 "register_operand" "=S"))
19137    (clobber (match_operand:SI 1 "register_operand" "=D"))
19138    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19139   "!TARGET_64BIT"
19140   "repz cmpsb"
19141   [(set_attr "type" "str")
19142    (set_attr "mode" "QI")
19143    (set_attr "prefix_rep" "1")])
19144
19145 (define_insn "*cmpstrnqi_rex_1"
19146   [(set (reg:CC FLAGS_REG)
19147         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19148                              (const_int 0))
19149           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19150                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19151           (const_int 0)))
19152    (use (match_operand:SI 3 "immediate_operand" "i"))
19153    (use (reg:CC FLAGS_REG))
19154    (clobber (match_operand:DI 0 "register_operand" "=S"))
19155    (clobber (match_operand:DI 1 "register_operand" "=D"))
19156    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19157   "TARGET_64BIT"
19158   "repz cmpsb"
19159   [(set_attr "type" "str")
19160    (set_attr "mode" "QI")
19161    (set_attr "prefix_rep" "1")])
19162
19163 (define_expand "strlensi"
19164   [(set (match_operand:SI 0 "register_operand" "")
19165         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19166                     (match_operand:QI 2 "immediate_operand" "")
19167                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19168   ""
19169 {
19170  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19171    DONE;
19172  else
19173    FAIL;
19174 })
19175
19176 (define_expand "strlendi"
19177   [(set (match_operand:DI 0 "register_operand" "")
19178         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19179                     (match_operand:QI 2 "immediate_operand" "")
19180                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19181   ""
19182 {
19183  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19184    DONE;
19185  else
19186    FAIL;
19187 })
19188
19189 (define_expand "strlenqi_1"
19190   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19191               (clobber (match_operand 1 "register_operand" ""))
19192               (clobber (reg:CC FLAGS_REG))])]
19193   ""
19194   "ix86_current_function_needs_cld = 1;")
19195
19196 (define_insn "*strlenqi_1"
19197   [(set (match_operand:SI 0 "register_operand" "=&c")
19198         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19199                     (match_operand:QI 2 "register_operand" "a")
19200                     (match_operand:SI 3 "immediate_operand" "i")
19201                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19202    (clobber (match_operand:SI 1 "register_operand" "=D"))
19203    (clobber (reg:CC FLAGS_REG))]
19204   "!TARGET_64BIT"
19205   "repnz scasb"
19206   [(set_attr "type" "str")
19207    (set_attr "mode" "QI")
19208    (set_attr "prefix_rep" "1")])
19209
19210 (define_insn "*strlenqi_rex_1"
19211   [(set (match_operand:DI 0 "register_operand" "=&c")
19212         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19213                     (match_operand:QI 2 "register_operand" "a")
19214                     (match_operand:DI 3 "immediate_operand" "i")
19215                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19216    (clobber (match_operand:DI 1 "register_operand" "=D"))
19217    (clobber (reg:CC FLAGS_REG))]
19218   "TARGET_64BIT"
19219   "repnz scasb"
19220   [(set_attr "type" "str")
19221    (set_attr "mode" "QI")
19222    (set_attr "prefix_rep" "1")])
19223
19224 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19225 ;; handled in combine, but it is not currently up to the task.
19226 ;; When used for their truth value, the cmpstrn* expanders generate
19227 ;; code like this:
19228 ;;
19229 ;;   repz cmpsb
19230 ;;   seta       %al
19231 ;;   setb       %dl
19232 ;;   cmpb       %al, %dl
19233 ;;   jcc        label
19234 ;;
19235 ;; The intermediate three instructions are unnecessary.
19236
19237 ;; This one handles cmpstrn*_nz_1...
19238 (define_peephole2
19239   [(parallel[
19240      (set (reg:CC FLAGS_REG)
19241           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19242                       (mem:BLK (match_operand 5 "register_operand" ""))))
19243      (use (match_operand 6 "register_operand" ""))
19244      (use (match_operand:SI 3 "immediate_operand" ""))
19245      (clobber (match_operand 0 "register_operand" ""))
19246      (clobber (match_operand 1 "register_operand" ""))
19247      (clobber (match_operand 2 "register_operand" ""))])
19248    (set (match_operand:QI 7 "register_operand" "")
19249         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19250    (set (match_operand:QI 8 "register_operand" "")
19251         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19252    (set (reg FLAGS_REG)
19253         (compare (match_dup 7) (match_dup 8)))
19254   ]
19255   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19256   [(parallel[
19257      (set (reg:CC FLAGS_REG)
19258           (compare:CC (mem:BLK (match_dup 4))
19259                       (mem:BLK (match_dup 5))))
19260      (use (match_dup 6))
19261      (use (match_dup 3))
19262      (clobber (match_dup 0))
19263      (clobber (match_dup 1))
19264      (clobber (match_dup 2))])]
19265   "")
19266
19267 ;; ...and this one handles cmpstrn*_1.
19268 (define_peephole2
19269   [(parallel[
19270      (set (reg:CC FLAGS_REG)
19271           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19272                                (const_int 0))
19273             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19274                         (mem:BLK (match_operand 5 "register_operand" "")))
19275             (const_int 0)))
19276      (use (match_operand:SI 3 "immediate_operand" ""))
19277      (use (reg:CC FLAGS_REG))
19278      (clobber (match_operand 0 "register_operand" ""))
19279      (clobber (match_operand 1 "register_operand" ""))
19280      (clobber (match_operand 2 "register_operand" ""))])
19281    (set (match_operand:QI 7 "register_operand" "")
19282         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19283    (set (match_operand:QI 8 "register_operand" "")
19284         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19285    (set (reg FLAGS_REG)
19286         (compare (match_dup 7) (match_dup 8)))
19287   ]
19288   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19289   [(parallel[
19290      (set (reg:CC FLAGS_REG)
19291           (if_then_else:CC (ne (match_dup 6)
19292                                (const_int 0))
19293             (compare:CC (mem:BLK (match_dup 4))
19294                         (mem:BLK (match_dup 5)))
19295             (const_int 0)))
19296      (use (match_dup 3))
19297      (use (reg:CC FLAGS_REG))
19298      (clobber (match_dup 0))
19299      (clobber (match_dup 1))
19300      (clobber (match_dup 2))])]
19301   "")
19302
19303
19304 \f
19305 ;; Conditional move instructions.
19306
19307 (define_expand "movdicc"
19308   [(set (match_operand:DI 0 "register_operand" "")
19309         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19310                          (match_operand:DI 2 "general_operand" "")
19311                          (match_operand:DI 3 "general_operand" "")))]
19312   "TARGET_64BIT"
19313   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19314
19315 (define_insn "x86_movdicc_0_m1_rex64"
19316   [(set (match_operand:DI 0 "register_operand" "=r")
19317         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19318           (const_int -1)
19319           (const_int 0)))
19320    (clobber (reg:CC FLAGS_REG))]
19321   "TARGET_64BIT"
19322   "sbb{q}\t%0, %0"
19323   ; Since we don't have the proper number of operands for an alu insn,
19324   ; fill in all the blanks.
19325   [(set_attr "type" "alu")
19326    (set_attr "pent_pair" "pu")
19327    (set_attr "memory" "none")
19328    (set_attr "imm_disp" "false")
19329    (set_attr "mode" "DI")
19330    (set_attr "length_immediate" "0")])
19331
19332 (define_insn "*x86_movdicc_0_m1_se"
19333   [(set (match_operand:DI 0 "register_operand" "=r")
19334         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19335                          (const_int 1)
19336                          (const_int 0)))
19337    (clobber (reg:CC FLAGS_REG))]
19338   ""
19339   "sbb{q}\t%0, %0"
19340   [(set_attr "type" "alu")
19341    (set_attr "pent_pair" "pu")
19342    (set_attr "memory" "none")
19343    (set_attr "imm_disp" "false")
19344    (set_attr "mode" "DI")
19345    (set_attr "length_immediate" "0")])
19346
19347 (define_insn "*movdicc_c_rex64"
19348   [(set (match_operand:DI 0 "register_operand" "=r,r")
19349         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19350                                 [(reg FLAGS_REG) (const_int 0)])
19351                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19352                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19353   "TARGET_64BIT && TARGET_CMOVE
19354    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19355   "@
19356    cmov%O2%C1\t{%2, %0|%0, %2}
19357    cmov%O2%c1\t{%3, %0|%0, %3}"
19358   [(set_attr "type" "icmov")
19359    (set_attr "mode" "DI")])
19360
19361 (define_expand "movsicc"
19362   [(set (match_operand:SI 0 "register_operand" "")
19363         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19364                          (match_operand:SI 2 "general_operand" "")
19365                          (match_operand:SI 3 "general_operand" "")))]
19366   ""
19367   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19368
19369 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19370 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19371 ;; So just document what we're doing explicitly.
19372
19373 (define_insn "x86_movsicc_0_m1"
19374   [(set (match_operand:SI 0 "register_operand" "=r")
19375         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19376           (const_int -1)
19377           (const_int 0)))
19378    (clobber (reg:CC FLAGS_REG))]
19379   ""
19380   "sbb{l}\t%0, %0"
19381   ; Since we don't have the proper number of operands for an alu insn,
19382   ; fill in all the blanks.
19383   [(set_attr "type" "alu")
19384    (set_attr "pent_pair" "pu")
19385    (set_attr "memory" "none")
19386    (set_attr "imm_disp" "false")
19387    (set_attr "mode" "SI")
19388    (set_attr "length_immediate" "0")])
19389
19390 (define_insn "*x86_movsicc_0_m1_se"
19391   [(set (match_operand:SI 0 "register_operand" "=r")
19392         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19393                          (const_int 1)
19394                          (const_int 0)))
19395    (clobber (reg:CC FLAGS_REG))]
19396   ""
19397   "sbb{l}\t%0, %0"
19398   [(set_attr "type" "alu")
19399    (set_attr "pent_pair" "pu")
19400    (set_attr "memory" "none")
19401    (set_attr "imm_disp" "false")
19402    (set_attr "mode" "SI")
19403    (set_attr "length_immediate" "0")])
19404
19405 (define_insn "*movsicc_noc"
19406   [(set (match_operand:SI 0 "register_operand" "=r,r")
19407         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19408                                 [(reg FLAGS_REG) (const_int 0)])
19409                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19410                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19411   "TARGET_CMOVE
19412    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19413   "@
19414    cmov%O2%C1\t{%2, %0|%0, %2}
19415    cmov%O2%c1\t{%3, %0|%0, %3}"
19416   [(set_attr "type" "icmov")
19417    (set_attr "mode" "SI")])
19418
19419 (define_expand "movhicc"
19420   [(set (match_operand:HI 0 "register_operand" "")
19421         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19422                          (match_operand:HI 2 "general_operand" "")
19423                          (match_operand:HI 3 "general_operand" "")))]
19424   "TARGET_HIMODE_MATH"
19425   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19426
19427 (define_insn "*movhicc_noc"
19428   [(set (match_operand:HI 0 "register_operand" "=r,r")
19429         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19430                                 [(reg FLAGS_REG) (const_int 0)])
19431                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19432                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19433   "TARGET_CMOVE
19434    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19435   "@
19436    cmov%O2%C1\t{%2, %0|%0, %2}
19437    cmov%O2%c1\t{%3, %0|%0, %3}"
19438   [(set_attr "type" "icmov")
19439    (set_attr "mode" "HI")])
19440
19441 (define_expand "movqicc"
19442   [(set (match_operand:QI 0 "register_operand" "")
19443         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19444                          (match_operand:QI 2 "general_operand" "")
19445                          (match_operand:QI 3 "general_operand" "")))]
19446   "TARGET_QIMODE_MATH"
19447   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19448
19449 (define_insn_and_split "*movqicc_noc"
19450   [(set (match_operand:QI 0 "register_operand" "=r,r")
19451         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19452                                 [(match_operand 4 "flags_reg_operand" "")
19453                                  (const_int 0)])
19454                       (match_operand:QI 2 "register_operand" "r,0")
19455                       (match_operand:QI 3 "register_operand" "0,r")))]
19456   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19457   "#"
19458   "&& reload_completed"
19459   [(set (match_dup 0)
19460         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19461                       (match_dup 2)
19462                       (match_dup 3)))]
19463   "operands[0] = gen_lowpart (SImode, operands[0]);
19464    operands[2] = gen_lowpart (SImode, operands[2]);
19465    operands[3] = gen_lowpart (SImode, operands[3]);"
19466   [(set_attr "type" "icmov")
19467    (set_attr "mode" "SI")])
19468
19469 (define_expand "mov<mode>cc"
19470   [(set (match_operand:X87MODEF 0 "register_operand" "")
19471         (if_then_else:X87MODEF
19472           (match_operand 1 "comparison_operator" "")
19473           (match_operand:X87MODEF 2 "register_operand" "")
19474           (match_operand:X87MODEF 3 "register_operand" "")))]
19475   "(TARGET_80387 && TARGET_CMOVE)
19476    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19477   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19478
19479 (define_insn "*movsfcc_1_387"
19480   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19481         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19482                                 [(reg FLAGS_REG) (const_int 0)])
19483                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19484                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19485   "TARGET_80387 && TARGET_CMOVE
19486    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19487   "@
19488    fcmov%F1\t{%2, %0|%0, %2}
19489    fcmov%f1\t{%3, %0|%0, %3}
19490    cmov%O2%C1\t{%2, %0|%0, %2}
19491    cmov%O2%c1\t{%3, %0|%0, %3}"
19492   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19493    (set_attr "mode" "SF,SF,SI,SI")])
19494
19495 (define_insn "*movdfcc_1"
19496   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19497         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19498                                 [(reg FLAGS_REG) (const_int 0)])
19499                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19500                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19501   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19502    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19503   "@
19504    fcmov%F1\t{%2, %0|%0, %2}
19505    fcmov%f1\t{%3, %0|%0, %3}
19506    #
19507    #"
19508   [(set_attr "type" "fcmov,fcmov,multi,multi")
19509    (set_attr "mode" "DF")])
19510
19511 (define_insn "*movdfcc_1_rex64"
19512   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19513         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19514                                 [(reg FLAGS_REG) (const_int 0)])
19515                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19516                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19517   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19518    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19519   "@
19520    fcmov%F1\t{%2, %0|%0, %2}
19521    fcmov%f1\t{%3, %0|%0, %3}
19522    cmov%O2%C1\t{%2, %0|%0, %2}
19523    cmov%O2%c1\t{%3, %0|%0, %3}"
19524   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19525    (set_attr "mode" "DF")])
19526
19527 (define_split
19528   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19529         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19530                                 [(match_operand 4 "flags_reg_operand" "")
19531                                  (const_int 0)])
19532                       (match_operand:DF 2 "nonimmediate_operand" "")
19533                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19534   "!TARGET_64BIT && reload_completed"
19535   [(set (match_dup 2)
19536         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19537                       (match_dup 5)
19538                       (match_dup 6)))
19539    (set (match_dup 3)
19540         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19541                       (match_dup 7)
19542                       (match_dup 8)))]
19543   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19544    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19545
19546 (define_insn "*movxfcc_1"
19547   [(set (match_operand:XF 0 "register_operand" "=f,f")
19548         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19549                                 [(reg FLAGS_REG) (const_int 0)])
19550                       (match_operand:XF 2 "register_operand" "f,0")
19551                       (match_operand:XF 3 "register_operand" "0,f")))]
19552   "TARGET_80387 && TARGET_CMOVE"
19553   "@
19554    fcmov%F1\t{%2, %0|%0, %2}
19555    fcmov%f1\t{%3, %0|%0, %3}"
19556   [(set_attr "type" "fcmov")
19557    (set_attr "mode" "XF")])
19558
19559 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19560 ;; the scalar versions to have only XMM registers as operands.
19561
19562 ;; SSE5 conditional move
19563 (define_insn "*sse5_pcmov_<mode>"
19564   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19565         (if_then_else:MODEF
19566           (match_operand:MODEF 1 "register_operand" "x,0")
19567           (match_operand:MODEF 2 "register_operand" "0,x")
19568           (match_operand:MODEF 3 "register_operand" "x,x")))]
19569   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19570   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19571   [(set_attr "type" "sse4arg")])
19572
19573 ;; These versions of the min/max patterns are intentionally ignorant of
19574 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19575 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19576 ;; are undefined in this condition, we're certain this is correct.
19577
19578 (define_insn "<code><mode>3"
19579   [(set (match_operand:MODEF 0 "register_operand" "=x")
19580         (smaxmin:MODEF
19581           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19582           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19583   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19584   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19585   [(set_attr "type" "sseadd")
19586    (set_attr "mode" "<MODE>")])
19587
19588 ;; These versions of the min/max patterns implement exactly the operations
19589 ;;   min = (op1 < op2 ? op1 : op2)
19590 ;;   max = (!(op1 < op2) ? op1 : op2)
19591 ;; Their operands are not commutative, and thus they may be used in the
19592 ;; presence of -0.0 and NaN.
19593
19594 (define_insn "*ieee_smin<mode>3"
19595   [(set (match_operand:MODEF 0 "register_operand" "=x")
19596         (unspec:MODEF
19597           [(match_operand:MODEF 1 "register_operand" "0")
19598            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19599          UNSPEC_IEEE_MIN))]
19600   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19601   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19602   [(set_attr "type" "sseadd")
19603    (set_attr "mode" "<MODE>")])
19604
19605 (define_insn "*ieee_smax<mode>3"
19606   [(set (match_operand:MODEF 0 "register_operand" "=x")
19607         (unspec:MODEF
19608           [(match_operand:MODEF 1 "register_operand" "0")
19609            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19610          UNSPEC_IEEE_MAX))]
19611   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19612   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19613   [(set_attr "type" "sseadd")
19614    (set_attr "mode" "<MODE>")])
19615
19616 ;; Make two stack loads independent:
19617 ;;   fld aa              fld aa
19618 ;;   fld %st(0)     ->   fld bb
19619 ;;   fmul bb             fmul %st(1), %st
19620 ;;
19621 ;; Actually we only match the last two instructions for simplicity.
19622 (define_peephole2
19623   [(set (match_operand 0 "fp_register_operand" "")
19624         (match_operand 1 "fp_register_operand" ""))
19625    (set (match_dup 0)
19626         (match_operator 2 "binary_fp_operator"
19627            [(match_dup 0)
19628             (match_operand 3 "memory_operand" "")]))]
19629   "REGNO (operands[0]) != REGNO (operands[1])"
19630   [(set (match_dup 0) (match_dup 3))
19631    (set (match_dup 0) (match_dup 4))]
19632
19633   ;; The % modifier is not operational anymore in peephole2's, so we have to
19634   ;; swap the operands manually in the case of addition and multiplication.
19635   "if (COMMUTATIVE_ARITH_P (operands[2]))
19636      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19637                                  operands[0], operands[1]);
19638    else
19639      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19640                                  operands[1], operands[0]);")
19641
19642 ;; Conditional addition patterns
19643 (define_expand "add<mode>cc"
19644   [(match_operand:SWI 0 "register_operand" "")
19645    (match_operand 1 "comparison_operator" "")
19646    (match_operand:SWI 2 "register_operand" "")
19647    (match_operand:SWI 3 "const_int_operand" "")]
19648   ""
19649   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19650
19651 \f
19652 ;; Misc patterns (?)
19653
19654 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19655 ;; Otherwise there will be nothing to keep
19656 ;;
19657 ;; [(set (reg ebp) (reg esp))]
19658 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19659 ;;  (clobber (eflags)]
19660 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19661 ;;
19662 ;; in proper program order.
19663 (define_insn "pro_epilogue_adjust_stack_1"
19664   [(set (match_operand:SI 0 "register_operand" "=r,r")
19665         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19666                  (match_operand:SI 2 "immediate_operand" "i,i")))
19667    (clobber (reg:CC FLAGS_REG))
19668    (clobber (mem:BLK (scratch)))]
19669   "!TARGET_64BIT"
19670 {
19671   switch (get_attr_type (insn))
19672     {
19673     case TYPE_IMOV:
19674       return "mov{l}\t{%1, %0|%0, %1}";
19675
19676     case TYPE_ALU:
19677       if (CONST_INT_P (operands[2])
19678           && (INTVAL (operands[2]) == 128
19679               || (INTVAL (operands[2]) < 0
19680                   && INTVAL (operands[2]) != -128)))
19681         {
19682           operands[2] = GEN_INT (-INTVAL (operands[2]));
19683           return "sub{l}\t{%2, %0|%0, %2}";
19684         }
19685       return "add{l}\t{%2, %0|%0, %2}";
19686
19687     case TYPE_LEA:
19688       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19689       return "lea{l}\t{%a2, %0|%0, %a2}";
19690
19691     default:
19692       gcc_unreachable ();
19693     }
19694 }
19695   [(set (attr "type")
19696         (cond [(eq_attr "alternative" "0")
19697                  (const_string "alu")
19698                (match_operand:SI 2 "const0_operand" "")
19699                  (const_string "imov")
19700               ]
19701               (const_string "lea")))
19702    (set_attr "mode" "SI")])
19703
19704 (define_insn "pro_epilogue_adjust_stack_rex64"
19705   [(set (match_operand:DI 0 "register_operand" "=r,r")
19706         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19707                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19708    (clobber (reg:CC FLAGS_REG))
19709    (clobber (mem:BLK (scratch)))]
19710   "TARGET_64BIT"
19711 {
19712   switch (get_attr_type (insn))
19713     {
19714     case TYPE_IMOV:
19715       return "mov{q}\t{%1, %0|%0, %1}";
19716
19717     case TYPE_ALU:
19718       if (CONST_INT_P (operands[2])
19719           /* Avoid overflows.  */
19720           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19721           && (INTVAL (operands[2]) == 128
19722               || (INTVAL (operands[2]) < 0
19723                   && INTVAL (operands[2]) != -128)))
19724         {
19725           operands[2] = GEN_INT (-INTVAL (operands[2]));
19726           return "sub{q}\t{%2, %0|%0, %2}";
19727         }
19728       return "add{q}\t{%2, %0|%0, %2}";
19729
19730     case TYPE_LEA:
19731       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19732       return "lea{q}\t{%a2, %0|%0, %a2}";
19733
19734     default:
19735       gcc_unreachable ();
19736     }
19737 }
19738   [(set (attr "type")
19739         (cond [(eq_attr "alternative" "0")
19740                  (const_string "alu")
19741                (match_operand:DI 2 "const0_operand" "")
19742                  (const_string "imov")
19743               ]
19744               (const_string "lea")))
19745    (set_attr "mode" "DI")])
19746
19747 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19748   [(set (match_operand:DI 0 "register_operand" "=r,r")
19749         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19750                  (match_operand:DI 3 "immediate_operand" "i,i")))
19751    (use (match_operand:DI 2 "register_operand" "r,r"))
19752    (clobber (reg:CC FLAGS_REG))
19753    (clobber (mem:BLK (scratch)))]
19754   "TARGET_64BIT"
19755 {
19756   switch (get_attr_type (insn))
19757     {
19758     case TYPE_ALU:
19759       return "add{q}\t{%2, %0|%0, %2}";
19760
19761     case TYPE_LEA:
19762       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19763       return "lea{q}\t{%a2, %0|%0, %a2}";
19764
19765     default:
19766       gcc_unreachable ();
19767     }
19768 }
19769   [(set_attr "type" "alu,lea")
19770    (set_attr "mode" "DI")])
19771
19772 (define_insn "allocate_stack_worker_32"
19773   [(set (match_operand:SI 0 "register_operand" "+a")
19774         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19775    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19776    (clobber (reg:CC FLAGS_REG))]
19777   "!TARGET_64BIT && TARGET_STACK_PROBE"
19778   "call\t___chkstk"
19779   [(set_attr "type" "multi")
19780    (set_attr "length" "5")])
19781
19782 (define_insn "allocate_stack_worker_64"
19783   [(set (match_operand:DI 0 "register_operand" "+a")
19784         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19785    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19786    (clobber (reg:DI R10_REG))
19787    (clobber (reg:DI R11_REG))
19788    (clobber (reg:CC FLAGS_REG))]
19789   "TARGET_64BIT && TARGET_STACK_PROBE"
19790   "call\t___chkstk"
19791   [(set_attr "type" "multi")
19792    (set_attr "length" "5")])
19793
19794 (define_expand "allocate_stack"
19795   [(match_operand 0 "register_operand" "")
19796    (match_operand 1 "general_operand" "")]
19797   "TARGET_STACK_PROBE"
19798 {
19799   rtx x;
19800
19801 #ifndef CHECK_STACK_LIMIT
19802 #define CHECK_STACK_LIMIT 0
19803 #endif
19804
19805   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19806       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19807     {
19808       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19809                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19810       if (x != stack_pointer_rtx)
19811         emit_move_insn (stack_pointer_rtx, x);
19812     }
19813   else
19814     {
19815       x = copy_to_mode_reg (Pmode, operands[1]);
19816       if (TARGET_64BIT)
19817         x = gen_allocate_stack_worker_64 (x);
19818       else
19819         x = gen_allocate_stack_worker_32 (x);
19820       emit_insn (x);
19821     }
19822
19823   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19824   DONE;
19825 })
19826
19827 (define_expand "builtin_setjmp_receiver"
19828   [(label_ref (match_operand 0 "" ""))]
19829   "!TARGET_64BIT && flag_pic"
19830 {
19831   if (TARGET_MACHO)
19832     {
19833       rtx xops[3];
19834       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19835       rtx label_rtx = gen_label_rtx ();
19836       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19837       xops[0] = xops[1] = picreg;
19838       xops[2] = gen_rtx_CONST (SImode,
19839                   gen_rtx_MINUS (SImode,
19840                     gen_rtx_LABEL_REF (SImode, label_rtx),
19841                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19842       ix86_expand_binary_operator (MINUS, SImode, xops);
19843     }
19844   else
19845     emit_insn (gen_set_got (pic_offset_table_rtx));
19846   DONE;
19847 })
19848 \f
19849 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19850
19851 (define_split
19852   [(set (match_operand 0 "register_operand" "")
19853         (match_operator 3 "promotable_binary_operator"
19854            [(match_operand 1 "register_operand" "")
19855             (match_operand 2 "aligned_operand" "")]))
19856    (clobber (reg:CC FLAGS_REG))]
19857   "! TARGET_PARTIAL_REG_STALL && reload_completed
19858    && ((GET_MODE (operands[0]) == HImode
19859         && ((!optimize_size && !TARGET_FAST_PREFIX)
19860             /* ??? next two lines just !satisfies_constraint_K (...) */
19861             || !CONST_INT_P (operands[2])
19862             || satisfies_constraint_K (operands[2])))
19863        || (GET_MODE (operands[0]) == QImode
19864            && (TARGET_PROMOTE_QImode || optimize_size)))"
19865   [(parallel [(set (match_dup 0)
19866                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19867               (clobber (reg:CC FLAGS_REG))])]
19868   "operands[0] = gen_lowpart (SImode, operands[0]);
19869    operands[1] = gen_lowpart (SImode, operands[1]);
19870    if (GET_CODE (operands[3]) != ASHIFT)
19871      operands[2] = gen_lowpart (SImode, operands[2]);
19872    PUT_MODE (operands[3], SImode);")
19873
19874 ; Promote the QImode tests, as i386 has encoding of the AND
19875 ; instruction with 32-bit sign-extended immediate and thus the
19876 ; instruction size is unchanged, except in the %eax case for
19877 ; which it is increased by one byte, hence the ! optimize_size.
19878 (define_split
19879   [(set (match_operand 0 "flags_reg_operand" "")
19880         (match_operator 2 "compare_operator"
19881           [(and (match_operand 3 "aligned_operand" "")
19882                 (match_operand 4 "const_int_operand" ""))
19883            (const_int 0)]))
19884    (set (match_operand 1 "register_operand" "")
19885         (and (match_dup 3) (match_dup 4)))]
19886   "! TARGET_PARTIAL_REG_STALL && reload_completed
19887    && ! optimize_size
19888    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19889        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19890    /* Ensure that the operand will remain sign-extended immediate.  */
19891    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19892   [(parallel [(set (match_dup 0)
19893                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19894                                     (const_int 0)]))
19895               (set (match_dup 1)
19896                    (and:SI (match_dup 3) (match_dup 4)))])]
19897 {
19898   operands[4]
19899     = gen_int_mode (INTVAL (operands[4])
19900                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19901   operands[1] = gen_lowpart (SImode, operands[1]);
19902   operands[3] = gen_lowpart (SImode, operands[3]);
19903 })
19904
19905 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19906 ; the TEST instruction with 32-bit sign-extended immediate and thus
19907 ; the instruction size would at least double, which is not what we
19908 ; want even with ! optimize_size.
19909 (define_split
19910   [(set (match_operand 0 "flags_reg_operand" "")
19911         (match_operator 1 "compare_operator"
19912           [(and (match_operand:HI 2 "aligned_operand" "")
19913                 (match_operand:HI 3 "const_int_operand" ""))
19914            (const_int 0)]))]
19915   "! TARGET_PARTIAL_REG_STALL && reload_completed
19916    && ! TARGET_FAST_PREFIX
19917    && ! optimize_size
19918    /* Ensure that the operand will remain sign-extended immediate.  */
19919    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19920   [(set (match_dup 0)
19921         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19922                          (const_int 0)]))]
19923 {
19924   operands[3]
19925     = gen_int_mode (INTVAL (operands[3])
19926                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19927   operands[2] = gen_lowpart (SImode, operands[2]);
19928 })
19929
19930 (define_split
19931   [(set (match_operand 0 "register_operand" "")
19932         (neg (match_operand 1 "register_operand" "")))
19933    (clobber (reg:CC FLAGS_REG))]
19934   "! TARGET_PARTIAL_REG_STALL && reload_completed
19935    && (GET_MODE (operands[0]) == HImode
19936        || (GET_MODE (operands[0]) == QImode
19937            && (TARGET_PROMOTE_QImode || optimize_size)))"
19938   [(parallel [(set (match_dup 0)
19939                    (neg:SI (match_dup 1)))
19940               (clobber (reg:CC FLAGS_REG))])]
19941   "operands[0] = gen_lowpart (SImode, operands[0]);
19942    operands[1] = gen_lowpart (SImode, operands[1]);")
19943
19944 (define_split
19945   [(set (match_operand 0 "register_operand" "")
19946         (not (match_operand 1 "register_operand" "")))]
19947   "! TARGET_PARTIAL_REG_STALL && reload_completed
19948    && (GET_MODE (operands[0]) == HImode
19949        || (GET_MODE (operands[0]) == QImode
19950            && (TARGET_PROMOTE_QImode || optimize_size)))"
19951   [(set (match_dup 0)
19952         (not:SI (match_dup 1)))]
19953   "operands[0] = gen_lowpart (SImode, operands[0]);
19954    operands[1] = gen_lowpart (SImode, operands[1]);")
19955
19956 (define_split
19957   [(set (match_operand 0 "register_operand" "")
19958         (if_then_else (match_operator 1 "comparison_operator"
19959                                 [(reg FLAGS_REG) (const_int 0)])
19960                       (match_operand 2 "register_operand" "")
19961                       (match_operand 3 "register_operand" "")))]
19962   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19963    && (GET_MODE (operands[0]) == HImode
19964        || (GET_MODE (operands[0]) == QImode
19965            && (TARGET_PROMOTE_QImode || optimize_size)))"
19966   [(set (match_dup 0)
19967         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19968   "operands[0] = gen_lowpart (SImode, operands[0]);
19969    operands[2] = gen_lowpart (SImode, operands[2]);
19970    operands[3] = gen_lowpart (SImode, operands[3]);")
19971
19972 \f
19973 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19974 ;; transform a complex memory operation into two memory to register operations.
19975
19976 ;; Don't push memory operands
19977 (define_peephole2
19978   [(set (match_operand:SI 0 "push_operand" "")
19979         (match_operand:SI 1 "memory_operand" ""))
19980    (match_scratch:SI 2 "r")]
19981   "!optimize_size && !TARGET_PUSH_MEMORY
19982    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19983   [(set (match_dup 2) (match_dup 1))
19984    (set (match_dup 0) (match_dup 2))]
19985   "")
19986
19987 (define_peephole2
19988   [(set (match_operand:DI 0 "push_operand" "")
19989         (match_operand:DI 1 "memory_operand" ""))
19990    (match_scratch:DI 2 "r")]
19991   "!optimize_size && !TARGET_PUSH_MEMORY
19992    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19993   [(set (match_dup 2) (match_dup 1))
19994    (set (match_dup 0) (match_dup 2))]
19995   "")
19996
19997 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19998 ;; SImode pushes.
19999 (define_peephole2
20000   [(set (match_operand:SF 0 "push_operand" "")
20001         (match_operand:SF 1 "memory_operand" ""))
20002    (match_scratch:SF 2 "r")]
20003   "!optimize_size && !TARGET_PUSH_MEMORY
20004    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20005   [(set (match_dup 2) (match_dup 1))
20006    (set (match_dup 0) (match_dup 2))]
20007   "")
20008
20009 (define_peephole2
20010   [(set (match_operand:HI 0 "push_operand" "")
20011         (match_operand:HI 1 "memory_operand" ""))
20012    (match_scratch:HI 2 "r")]
20013   "!optimize_size && !TARGET_PUSH_MEMORY
20014    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20015   [(set (match_dup 2) (match_dup 1))
20016    (set (match_dup 0) (match_dup 2))]
20017   "")
20018
20019 (define_peephole2
20020   [(set (match_operand:QI 0 "push_operand" "")
20021         (match_operand:QI 1 "memory_operand" ""))
20022    (match_scratch:QI 2 "q")]
20023   "!optimize_size && !TARGET_PUSH_MEMORY
20024    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20025   [(set (match_dup 2) (match_dup 1))
20026    (set (match_dup 0) (match_dup 2))]
20027   "")
20028
20029 ;; Don't move an immediate directly to memory when the instruction
20030 ;; gets too big.
20031 (define_peephole2
20032   [(match_scratch:SI 1 "r")
20033    (set (match_operand:SI 0 "memory_operand" "")
20034         (const_int 0))]
20035   "! optimize_size
20036    && ! TARGET_USE_MOV0
20037    && TARGET_SPLIT_LONG_MOVES
20038    && get_attr_length (insn) >= ix86_cost->large_insn
20039    && peep2_regno_dead_p (0, FLAGS_REG)"
20040   [(parallel [(set (match_dup 1) (const_int 0))
20041               (clobber (reg:CC FLAGS_REG))])
20042    (set (match_dup 0) (match_dup 1))]
20043   "")
20044
20045 (define_peephole2
20046   [(match_scratch:HI 1 "r")
20047    (set (match_operand:HI 0 "memory_operand" "")
20048         (const_int 0))]
20049   "! optimize_size
20050    && ! TARGET_USE_MOV0
20051    && TARGET_SPLIT_LONG_MOVES
20052    && get_attr_length (insn) >= ix86_cost->large_insn
20053    && peep2_regno_dead_p (0, FLAGS_REG)"
20054   [(parallel [(set (match_dup 2) (const_int 0))
20055               (clobber (reg:CC FLAGS_REG))])
20056    (set (match_dup 0) (match_dup 1))]
20057   "operands[2] = gen_lowpart (SImode, operands[1]);")
20058
20059 (define_peephole2
20060   [(match_scratch:QI 1 "q")
20061    (set (match_operand:QI 0 "memory_operand" "")
20062         (const_int 0))]
20063   "! optimize_size
20064    && ! TARGET_USE_MOV0
20065    && TARGET_SPLIT_LONG_MOVES
20066    && get_attr_length (insn) >= ix86_cost->large_insn
20067    && peep2_regno_dead_p (0, FLAGS_REG)"
20068   [(parallel [(set (match_dup 2) (const_int 0))
20069               (clobber (reg:CC FLAGS_REG))])
20070    (set (match_dup 0) (match_dup 1))]
20071   "operands[2] = gen_lowpart (SImode, operands[1]);")
20072
20073 (define_peephole2
20074   [(match_scratch:SI 2 "r")
20075    (set (match_operand:SI 0 "memory_operand" "")
20076         (match_operand:SI 1 "immediate_operand" ""))]
20077   "! optimize_size
20078    && TARGET_SPLIT_LONG_MOVES
20079    && get_attr_length (insn) >= ix86_cost->large_insn"
20080   [(set (match_dup 2) (match_dup 1))
20081    (set (match_dup 0) (match_dup 2))]
20082   "")
20083
20084 (define_peephole2
20085   [(match_scratch:HI 2 "r")
20086    (set (match_operand:HI 0 "memory_operand" "")
20087         (match_operand:HI 1 "immediate_operand" ""))]
20088   "! optimize_size
20089    && TARGET_SPLIT_LONG_MOVES
20090    && get_attr_length (insn) >= ix86_cost->large_insn"
20091   [(set (match_dup 2) (match_dup 1))
20092    (set (match_dup 0) (match_dup 2))]
20093   "")
20094
20095 (define_peephole2
20096   [(match_scratch:QI 2 "q")
20097    (set (match_operand:QI 0 "memory_operand" "")
20098         (match_operand:QI 1 "immediate_operand" ""))]
20099   "! optimize_size
20100    && TARGET_SPLIT_LONG_MOVES
20101    && get_attr_length (insn) >= ix86_cost->large_insn"
20102   [(set (match_dup 2) (match_dup 1))
20103    (set (match_dup 0) (match_dup 2))]
20104   "")
20105
20106 ;; Don't compare memory with zero, load and use a test instead.
20107 (define_peephole2
20108   [(set (match_operand 0 "flags_reg_operand" "")
20109         (match_operator 1 "compare_operator"
20110           [(match_operand:SI 2 "memory_operand" "")
20111            (const_int 0)]))
20112    (match_scratch:SI 3 "r")]
20113   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20114   [(set (match_dup 3) (match_dup 2))
20115    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20116   "")
20117
20118 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20119 ;; Don't split NOTs with a displacement operand, because resulting XOR
20120 ;; will not be pairable anyway.
20121 ;;
20122 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20123 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20124 ;; so this split helps here as well.
20125 ;;
20126 ;; Note: Can't do this as a regular split because we can't get proper
20127 ;; lifetime information then.
20128
20129 (define_peephole2
20130   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20131         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20132   "!optimize_size
20133    && ((TARGET_NOT_UNPAIRABLE
20134         && (!MEM_P (operands[0])
20135             || !memory_displacement_operand (operands[0], SImode)))
20136        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20137    && peep2_regno_dead_p (0, FLAGS_REG)"
20138   [(parallel [(set (match_dup 0)
20139                    (xor:SI (match_dup 1) (const_int -1)))
20140               (clobber (reg:CC FLAGS_REG))])]
20141   "")
20142
20143 (define_peephole2
20144   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20145         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20146   "!optimize_size
20147    && ((TARGET_NOT_UNPAIRABLE
20148         && (!MEM_P (operands[0])
20149             || !memory_displacement_operand (operands[0], HImode)))
20150        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20151    && peep2_regno_dead_p (0, FLAGS_REG)"
20152   [(parallel [(set (match_dup 0)
20153                    (xor:HI (match_dup 1) (const_int -1)))
20154               (clobber (reg:CC FLAGS_REG))])]
20155   "")
20156
20157 (define_peephole2
20158   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20159         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20160   "!optimize_size
20161    && ((TARGET_NOT_UNPAIRABLE
20162         && (!MEM_P (operands[0])
20163             || !memory_displacement_operand (operands[0], QImode)))
20164        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20165    && peep2_regno_dead_p (0, FLAGS_REG)"
20166   [(parallel [(set (match_dup 0)
20167                    (xor:QI (match_dup 1) (const_int -1)))
20168               (clobber (reg:CC FLAGS_REG))])]
20169   "")
20170
20171 ;; Non pairable "test imm, reg" instructions can be translated to
20172 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20173 ;; byte opcode instead of two, have a short form for byte operands),
20174 ;; so do it for other CPUs as well.  Given that the value was dead,
20175 ;; this should not create any new dependencies.  Pass on the sub-word
20176 ;; versions if we're concerned about partial register stalls.
20177
20178 (define_peephole2
20179   [(set (match_operand 0 "flags_reg_operand" "")
20180         (match_operator 1 "compare_operator"
20181           [(and:SI (match_operand:SI 2 "register_operand" "")
20182                    (match_operand:SI 3 "immediate_operand" ""))
20183            (const_int 0)]))]
20184   "ix86_match_ccmode (insn, CCNOmode)
20185    && (true_regnum (operands[2]) != AX_REG
20186        || satisfies_constraint_K (operands[3]))
20187    && peep2_reg_dead_p (1, operands[2])"
20188   [(parallel
20189      [(set (match_dup 0)
20190            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20191                             (const_int 0)]))
20192       (set (match_dup 2)
20193            (and:SI (match_dup 2) (match_dup 3)))])]
20194   "")
20195
20196 ;; We don't need to handle HImode case, because it will be promoted to SImode
20197 ;; on ! TARGET_PARTIAL_REG_STALL
20198
20199 (define_peephole2
20200   [(set (match_operand 0 "flags_reg_operand" "")
20201         (match_operator 1 "compare_operator"
20202           [(and:QI (match_operand:QI 2 "register_operand" "")
20203                    (match_operand:QI 3 "immediate_operand" ""))
20204            (const_int 0)]))]
20205   "! TARGET_PARTIAL_REG_STALL
20206    && ix86_match_ccmode (insn, CCNOmode)
20207    && true_regnum (operands[2]) != AX_REG
20208    && peep2_reg_dead_p (1, operands[2])"
20209   [(parallel
20210      [(set (match_dup 0)
20211            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20212                             (const_int 0)]))
20213       (set (match_dup 2)
20214            (and:QI (match_dup 2) (match_dup 3)))])]
20215   "")
20216
20217 (define_peephole2
20218   [(set (match_operand 0 "flags_reg_operand" "")
20219         (match_operator 1 "compare_operator"
20220           [(and:SI
20221              (zero_extract:SI
20222                (match_operand 2 "ext_register_operand" "")
20223                (const_int 8)
20224                (const_int 8))
20225              (match_operand 3 "const_int_operand" ""))
20226            (const_int 0)]))]
20227   "! TARGET_PARTIAL_REG_STALL
20228    && ix86_match_ccmode (insn, CCNOmode)
20229    && true_regnum (operands[2]) != AX_REG
20230    && peep2_reg_dead_p (1, operands[2])"
20231   [(parallel [(set (match_dup 0)
20232                    (match_op_dup 1
20233                      [(and:SI
20234                         (zero_extract:SI
20235                           (match_dup 2)
20236                           (const_int 8)
20237                           (const_int 8))
20238                         (match_dup 3))
20239                       (const_int 0)]))
20240               (set (zero_extract:SI (match_dup 2)
20241                                     (const_int 8)
20242                                     (const_int 8))
20243                    (and:SI
20244                      (zero_extract:SI
20245                        (match_dup 2)
20246                        (const_int 8)
20247                        (const_int 8))
20248                      (match_dup 3)))])]
20249   "")
20250
20251 ;; Don't do logical operations with memory inputs.
20252 (define_peephole2
20253   [(match_scratch:SI 2 "r")
20254    (parallel [(set (match_operand:SI 0 "register_operand" "")
20255                    (match_operator:SI 3 "arith_or_logical_operator"
20256                      [(match_dup 0)
20257                       (match_operand:SI 1 "memory_operand" "")]))
20258               (clobber (reg:CC FLAGS_REG))])]
20259   "! optimize_size && ! TARGET_READ_MODIFY"
20260   [(set (match_dup 2) (match_dup 1))
20261    (parallel [(set (match_dup 0)
20262                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20263               (clobber (reg:CC FLAGS_REG))])]
20264   "")
20265
20266 (define_peephole2
20267   [(match_scratch:SI 2 "r")
20268    (parallel [(set (match_operand:SI 0 "register_operand" "")
20269                    (match_operator:SI 3 "arith_or_logical_operator"
20270                      [(match_operand:SI 1 "memory_operand" "")
20271                       (match_dup 0)]))
20272               (clobber (reg:CC FLAGS_REG))])]
20273   "! optimize_size && ! TARGET_READ_MODIFY"
20274   [(set (match_dup 2) (match_dup 1))
20275    (parallel [(set (match_dup 0)
20276                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20277               (clobber (reg:CC FLAGS_REG))])]
20278   "")
20279
20280 ; Don't do logical operations with memory outputs
20281 ;
20282 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20283 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20284 ; the same decoder scheduling characteristics as the original.
20285
20286 (define_peephole2
20287   [(match_scratch:SI 2 "r")
20288    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20289                    (match_operator:SI 3 "arith_or_logical_operator"
20290                      [(match_dup 0)
20291                       (match_operand:SI 1 "nonmemory_operand" "")]))
20292               (clobber (reg:CC FLAGS_REG))])]
20293   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20294   [(set (match_dup 2) (match_dup 0))
20295    (parallel [(set (match_dup 2)
20296                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20297               (clobber (reg:CC FLAGS_REG))])
20298    (set (match_dup 0) (match_dup 2))]
20299   "")
20300
20301 (define_peephole2
20302   [(match_scratch:SI 2 "r")
20303    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20304                    (match_operator:SI 3 "arith_or_logical_operator"
20305                      [(match_operand:SI 1 "nonmemory_operand" "")
20306                       (match_dup 0)]))
20307               (clobber (reg:CC FLAGS_REG))])]
20308   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20309   [(set (match_dup 2) (match_dup 0))
20310    (parallel [(set (match_dup 2)
20311                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20312               (clobber (reg:CC FLAGS_REG))])
20313    (set (match_dup 0) (match_dup 2))]
20314   "")
20315
20316 ;; Attempt to always use XOR for zeroing registers.
20317 (define_peephole2
20318   [(set (match_operand 0 "register_operand" "")
20319         (match_operand 1 "const0_operand" ""))]
20320   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20321    && (! TARGET_USE_MOV0 || optimize_size)
20322    && GENERAL_REG_P (operands[0])
20323    && peep2_regno_dead_p (0, FLAGS_REG)"
20324   [(parallel [(set (match_dup 0) (const_int 0))
20325               (clobber (reg:CC FLAGS_REG))])]
20326 {
20327   operands[0] = gen_lowpart (word_mode, operands[0]);
20328 })
20329
20330 (define_peephole2
20331   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20332         (const_int 0))]
20333   "(GET_MODE (operands[0]) == QImode
20334     || GET_MODE (operands[0]) == HImode)
20335    && (! TARGET_USE_MOV0 || optimize_size)
20336    && peep2_regno_dead_p (0, FLAGS_REG)"
20337   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20338               (clobber (reg:CC FLAGS_REG))])])
20339
20340 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20341 (define_peephole2
20342   [(set (match_operand 0 "register_operand" "")
20343         (const_int -1))]
20344   "(GET_MODE (operands[0]) == HImode
20345     || GET_MODE (operands[0]) == SImode
20346     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20347    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20348    && peep2_regno_dead_p (0, FLAGS_REG)"
20349   [(parallel [(set (match_dup 0) (const_int -1))
20350               (clobber (reg:CC FLAGS_REG))])]
20351   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20352                               operands[0]);")
20353
20354 ;; Attempt to convert simple leas to adds. These can be created by
20355 ;; move expanders.
20356 (define_peephole2
20357   [(set (match_operand:SI 0 "register_operand" "")
20358         (plus:SI (match_dup 0)
20359                  (match_operand:SI 1 "nonmemory_operand" "")))]
20360   "peep2_regno_dead_p (0, FLAGS_REG)"
20361   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20362               (clobber (reg:CC FLAGS_REG))])]
20363   "")
20364
20365 (define_peephole2
20366   [(set (match_operand:SI 0 "register_operand" "")
20367         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20368                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20369   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20370   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20371               (clobber (reg:CC FLAGS_REG))])]
20372   "operands[2] = gen_lowpart (SImode, operands[2]);")
20373
20374 (define_peephole2
20375   [(set (match_operand:DI 0 "register_operand" "")
20376         (plus:DI (match_dup 0)
20377                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20378   "peep2_regno_dead_p (0, FLAGS_REG)"
20379   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20380               (clobber (reg:CC FLAGS_REG))])]
20381   "")
20382
20383 (define_peephole2
20384   [(set (match_operand:SI 0 "register_operand" "")
20385         (mult:SI (match_dup 0)
20386                  (match_operand:SI 1 "const_int_operand" "")))]
20387   "exact_log2 (INTVAL (operands[1])) >= 0
20388    && peep2_regno_dead_p (0, FLAGS_REG)"
20389   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20390               (clobber (reg:CC FLAGS_REG))])]
20391   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20392
20393 (define_peephole2
20394   [(set (match_operand:DI 0 "register_operand" "")
20395         (mult:DI (match_dup 0)
20396                  (match_operand:DI 1 "const_int_operand" "")))]
20397   "exact_log2 (INTVAL (operands[1])) >= 0
20398    && peep2_regno_dead_p (0, FLAGS_REG)"
20399   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20400               (clobber (reg:CC FLAGS_REG))])]
20401   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20402
20403 (define_peephole2
20404   [(set (match_operand:SI 0 "register_operand" "")
20405         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20406                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20407   "exact_log2 (INTVAL (operands[2])) >= 0
20408    && REGNO (operands[0]) == REGNO (operands[1])
20409    && peep2_regno_dead_p (0, FLAGS_REG)"
20410   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20411               (clobber (reg:CC FLAGS_REG))])]
20412   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20413
20414 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20415 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20416 ;; many CPUs it is also faster, since special hardware to avoid esp
20417 ;; dependencies is present.
20418
20419 ;; While some of these conversions may be done using splitters, we use peepholes
20420 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20421
20422 ;; Convert prologue esp subtractions to push.
20423 ;; We need register to push.  In order to keep verify_flow_info happy we have
20424 ;; two choices
20425 ;; - use scratch and clobber it in order to avoid dependencies
20426 ;; - use already live register
20427 ;; We can't use the second way right now, since there is no reliable way how to
20428 ;; verify that given register is live.  First choice will also most likely in
20429 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20430 ;; call clobbered registers are dead.  We may want to use base pointer as an
20431 ;; alternative when no register is available later.
20432
20433 (define_peephole2
20434   [(match_scratch:SI 0 "r")
20435    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20436               (clobber (reg:CC FLAGS_REG))
20437               (clobber (mem:BLK (scratch)))])]
20438   "optimize_size || !TARGET_SUB_ESP_4"
20439   [(clobber (match_dup 0))
20440    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20441               (clobber (mem:BLK (scratch)))])])
20442
20443 (define_peephole2
20444   [(match_scratch:SI 0 "r")
20445    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20446               (clobber (reg:CC FLAGS_REG))
20447               (clobber (mem:BLK (scratch)))])]
20448   "optimize_size || !TARGET_SUB_ESP_8"
20449   [(clobber (match_dup 0))
20450    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20451    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20452               (clobber (mem:BLK (scratch)))])])
20453
20454 ;; Convert esp subtractions to push.
20455 (define_peephole2
20456   [(match_scratch:SI 0 "r")
20457    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20458               (clobber (reg:CC FLAGS_REG))])]
20459   "optimize_size || !TARGET_SUB_ESP_4"
20460   [(clobber (match_dup 0))
20461    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20462
20463 (define_peephole2
20464   [(match_scratch:SI 0 "r")
20465    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20466               (clobber (reg:CC FLAGS_REG))])]
20467   "optimize_size || !TARGET_SUB_ESP_8"
20468   [(clobber (match_dup 0))
20469    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20470    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20471
20472 ;; Convert epilogue deallocator to pop.
20473 (define_peephole2
20474   [(match_scratch:SI 0 "r")
20475    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20476               (clobber (reg:CC FLAGS_REG))
20477               (clobber (mem:BLK (scratch)))])]
20478   "optimize_size || !TARGET_ADD_ESP_4"
20479   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20480               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20481               (clobber (mem:BLK (scratch)))])]
20482   "")
20483
20484 ;; Two pops case is tricky, since pop causes dependency on destination register.
20485 ;; We use two registers if available.
20486 (define_peephole2
20487   [(match_scratch:SI 0 "r")
20488    (match_scratch:SI 1 "r")
20489    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20490               (clobber (reg:CC FLAGS_REG))
20491               (clobber (mem:BLK (scratch)))])]
20492   "optimize_size || !TARGET_ADD_ESP_8"
20493   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20494               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20495               (clobber (mem:BLK (scratch)))])
20496    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20497               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20498   "")
20499
20500 (define_peephole2
20501   [(match_scratch:SI 0 "r")
20502    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20503               (clobber (reg:CC FLAGS_REG))
20504               (clobber (mem:BLK (scratch)))])]
20505   "optimize_size"
20506   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20507               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20508               (clobber (mem:BLK (scratch)))])
20509    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20510               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20511   "")
20512
20513 ;; Convert esp additions to pop.
20514 (define_peephole2
20515   [(match_scratch:SI 0 "r")
20516    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20517               (clobber (reg:CC FLAGS_REG))])]
20518   ""
20519   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20520               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20521   "")
20522
20523 ;; Two pops case is tricky, since pop causes dependency on destination register.
20524 ;; We use two registers if available.
20525 (define_peephole2
20526   [(match_scratch:SI 0 "r")
20527    (match_scratch:SI 1 "r")
20528    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20529               (clobber (reg:CC FLAGS_REG))])]
20530   ""
20531   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20532               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20533    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20534               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20535   "")
20536
20537 (define_peephole2
20538   [(match_scratch:SI 0 "r")
20539    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20540               (clobber (reg:CC FLAGS_REG))])]
20541   "optimize_size"
20542   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20543               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20544    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20545               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20546   "")
20547 \f
20548 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20549 ;; required and register dies.  Similarly for 128 to plus -128.
20550 (define_peephole2
20551   [(set (match_operand 0 "flags_reg_operand" "")
20552         (match_operator 1 "compare_operator"
20553           [(match_operand 2 "register_operand" "")
20554            (match_operand 3 "const_int_operand" "")]))]
20555   "(INTVAL (operands[3]) == -1
20556     || INTVAL (operands[3]) == 1
20557     || INTVAL (operands[3]) == 128)
20558    && ix86_match_ccmode (insn, CCGCmode)
20559    && peep2_reg_dead_p (1, operands[2])"
20560   [(parallel [(set (match_dup 0)
20561                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20562               (clobber (match_dup 2))])]
20563   "")
20564 \f
20565 (define_peephole2
20566   [(match_scratch:DI 0 "r")
20567    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20568               (clobber (reg:CC FLAGS_REG))
20569               (clobber (mem:BLK (scratch)))])]
20570   "optimize_size || !TARGET_SUB_ESP_4"
20571   [(clobber (match_dup 0))
20572    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20573               (clobber (mem:BLK (scratch)))])])
20574
20575 (define_peephole2
20576   [(match_scratch:DI 0 "r")
20577    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20578               (clobber (reg:CC FLAGS_REG))
20579               (clobber (mem:BLK (scratch)))])]
20580   "optimize_size || !TARGET_SUB_ESP_8"
20581   [(clobber (match_dup 0))
20582    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20583    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20584               (clobber (mem:BLK (scratch)))])])
20585
20586 ;; Convert esp subtractions to push.
20587 (define_peephole2
20588   [(match_scratch:DI 0 "r")
20589    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20590               (clobber (reg:CC FLAGS_REG))])]
20591   "optimize_size || !TARGET_SUB_ESP_4"
20592   [(clobber (match_dup 0))
20593    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20594
20595 (define_peephole2
20596   [(match_scratch:DI 0 "r")
20597    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20598               (clobber (reg:CC FLAGS_REG))])]
20599   "optimize_size || !TARGET_SUB_ESP_8"
20600   [(clobber (match_dup 0))
20601    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20602    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20603
20604 ;; Convert epilogue deallocator to pop.
20605 (define_peephole2
20606   [(match_scratch:DI 0 "r")
20607    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20608               (clobber (reg:CC FLAGS_REG))
20609               (clobber (mem:BLK (scratch)))])]
20610   "optimize_size || !TARGET_ADD_ESP_4"
20611   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20612               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20613               (clobber (mem:BLK (scratch)))])]
20614   "")
20615
20616 ;; Two pops case is tricky, since pop causes dependency on destination register.
20617 ;; We use two registers if available.
20618 (define_peephole2
20619   [(match_scratch:DI 0 "r")
20620    (match_scratch:DI 1 "r")
20621    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20622               (clobber (reg:CC FLAGS_REG))
20623               (clobber (mem:BLK (scratch)))])]
20624   "optimize_size || !TARGET_ADD_ESP_8"
20625   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20626               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20627               (clobber (mem:BLK (scratch)))])
20628    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20629               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20630   "")
20631
20632 (define_peephole2
20633   [(match_scratch:DI 0 "r")
20634    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20635               (clobber (reg:CC FLAGS_REG))
20636               (clobber (mem:BLK (scratch)))])]
20637   "optimize_size"
20638   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20639               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20640               (clobber (mem:BLK (scratch)))])
20641    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20642               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20643   "")
20644
20645 ;; Convert esp additions to pop.
20646 (define_peephole2
20647   [(match_scratch:DI 0 "r")
20648    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20649               (clobber (reg:CC FLAGS_REG))])]
20650   ""
20651   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20652               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20653   "")
20654
20655 ;; Two pops case is tricky, since pop causes dependency on destination register.
20656 ;; We use two registers if available.
20657 (define_peephole2
20658   [(match_scratch:DI 0 "r")
20659    (match_scratch:DI 1 "r")
20660    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20661               (clobber (reg:CC FLAGS_REG))])]
20662   ""
20663   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20664               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20665    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20666               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20667   "")
20668
20669 (define_peephole2
20670   [(match_scratch:DI 0 "r")
20671    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20672               (clobber (reg:CC FLAGS_REG))])]
20673   "optimize_size"
20674   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20675               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20676    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20677               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20678   "")
20679 \f
20680 ;; Convert imul by three, five and nine into lea
20681 (define_peephole2
20682   [(parallel
20683     [(set (match_operand:SI 0 "register_operand" "")
20684           (mult:SI (match_operand:SI 1 "register_operand" "")
20685                    (match_operand:SI 2 "const_int_operand" "")))
20686      (clobber (reg:CC FLAGS_REG))])]
20687   "INTVAL (operands[2]) == 3
20688    || INTVAL (operands[2]) == 5
20689    || INTVAL (operands[2]) == 9"
20690   [(set (match_dup 0)
20691         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20692                  (match_dup 1)))]
20693   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20694
20695 (define_peephole2
20696   [(parallel
20697     [(set (match_operand:SI 0 "register_operand" "")
20698           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20699                    (match_operand:SI 2 "const_int_operand" "")))
20700      (clobber (reg:CC FLAGS_REG))])]
20701   "!optimize_size
20702    && (INTVAL (operands[2]) == 3
20703        || INTVAL (operands[2]) == 5
20704        || INTVAL (operands[2]) == 9)"
20705   [(set (match_dup 0) (match_dup 1))
20706    (set (match_dup 0)
20707         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20708                  (match_dup 0)))]
20709   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20710
20711 (define_peephole2
20712   [(parallel
20713     [(set (match_operand:DI 0 "register_operand" "")
20714           (mult:DI (match_operand:DI 1 "register_operand" "")
20715                    (match_operand:DI 2 "const_int_operand" "")))
20716      (clobber (reg:CC FLAGS_REG))])]
20717   "TARGET_64BIT
20718    && (INTVAL (operands[2]) == 3
20719        || INTVAL (operands[2]) == 5
20720        || INTVAL (operands[2]) == 9)"
20721   [(set (match_dup 0)
20722         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20723                  (match_dup 1)))]
20724   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20725
20726 (define_peephole2
20727   [(parallel
20728     [(set (match_operand:DI 0 "register_operand" "")
20729           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20730                    (match_operand:DI 2 "const_int_operand" "")))
20731      (clobber (reg:CC FLAGS_REG))])]
20732   "TARGET_64BIT
20733    && !optimize_size
20734    && (INTVAL (operands[2]) == 3
20735        || INTVAL (operands[2]) == 5
20736        || INTVAL (operands[2]) == 9)"
20737   [(set (match_dup 0) (match_dup 1))
20738    (set (match_dup 0)
20739         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20740                  (match_dup 0)))]
20741   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20742
20743 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20744 ;; imul $32bit_imm, reg, reg is direct decoded.
20745 (define_peephole2
20746   [(match_scratch:DI 3 "r")
20747    (parallel [(set (match_operand:DI 0 "register_operand" "")
20748                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20749                             (match_operand:DI 2 "immediate_operand" "")))
20750               (clobber (reg:CC FLAGS_REG))])]
20751   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20752    && !satisfies_constraint_K (operands[2])"
20753   [(set (match_dup 3) (match_dup 1))
20754    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20755               (clobber (reg:CC FLAGS_REG))])]
20756 "")
20757
20758 (define_peephole2
20759   [(match_scratch:SI 3 "r")
20760    (parallel [(set (match_operand:SI 0 "register_operand" "")
20761                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20762                             (match_operand:SI 2 "immediate_operand" "")))
20763               (clobber (reg:CC FLAGS_REG))])]
20764   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20765    && !satisfies_constraint_K (operands[2])"
20766   [(set (match_dup 3) (match_dup 1))
20767    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20768               (clobber (reg:CC FLAGS_REG))])]
20769 "")
20770
20771 (define_peephole2
20772   [(match_scratch:SI 3 "r")
20773    (parallel [(set (match_operand:DI 0 "register_operand" "")
20774                    (zero_extend:DI
20775                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20776                               (match_operand:SI 2 "immediate_operand" ""))))
20777               (clobber (reg:CC FLAGS_REG))])]
20778   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20779    && !satisfies_constraint_K (operands[2])"
20780   [(set (match_dup 3) (match_dup 1))
20781    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20782               (clobber (reg:CC FLAGS_REG))])]
20783 "")
20784
20785 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20786 ;; Convert it into imul reg, reg
20787 ;; It would be better to force assembler to encode instruction using long
20788 ;; immediate, but there is apparently no way to do so.
20789 (define_peephole2
20790   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20791                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20792                             (match_operand:DI 2 "const_int_operand" "")))
20793               (clobber (reg:CC FLAGS_REG))])
20794    (match_scratch:DI 3 "r")]
20795   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20796    && satisfies_constraint_K (operands[2])"
20797   [(set (match_dup 3) (match_dup 2))
20798    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20799               (clobber (reg:CC FLAGS_REG))])]
20800 {
20801   if (!rtx_equal_p (operands[0], operands[1]))
20802     emit_move_insn (operands[0], operands[1]);
20803 })
20804
20805 (define_peephole2
20806   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20807                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20808                             (match_operand:SI 2 "const_int_operand" "")))
20809               (clobber (reg:CC FLAGS_REG))])
20810    (match_scratch:SI 3 "r")]
20811   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20812    && satisfies_constraint_K (operands[2])"
20813   [(set (match_dup 3) (match_dup 2))
20814    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20815               (clobber (reg:CC FLAGS_REG))])]
20816 {
20817   if (!rtx_equal_p (operands[0], operands[1]))
20818     emit_move_insn (operands[0], operands[1]);
20819 })
20820
20821 (define_peephole2
20822   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20823                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20824                             (match_operand:HI 2 "immediate_operand" "")))
20825               (clobber (reg:CC FLAGS_REG))])
20826    (match_scratch:HI 3 "r")]
20827   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20828   [(set (match_dup 3) (match_dup 2))
20829    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20830               (clobber (reg:CC FLAGS_REG))])]
20831 {
20832   if (!rtx_equal_p (operands[0], operands[1]))
20833     emit_move_insn (operands[0], operands[1]);
20834 })
20835
20836 ;; After splitting up read-modify operations, array accesses with memory
20837 ;; operands might end up in form:
20838 ;;  sall    $2, %eax
20839 ;;  movl    4(%esp), %edx
20840 ;;  addl    %edx, %eax
20841 ;; instead of pre-splitting:
20842 ;;  sall    $2, %eax
20843 ;;  addl    4(%esp), %eax
20844 ;; Turn it into:
20845 ;;  movl    4(%esp), %edx
20846 ;;  leal    (%edx,%eax,4), %eax
20847
20848 (define_peephole2
20849   [(parallel [(set (match_operand 0 "register_operand" "")
20850                    (ashift (match_operand 1 "register_operand" "")
20851                            (match_operand 2 "const_int_operand" "")))
20852                (clobber (reg:CC FLAGS_REG))])
20853    (set (match_operand 3 "register_operand")
20854         (match_operand 4 "x86_64_general_operand" ""))
20855    (parallel [(set (match_operand 5 "register_operand" "")
20856                    (plus (match_operand 6 "register_operand" "")
20857                          (match_operand 7 "register_operand" "")))
20858                    (clobber (reg:CC FLAGS_REG))])]
20859   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20860    /* Validate MODE for lea.  */
20861    && ((!TARGET_PARTIAL_REG_STALL
20862         && (GET_MODE (operands[0]) == QImode
20863             || GET_MODE (operands[0]) == HImode))
20864        || GET_MODE (operands[0]) == SImode
20865        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20866    /* We reorder load and the shift.  */
20867    && !rtx_equal_p (operands[1], operands[3])
20868    && !reg_overlap_mentioned_p (operands[0], operands[4])
20869    /* Last PLUS must consist of operand 0 and 3.  */
20870    && !rtx_equal_p (operands[0], operands[3])
20871    && (rtx_equal_p (operands[3], operands[6])
20872        || rtx_equal_p (operands[3], operands[7]))
20873    && (rtx_equal_p (operands[0], operands[6])
20874        || rtx_equal_p (operands[0], operands[7]))
20875    /* The intermediate operand 0 must die or be same as output.  */
20876    && (rtx_equal_p (operands[0], operands[5])
20877        || peep2_reg_dead_p (3, operands[0]))"
20878   [(set (match_dup 3) (match_dup 4))
20879    (set (match_dup 0) (match_dup 1))]
20880 {
20881   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20882   int scale = 1 << INTVAL (operands[2]);
20883   rtx index = gen_lowpart (Pmode, operands[1]);
20884   rtx base = gen_lowpart (Pmode, operands[3]);
20885   rtx dest = gen_lowpart (mode, operands[5]);
20886
20887   operands[1] = gen_rtx_PLUS (Pmode, base,
20888                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20889   if (mode != Pmode)
20890     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20891   operands[0] = dest;
20892 })
20893 \f
20894 ;; Call-value patterns last so that the wildcard operand does not
20895 ;; disrupt insn-recog's switch tables.
20896
20897 (define_insn "*call_value_pop_0"
20898   [(set (match_operand 0 "" "")
20899         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20900               (match_operand:SI 2 "" "")))
20901    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20902                             (match_operand:SI 3 "immediate_operand" "")))]
20903   "!TARGET_64BIT"
20904 {
20905   if (SIBLING_CALL_P (insn))
20906     return "jmp\t%P1";
20907   else
20908     return "call\t%P1";
20909 }
20910   [(set_attr "type" "callv")])
20911
20912 (define_insn "*call_value_pop_1"
20913   [(set (match_operand 0 "" "")
20914         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20915               (match_operand:SI 2 "" "")))
20916    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20917                             (match_operand:SI 3 "immediate_operand" "i")))]
20918   "!TARGET_64BIT"
20919 {
20920   if (constant_call_address_operand (operands[1], Pmode))
20921     {
20922       if (SIBLING_CALL_P (insn))
20923         return "jmp\t%P1";
20924       else
20925         return "call\t%P1";
20926     }
20927   if (SIBLING_CALL_P (insn))
20928     return "jmp\t%A1";
20929   else
20930     return "call\t%A1";
20931 }
20932   [(set_attr "type" "callv")])
20933
20934 (define_insn "*call_value_0"
20935   [(set (match_operand 0 "" "")
20936         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20937               (match_operand:SI 2 "" "")))]
20938   "!TARGET_64BIT"
20939 {
20940   if (SIBLING_CALL_P (insn))
20941     return "jmp\t%P1";
20942   else
20943     return "call\t%P1";
20944 }
20945   [(set_attr "type" "callv")])
20946
20947 (define_insn "*call_value_0_rex64"
20948   [(set (match_operand 0 "" "")
20949         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20950               (match_operand:DI 2 "const_int_operand" "")))]
20951   "TARGET_64BIT"
20952 {
20953   if (SIBLING_CALL_P (insn))
20954     return "jmp\t%P1";
20955   else
20956     return "call\t%P1";
20957 }
20958   [(set_attr "type" "callv")])
20959
20960 (define_insn "*call_value_1"
20961   [(set (match_operand 0 "" "")
20962         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20963               (match_operand:SI 2 "" "")))]
20964   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20965 {
20966   if (constant_call_address_operand (operands[1], Pmode))
20967     return "call\t%P1";
20968   return "call\t%A1";
20969 }
20970   [(set_attr "type" "callv")])
20971
20972 (define_insn "*sibcall_value_1"
20973   [(set (match_operand 0 "" "")
20974         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20975               (match_operand:SI 2 "" "")))]
20976   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20977 {
20978   if (constant_call_address_operand (operands[1], Pmode))
20979     return "jmp\t%P1";
20980   return "jmp\t%A1";
20981 }
20982   [(set_attr "type" "callv")])
20983
20984 (define_insn "*call_value_1_rex64"
20985   [(set (match_operand 0 "" "")
20986         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20987               (match_operand:DI 2 "" "")))]
20988   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20989    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20990 {
20991   if (constant_call_address_operand (operands[1], Pmode))
20992     return "call\t%P1";
20993   return "call\t%A1";
20994 }
20995   [(set_attr "type" "callv")])
20996
20997 (define_insn "*call_value_1_rex64_large"
20998   [(set (match_operand 0 "" "")
20999         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21000               (match_operand:DI 2 "" "")))]
21001   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21002   "call\t%A1"
21003   [(set_attr "type" "callv")])
21004
21005 (define_insn "*sibcall_value_1_rex64"
21006   [(set (match_operand 0 "" "")
21007         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21008               (match_operand:DI 2 "" "")))]
21009   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21010   "jmp\t%P1"
21011   [(set_attr "type" "callv")])
21012
21013 (define_insn "*sibcall_value_1_rex64_v"
21014   [(set (match_operand 0 "" "")
21015         (call (mem:QI (reg:DI R11_REG))
21016               (match_operand:DI 1 "" "")))]
21017   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21018   "jmp\t{*%%}r11"
21019   [(set_attr "type" "callv")])
21020 \f
21021 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21022 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21023 ;; caught for use by garbage collectors and the like.  Using an insn that
21024 ;; maps to SIGILL makes it more likely the program will rightfully die.
21025 ;; Keeping with tradition, "6" is in honor of #UD.
21026 (define_insn "trap"
21027   [(trap_if (const_int 1) (const_int 6))]
21028   ""
21029   { return ASM_SHORT "0x0b0f"; }
21030   [(set_attr "length" "2")])
21031
21032 (define_expand "sse_prologue_save"
21033   [(parallel [(set (match_operand:BLK 0 "" "")
21034                    (unspec:BLK [(reg:DI 21)
21035                                 (reg:DI 22)
21036                                 (reg:DI 23)
21037                                 (reg:DI 24)
21038                                 (reg:DI 25)
21039                                 (reg:DI 26)
21040                                 (reg:DI 27)
21041                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21042               (use (match_operand:DI 1 "register_operand" ""))
21043               (use (match_operand:DI 2 "immediate_operand" ""))
21044               (use (label_ref:DI (match_operand 3 "" "")))])]
21045   "TARGET_64BIT"
21046   "")
21047
21048 (define_insn "*sse_prologue_save_insn"
21049   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21050                           (match_operand:DI 4 "const_int_operand" "n")))
21051         (unspec:BLK [(reg:DI 21)
21052                      (reg:DI 22)
21053                      (reg:DI 23)
21054                      (reg:DI 24)
21055                      (reg:DI 25)
21056                      (reg:DI 26)
21057                      (reg:DI 27)
21058                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21059    (use (match_operand:DI 1 "register_operand" "r"))
21060    (use (match_operand:DI 2 "const_int_operand" "i"))
21061    (use (label_ref:DI (match_operand 3 "" "X")))]
21062   "TARGET_64BIT
21063    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21064    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21065 {
21066   int i;
21067   operands[0] = gen_rtx_MEM (Pmode,
21068                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21069   output_asm_insn ("jmp\t%A1", operands);
21070   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21071     {
21072       operands[4] = adjust_address (operands[0], DImode, i*16);
21073       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21074       PUT_MODE (operands[4], TImode);
21075       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21076         output_asm_insn ("rex", operands);
21077       output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21078     }
21079   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21080                                      CODE_LABEL_NUMBER (operands[3]));
21081   return "";
21082 }
21083   [(set_attr "type" "other")
21084    (set_attr "length_immediate" "0")
21085    (set_attr "length_address" "0")
21086    (set_attr "length" "34")
21087    (set_attr "memory" "store")
21088    (set_attr "modrm" "0")
21089    (set_attr "mode" "DI")])
21090
21091 (define_expand "prefetch"
21092   [(prefetch (match_operand 0 "address_operand" "")
21093              (match_operand:SI 1 "const_int_operand" "")
21094              (match_operand:SI 2 "const_int_operand" ""))]
21095   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21096 {
21097   int rw = INTVAL (operands[1]);
21098   int locality = INTVAL (operands[2]);
21099
21100   gcc_assert (rw == 0 || rw == 1);
21101   gcc_assert (locality >= 0 && locality <= 3);
21102   gcc_assert (GET_MODE (operands[0]) == Pmode
21103               || GET_MODE (operands[0]) == VOIDmode);
21104
21105   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21106      supported by SSE counterpart or the SSE prefetch is not available
21107      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21108      of locality.  */
21109   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21110     operands[2] = GEN_INT (3);
21111   else
21112     operands[1] = const0_rtx;
21113 })
21114
21115 (define_insn "*prefetch_sse"
21116   [(prefetch (match_operand:SI 0 "address_operand" "p")
21117              (const_int 0)
21118              (match_operand:SI 1 "const_int_operand" ""))]
21119   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21120 {
21121   static const char * const patterns[4] = {
21122    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21123   };
21124
21125   int locality = INTVAL (operands[1]);
21126   gcc_assert (locality >= 0 && locality <= 3);
21127
21128   return patterns[locality];
21129 }
21130   [(set_attr "type" "sse")
21131    (set_attr "memory" "none")])
21132
21133 (define_insn "*prefetch_sse_rex"
21134   [(prefetch (match_operand:DI 0 "address_operand" "p")
21135              (const_int 0)
21136              (match_operand:SI 1 "const_int_operand" ""))]
21137   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21138 {
21139   static const char * const patterns[4] = {
21140    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21141   };
21142
21143   int locality = INTVAL (operands[1]);
21144   gcc_assert (locality >= 0 && locality <= 3);
21145
21146   return patterns[locality];
21147 }
21148   [(set_attr "type" "sse")
21149    (set_attr "memory" "none")])
21150
21151 (define_insn "*prefetch_3dnow"
21152   [(prefetch (match_operand:SI 0 "address_operand" "p")
21153              (match_operand:SI 1 "const_int_operand" "n")
21154              (const_int 3))]
21155   "TARGET_3DNOW && !TARGET_64BIT"
21156 {
21157   if (INTVAL (operands[1]) == 0)
21158     return "prefetch\t%a0";
21159   else
21160     return "prefetchw\t%a0";
21161 }
21162   [(set_attr "type" "mmx")
21163    (set_attr "memory" "none")])
21164
21165 (define_insn "*prefetch_3dnow_rex"
21166   [(prefetch (match_operand:DI 0 "address_operand" "p")
21167              (match_operand:SI 1 "const_int_operand" "n")
21168              (const_int 3))]
21169   "TARGET_3DNOW && TARGET_64BIT"
21170 {
21171   if (INTVAL (operands[1]) == 0)
21172     return "prefetch\t%a0";
21173   else
21174     return "prefetchw\t%a0";
21175 }
21176   [(set_attr "type" "mmx")
21177    (set_attr "memory" "none")])
21178
21179 (define_expand "stack_protect_set"
21180   [(match_operand 0 "memory_operand" "")
21181    (match_operand 1 "memory_operand" "")]
21182   ""
21183 {
21184 #ifdef TARGET_THREAD_SSP_OFFSET
21185   if (TARGET_64BIT)
21186     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21187                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21188   else
21189     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21190                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21191 #else
21192   if (TARGET_64BIT)
21193     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21194   else
21195     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21196 #endif
21197   DONE;
21198 })
21199
21200 (define_insn "stack_protect_set_si"
21201   [(set (match_operand:SI 0 "memory_operand" "=m")
21202         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21203    (set (match_scratch:SI 2 "=&r") (const_int 0))
21204    (clobber (reg:CC FLAGS_REG))]
21205   ""
21206   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21207   [(set_attr "type" "multi")])
21208
21209 (define_insn "stack_protect_set_di"
21210   [(set (match_operand:DI 0 "memory_operand" "=m")
21211         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21212    (set (match_scratch:DI 2 "=&r") (const_int 0))
21213    (clobber (reg:CC FLAGS_REG))]
21214   "TARGET_64BIT"
21215   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21216   [(set_attr "type" "multi")])
21217
21218 (define_insn "stack_tls_protect_set_si"
21219   [(set (match_operand:SI 0 "memory_operand" "=m")
21220         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21221    (set (match_scratch:SI 2 "=&r") (const_int 0))
21222    (clobber (reg:CC FLAGS_REG))]
21223   ""
21224   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21225   [(set_attr "type" "multi")])
21226
21227 (define_insn "stack_tls_protect_set_di"
21228   [(set (match_operand:DI 0 "memory_operand" "=m")
21229         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21230    (set (match_scratch:DI 2 "=&r") (const_int 0))
21231    (clobber (reg:CC FLAGS_REG))]
21232   "TARGET_64BIT"
21233   {
21234      /* The kernel uses a different segment register for performance reasons; a
21235         system call would not have to trash the userspace segment register,
21236         which would be expensive */
21237      if (ix86_cmodel != CM_KERNEL)
21238         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21239      else
21240         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21241   }
21242   [(set_attr "type" "multi")])
21243
21244 (define_expand "stack_protect_test"
21245   [(match_operand 0 "memory_operand" "")
21246    (match_operand 1 "memory_operand" "")
21247    (match_operand 2 "" "")]
21248   ""
21249 {
21250   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21251   ix86_compare_op0 = operands[0];
21252   ix86_compare_op1 = operands[1];
21253   ix86_compare_emitted = flags;
21254
21255 #ifdef TARGET_THREAD_SSP_OFFSET
21256   if (TARGET_64BIT)
21257     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21258                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21259   else
21260     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21261                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21262 #else
21263   if (TARGET_64BIT)
21264     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21265   else
21266     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21267 #endif
21268   emit_jump_insn (gen_beq (operands[2]));
21269   DONE;
21270 })
21271
21272 (define_insn "stack_protect_test_si"
21273   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21274         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21275                      (match_operand:SI 2 "memory_operand" "m")]
21276                     UNSPEC_SP_TEST))
21277    (clobber (match_scratch:SI 3 "=&r"))]
21278   ""
21279   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21280   [(set_attr "type" "multi")])
21281
21282 (define_insn "stack_protect_test_di"
21283   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21284         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21285                      (match_operand:DI 2 "memory_operand" "m")]
21286                     UNSPEC_SP_TEST))
21287    (clobber (match_scratch:DI 3 "=&r"))]
21288   "TARGET_64BIT"
21289   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21290   [(set_attr "type" "multi")])
21291
21292 (define_insn "stack_tls_protect_test_si"
21293   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21294         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21295                      (match_operand:SI 2 "const_int_operand" "i")]
21296                     UNSPEC_SP_TLS_TEST))
21297    (clobber (match_scratch:SI 3 "=r"))]
21298   ""
21299   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21300   [(set_attr "type" "multi")])
21301
21302 (define_insn "stack_tls_protect_test_di"
21303   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21304         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21305                      (match_operand:DI 2 "const_int_operand" "i")]
21306                     UNSPEC_SP_TLS_TEST))
21307    (clobber (match_scratch:DI 3 "=r"))]
21308   "TARGET_64BIT"
21309   {
21310      /* The kernel uses a different segment register for performance reasons; a
21311         system call would not have to trash the userspace segment register,
21312         which would be expensive */
21313      if (ix86_cmodel != CM_KERNEL)
21314         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21315      else
21316         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21317   }
21318   [(set_attr "type" "multi")])
21319
21320 (define_mode_iterator CRC32MODE [QI HI SI])
21321 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21322 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21323
21324 (define_insn "sse4_2_crc32<mode>"
21325   [(set (match_operand:SI 0 "register_operand" "=r")
21326         (unspec:SI
21327           [(match_operand:SI 1 "register_operand" "0")
21328            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21329           UNSPEC_CRC32))]
21330   "TARGET_SSE4_2"
21331   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21332   [(set_attr "type" "sselog1")
21333    (set_attr "prefix_rep" "1")
21334    (set_attr "prefix_extra" "1")
21335    (set_attr "mode" "SI")])
21336
21337 (define_insn "sse4_2_crc32di"
21338   [(set (match_operand:DI 0 "register_operand" "=r")
21339         (unspec:DI
21340           [(match_operand:DI 1 "register_operand" "0")
21341            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21342           UNSPEC_CRC32))]
21343   "TARGET_SSE4_2 && TARGET_64BIT"
21344   "crc32q\t{%2, %0|%0, %2}"
21345   [(set_attr "type" "sselog1")
21346    (set_attr "prefix_rep" "1")
21347    (set_attr "prefix_extra" "1")
21348    (set_attr "mode" "DI")])
21349
21350 (include "mmx.md")
21351 (include "sse.md")
21352 (include "sync.md")