OSDN Git Service

* gcc/config/i386/i386.h (TARGET_KEEPS_VECTOR_ALIGNED_STACK): New.
[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
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 2, 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 COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           29)
89
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          30)
92    (UNSPEC_MASKMOV              31)
93    (UNSPEC_MOVMSK               32)
94    (UNSPEC_MOVNT                33)
95    (UNSPEC_MOVU                 34)
96    (UNSPEC_RCP                  35)
97    (UNSPEC_RSQRT                36)
98    (UNSPEC_SFENCE               37)
99    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                39)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
114
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124    (UNSPEC_TAN                  68)
125    (UNSPEC_FXAM                 69)
126
127    ; x87 Rounding
128    (UNSPEC_FRNDINT_FLOOR        70)
129    (UNSPEC_FRNDINT_CEIL         71)
130    (UNSPEC_FRNDINT_TRUNC        72)
131    (UNSPEC_FRNDINT_MASK_PM      73)
132    (UNSPEC_FIST_FLOOR           74)
133    (UNSPEC_FIST_CEIL            75)
134
135    ; x87 Double output FP
136    (UNSPEC_SINCOS_COS           80)
137    (UNSPEC_SINCOS_SIN           81)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
146
147    ; 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
165 (define_constants
166   [(UNSPECV_BLOCKAGE            0)
167    (UNSPECV_STACK_PROBE         1)
168    (UNSPECV_EMMS                2)
169    (UNSPECV_LDMXCSR             3)
170    (UNSPECV_STMXCSR             4)
171    (UNSPECV_FEMMS               5)
172    (UNSPECV_CLFLUSH             6)
173    (UNSPECV_ALIGN               7)
174    (UNSPECV_MONITOR             8)
175    (UNSPECV_MWAIT               9)
176    (UNSPECV_CMPXCHG_1           10)
177    (UNSPECV_CMPXCHG_2           11)
178    (UNSPECV_XCHG                12)
179    (UNSPECV_LOCK                13)
180   ])
181
182 ;; Registers by name.
183 (define_constants
184   [(BP_REG                       6)
185    (SP_REG                       7)
186    (FLAGS_REG                   17)
187    (FPSR_REG                    18)
188    (FPCR_REG                    19)
189    (R10_REG                     39)
190    (R11_REG                     40)
191   ])
192
193 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
194 ;; from i386.c.
195
196 ;; In C guard expressions, put expressions which may be compile-time
197 ;; constants first.  This allows for better optimization.  For
198 ;; example, write "TARGET_64BIT && reload_completed", not
199 ;; "reload_completed && TARGET_64BIT".
200
201 \f
202 ;; Processor type.  This attribute must exactly match the processor_type
203 ;; enumeration in i386.h.
204 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
205                     nocona,core2,generic32,generic64,amdfam10"
206   (const (symbol_ref "ix86_tune")))
207
208 ;; A basic instruction type.  Refinements due to arguments to be
209 ;; provided in other attributes.
210 (define_attr "type"
211   "other,multi,
212    alu,alu1,negnot,imov,imovx,lea,
213    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
214    icmp,test,ibr,setcc,icmov,
215    push,pop,call,callv,leave,
216    str,bitmanip,
217    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
218    sselog,sselog1,sseiadd,sseishft,sseimul,
219    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
220    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
221   (const_string "other"))
222
223 ;; Main data type used by the insn
224 (define_attr "mode"
225   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
226   (const_string "unknown"))
227
228 ;; The CPU unit operations uses.
229 (define_attr "unit" "integer,i387,sse,mmx,unknown"
230   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
231            (const_string "i387")
232          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
233                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
234            (const_string "sse")
235          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
236            (const_string "mmx")
237          (eq_attr "type" "other")
238            (const_string "unknown")]
239          (const_string "integer")))
240
241 ;; The (bounding maximum) length of an instruction immediate.
242 (define_attr "length_immediate" ""
243   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
244                           bitmanip")
245            (const_int 0)
246          (eq_attr "unit" "i387,sse,mmx")
247            (const_int 0)
248          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
249                           imul,icmp,push,pop")
250            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
251          (eq_attr "type" "imov,test")
252            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
253          (eq_attr "type" "call")
254            (if_then_else (match_operand 0 "constant_call_address_operand" "")
255              (const_int 4)
256              (const_int 0))
257          (eq_attr "type" "callv")
258            (if_then_else (match_operand 1 "constant_call_address_operand" "")
259              (const_int 4)
260              (const_int 0))
261          ;; We don't know the size before shorten_branches.  Expect
262          ;; the instruction to fit for better scheduling.
263          (eq_attr "type" "ibr")
264            (const_int 1)
265          ]
266          (symbol_ref "/* Update immediate_length and other attributes! */
267                       gcc_unreachable (),1")))
268
269 ;; The (bounding maximum) length of an instruction address.
270 (define_attr "length_address" ""
271   (cond [(eq_attr "type" "str,other,multi,fxch")
272            (const_int 0)
273          (and (eq_attr "type" "call")
274               (match_operand 0 "constant_call_address_operand" ""))
275              (const_int 0)
276          (and (eq_attr "type" "callv")
277               (match_operand 1 "constant_call_address_operand" ""))
278              (const_int 0)
279          ]
280          (symbol_ref "ix86_attr_length_address_default (insn)")))
281
282 ;; Set when length prefix is used.
283 (define_attr "prefix_data16" ""
284   (if_then_else (ior (eq_attr "mode" "HI")
285                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
286     (const_int 1)
287     (const_int 0)))
288
289 ;; Set when string REP prefix is used.
290 (define_attr "prefix_rep" ""
291   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
292     (const_int 1)
293     (const_int 0)))
294
295 ;; Set when 0f opcode prefix is used.
296 (define_attr "prefix_0f" ""
297   (if_then_else
298     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
299          (eq_attr "unit" "sse,mmx"))
300     (const_int 1)
301     (const_int 0)))
302
303 ;; Set when REX opcode prefix is used.
304 (define_attr "prefix_rex" ""
305   (cond [(and (eq_attr "mode" "DI")
306               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
307            (const_int 1)
308          (and (eq_attr "mode" "QI")
309               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
310                   (const_int 0)))
311            (const_int 1)
312          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
313              (const_int 0))
314            (const_int 1)
315         ]
316         (const_int 0)))
317
318 ;; Set when modrm byte is used.
319 (define_attr "modrm" ""
320   (cond [(eq_attr "type" "str,leave")
321            (const_int 0)
322          (eq_attr "unit" "i387")
323            (const_int 0)
324          (and (eq_attr "type" "incdec")
325               (ior (match_operand:SI 1 "register_operand" "")
326                    (match_operand:HI 1 "register_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "push")
329               (not (match_operand 1 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "pop")
332               (not (match_operand 0 "memory_operand" "")))
333            (const_int 0)
334          (and (eq_attr "type" "imov")
335               (ior (and (match_operand 0 "register_operand" "")
336                         (match_operand 1 "immediate_operand" ""))
337                    (ior (and (match_operand 0 "ax_reg_operand" "")
338                              (match_operand 1 "memory_displacement_only_operand" ""))
339                         (and (match_operand 0 "memory_displacement_only_operand" "")
340                              (match_operand 1 "ax_reg_operand" "")))))
341            (const_int 0)
342          (and (eq_attr "type" "call")
343               (match_operand 0 "constant_call_address_operand" ""))
344              (const_int 0)
345          (and (eq_attr "type" "callv")
346               (match_operand 1 "constant_call_address_operand" ""))
347              (const_int 0)
348          ]
349          (const_int 1)))
350
351 ;; The (bounding maximum) length of an instruction in bytes.
352 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
353 ;; Later we may want to split them and compute proper length as for
354 ;; other insns.
355 (define_attr "length" ""
356   (cond [(eq_attr "type" "other,multi,fistp,frndint")
357            (const_int 16)
358          (eq_attr "type" "fcmp")
359            (const_int 4)
360          (eq_attr "unit" "i387")
361            (plus (const_int 2)
362                  (plus (attr "prefix_data16")
363                        (attr "length_address")))]
364          (plus (plus (attr "modrm")
365                      (plus (attr "prefix_0f")
366                            (plus (attr "prefix_rex")
367                                  (const_int 1))))
368                (plus (attr "prefix_rep")
369                      (plus (attr "prefix_data16")
370                            (plus (attr "length_immediate")
371                                  (attr "length_address")))))))
372
373 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
374 ;; `store' if there is a simple memory reference therein, or `unknown'
375 ;; if the instruction is complex.
376
377 (define_attr "memory" "none,load,store,both,unknown"
378   (cond [(eq_attr "type" "other,multi,str")
379            (const_string "unknown")
380          (eq_attr "type" "lea,fcmov,fpspc")
381            (const_string "none")
382          (eq_attr "type" "fistp,leave")
383            (const_string "both")
384          (eq_attr "type" "frndint")
385            (const_string "load")
386          (eq_attr "type" "push")
387            (if_then_else (match_operand 1 "memory_operand" "")
388              (const_string "both")
389              (const_string "store"))
390          (eq_attr "type" "pop")
391            (if_then_else (match_operand 0 "memory_operand" "")
392              (const_string "both")
393              (const_string "load"))
394          (eq_attr "type" "setcc")
395            (if_then_else (match_operand 0 "memory_operand" "")
396              (const_string "store")
397              (const_string "none"))
398          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
399            (if_then_else (ior (match_operand 0 "memory_operand" "")
400                               (match_operand 1 "memory_operand" ""))
401              (const_string "load")
402              (const_string "none"))
403          (eq_attr "type" "ibr")
404            (if_then_else (match_operand 0 "memory_operand" "")
405              (const_string "load")
406              (const_string "none"))
407          (eq_attr "type" "call")
408            (if_then_else (match_operand 0 "constant_call_address_operand" "")
409              (const_string "none")
410              (const_string "load"))
411          (eq_attr "type" "callv")
412            (if_then_else (match_operand 1 "constant_call_address_operand" "")
413              (const_string "none")
414              (const_string "load"))
415          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (and (match_operand 0 "memory_operand" "")
419               (match_operand 1 "memory_operand" ""))
420            (const_string "both")
421          (match_operand 0 "memory_operand" "")
422            (const_string "store")
423          (match_operand 1 "memory_operand" "")
424            (const_string "load")
425          (and (eq_attr "type"
426                  "!alu1,negnot,ishift1,
427                    imov,imovx,icmp,test,bitmanip,
428                    fmov,fcmp,fsgn,
429                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
430                    mmx,mmxmov,mmxcmp,mmxcvt")
431               (match_operand 2 "memory_operand" ""))
432            (const_string "load")
433          (and (eq_attr "type" "icmov")
434               (match_operand 3 "memory_operand" ""))
435            (const_string "load")
436         ]
437         (const_string "none")))
438
439 ;; Indicates if an instruction has both an immediate and a displacement.
440
441 (define_attr "imm_disp" "false,true,unknown"
442   (cond [(eq_attr "type" "other,multi")
443            (const_string "unknown")
444          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
445               (and (match_operand 0 "memory_displacement_operand" "")
446                    (match_operand 1 "immediate_operand" "")))
447            (const_string "true")
448          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
449               (and (match_operand 0 "memory_displacement_operand" "")
450                    (match_operand 2 "immediate_operand" "")))
451            (const_string "true")
452         ]
453         (const_string "false")))
454
455 ;; Indicates if an FP operation has an integer source.
456
457 (define_attr "fp_int_src" "false,true"
458   (const_string "false"))
459
460 ;; Defines rounding mode of an FP operation.
461
462 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
463   (const_string "any"))
464
465 ;; Describe a user's asm statement.
466 (define_asm_attributes
467   [(set_attr "length" "128")
468    (set_attr "type" "multi")])
469
470 ;; All x87 floating point modes
471 (define_mode_macro X87MODEF [SF DF XF])
472
473 ;; x87 SFmode and DFMode floating point modes
474 (define_mode_macro X87MODEF12 [SF DF])
475
476 ;; All integer modes handled by x87 fisttp operator.
477 (define_mode_macro X87MODEI [HI SI DI])
478
479 ;; All integer modes handled by integer x87 operators.
480 (define_mode_macro X87MODEI12 [HI SI])
481
482 ;; All SSE floating point modes
483 (define_mode_macro SSEMODEF [SF DF])
484
485 ;; All integer modes handled by SSE cvtts?2si* operators.
486 (define_mode_macro SSEMODEI24 [SI DI])
487
488 ;; SSE asm suffix for floating point modes
489 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
490
491 \f
492 ;; Scheduling descriptions
493
494 (include "pentium.md")
495 (include "ppro.md")
496 (include "k6.md")
497 (include "athlon.md")
498 (include "geode.md")
499
500 \f
501 ;; Operand and operator predicates and constraints
502
503 (include "predicates.md")
504 (include "constraints.md")
505
506 \f
507 ;; Compare instructions.
508
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
512
513 (define_expand "cmpti"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516                     (match_operand:TI 1 "x86_64_general_operand" "")))]
517   "TARGET_64BIT"
518 {
519   if (MEM_P (operands[0]) && MEM_P (operands[1]))
520     operands[0] = force_reg (TImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmpdi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529                     (match_operand:DI 1 "x86_64_general_operand" "")))]
530   ""
531 {
532   if (MEM_P (operands[0]) && MEM_P (operands[1]))
533     operands[0] = force_reg (DImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpsi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542                     (match_operand:SI 1 "general_operand" "")))]
543   ""
544 {
545   if (MEM_P (operands[0]) && MEM_P (operands[1]))
546     operands[0] = force_reg (SImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_expand "cmphi"
553   [(set (reg:CC FLAGS_REG)
554         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555                     (match_operand:HI 1 "general_operand" "")))]
556   ""
557 {
558   if (MEM_P (operands[0]) && MEM_P (operands[1]))
559     operands[0] = force_reg (HImode, operands[0]);
560   ix86_compare_op0 = operands[0];
561   ix86_compare_op1 = operands[1];
562   DONE;
563 })
564
565 (define_expand "cmpqi"
566   [(set (reg:CC FLAGS_REG)
567         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568                     (match_operand:QI 1 "general_operand" "")))]
569   "TARGET_QIMODE_MATH"
570 {
571   if (MEM_P (operands[0]) && MEM_P (operands[1]))
572     operands[0] = force_reg (QImode, operands[0]);
573   ix86_compare_op0 = operands[0];
574   ix86_compare_op1 = operands[1];
575   DONE;
576 })
577
578 (define_insn "cmpdi_ccno_1_rex64"
579   [(set (reg FLAGS_REG)
580         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581                  (match_operand:DI 1 "const0_operand" "n,n")))]
582   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
583   "@
584    test{q}\t{%0, %0|%0, %0}
585    cmp{q}\t{%1, %0|%0, %1}"
586   [(set_attr "type" "test,icmp")
587    (set_attr "length_immediate" "0,1")
588    (set_attr "mode" "DI")])
589
590 (define_insn "*cmpdi_minus_1_rex64"
591   [(set (reg FLAGS_REG)
592         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
594                  (const_int 0)))]
595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596   "cmp{q}\t{%1, %0|%0, %1}"
597   [(set_attr "type" "icmp")
598    (set_attr "mode" "DI")])
599
600 (define_expand "cmpdi_1_rex64"
601   [(set (reg:CC FLAGS_REG)
602         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603                     (match_operand:DI 1 "general_operand" "")))]
604   "TARGET_64BIT"
605   "")
606
607 (define_insn "cmpdi_1_insn_rex64"
608   [(set (reg FLAGS_REG)
609         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612   "cmp{q}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "DI")])
615
616
617 (define_insn "*cmpsi_ccno_1"
618   [(set (reg FLAGS_REG)
619         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620                  (match_operand:SI 1 "const0_operand" "n,n")))]
621   "ix86_match_ccmode (insn, CCNOmode)"
622   "@
623    test{l}\t{%0, %0|%0, %0}
624    cmp{l}\t{%1, %0|%0, %1}"
625   [(set_attr "type" "test,icmp")
626    (set_attr "length_immediate" "0,1")
627    (set_attr "mode" "SI")])
628
629 (define_insn "*cmpsi_minus_1"
630   [(set (reg FLAGS_REG)
631         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632                            (match_operand:SI 1 "general_operand" "ri,mr"))
633                  (const_int 0)))]
634   "ix86_match_ccmode (insn, CCGOCmode)"
635   "cmp{l}\t{%1, %0|%0, %1}"
636   [(set_attr "type" "icmp")
637    (set_attr "mode" "SI")])
638
639 (define_expand "cmpsi_1"
640   [(set (reg:CC FLAGS_REG)
641         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642                     (match_operand:SI 1 "general_operand" "ri,mr")))]
643   ""
644   "")
645
646 (define_insn "*cmpsi_1_insn"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:SI 1 "general_operand" "ri,mr")))]
650   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651     && ix86_match_ccmode (insn, CCmode)"
652   "cmp{l}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "SI")])
655
656 (define_insn "*cmphi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659                  (match_operand:HI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{w}\t{%0, %0|%0, %0}
663    cmp{w}\t{%1, %0|%0, %1}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "HI")])
667
668 (define_insn "*cmphi_minus_1"
669   [(set (reg FLAGS_REG)
670         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671                            (match_operand:HI 1 "general_operand" "ri,mr"))
672                  (const_int 0)))]
673   "ix86_match_ccmode (insn, CCGOCmode)"
674   "cmp{w}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "HI")])
677
678 (define_insn "*cmphi_1"
679   [(set (reg FLAGS_REG)
680         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681                  (match_operand:HI 1 "general_operand" "ri,mr")))]
682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683    && ix86_match_ccmode (insn, CCmode)"
684   "cmp{w}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "HI")])
687
688 (define_insn "*cmpqi_ccno_1"
689   [(set (reg FLAGS_REG)
690         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691                  (match_operand:QI 1 "const0_operand" "n,n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "@
694    test{b}\t{%0, %0|%0, %0}
695    cmp{b}\t{$0, %0|%0, 0}"
696   [(set_attr "type" "test,icmp")
697    (set_attr "length_immediate" "0,1")
698    (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_1"
701   [(set (reg FLAGS_REG)
702         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703                  (match_operand:QI 1 "general_operand" "qi,mq")))]
704   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705     && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_minus_1"
711   [(set (reg FLAGS_REG)
712         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713                            (match_operand:QI 1 "general_operand" "qi,mq"))
714                  (const_int 0)))]
715   "ix86_match_ccmode (insn, CCGOCmode)"
716   "cmp{b}\t{%1, %0|%0, %1}"
717   [(set_attr "type" "icmp")
718    (set_attr "mode" "QI")])
719
720 (define_insn "*cmpqi_ext_1"
721   [(set (reg FLAGS_REG)
722         (compare
723           (match_operand:QI 0 "general_operand" "Qm")
724           (subreg:QI
725             (zero_extract:SI
726               (match_operand 1 "ext_register_operand" "Q")
727               (const_int 8)
728               (const_int 8)) 0)))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%h1, %0|%0, %h1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_ext_1_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (match_operand:QI 0 "register_operand" "Q")
738           (subreg:QI
739             (zero_extract:SI
740               (match_operand 1 "ext_register_operand" "Q")
741               (const_int 8)
742               (const_int 8)) 0)))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%h1, %0|%0, %h1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_2"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "const0_operand" "n")))]
757   "ix86_match_ccmode (insn, CCNOmode)"
758   "test{b}\t%h0, %h0"
759   [(set_attr "type" "test")
760    (set_attr "length_immediate" "0")
761    (set_attr "mode" "QI")])
762
763 (define_expand "cmpqi_ext_3"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "general_operand" "")))]
772   ""
773   "")
774
775 (define_insn "cmpqi_ext_3_insn"
776   [(set (reg FLAGS_REG)
777         (compare
778           (subreg:QI
779             (zero_extract:SI
780               (match_operand 0 "ext_register_operand" "Q")
781               (const_int 8)
782               (const_int 8)) 0)
783           (match_operand:QI 1 "general_operand" "Qmn")))]
784   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%1, %h0|%h0, %1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 (define_insn "cmpqi_ext_3_insn_rex64"
790   [(set (reg FLAGS_REG)
791         (compare
792           (subreg:QI
793             (zero_extract:SI
794               (match_operand 0 "ext_register_operand" "Q")
795               (const_int 8)
796               (const_int 8)) 0)
797           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799   "cmp{b}\t{%1, %h0|%h0, %1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "QI")])
802
803 (define_insn "*cmpqi_ext_4"
804   [(set (reg FLAGS_REG)
805         (compare
806           (subreg:QI
807             (zero_extract:SI
808               (match_operand 0 "ext_register_operand" "Q")
809               (const_int 8)
810               (const_int 8)) 0)
811           (subreg:QI
812             (zero_extract:SI
813               (match_operand 1 "ext_register_operand" "Q")
814               (const_int 8)
815               (const_int 8)) 0)))]
816   "ix86_match_ccmode (insn, CCmode)"
817   "cmp{b}\t{%h1, %h0|%h0, %h1}"
818   [(set_attr "type" "icmp")
819    (set_attr "mode" "QI")])
820
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares.  Which is what
824 ;; the old patterns did, but with many more of them.
825
826 (define_expand "cmpxf"
827   [(set (reg:CC FLAGS_REG)
828         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829                     (match_operand:XF 1 "nonmemory_operand" "")))]
830   "TARGET_80387"
831 {
832   ix86_compare_op0 = operands[0];
833   ix86_compare_op1 = operands[1];
834   DONE;
835 })
836
837 (define_expand "cmpdf"
838   [(set (reg:CC FLAGS_REG)
839         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
842 {
843   ix86_compare_op0 = operands[0];
844   ix86_compare_op1 = operands[1];
845   DONE;
846 })
847
848 (define_expand "cmpsf"
849   [(set (reg:CC FLAGS_REG)
850         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852   "TARGET_80387 || TARGET_SSE_MATH"
853 {
854   ix86_compare_op0 = operands[0];
855   ix86_compare_op1 = operands[1];
856   DONE;
857 })
858
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
861 ;;
862 ;; CCFPmode     compare with exceptions
863 ;; CCFPUmode    compare with no exceptions
864
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
867
868 (define_insn "*cmpfp_0"
869   [(set (match_operand:HI 0 "register_operand" "=a")
870         (unspec:HI
871           [(compare:CCFP
872              (match_operand 1 "register_operand" "f")
873              (match_operand 2 "const0_operand" "X"))]
874         UNSPEC_FNSTSW))]
875   "TARGET_80387
876    && FLOAT_MODE_P (GET_MODE (operands[1]))
877    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set (attr "mode")
882      (cond [(match_operand:SF 1 "" "")
883               (const_string "SF")
884             (match_operand:DF 1 "" "")
885               (const_string "DF")
886            ]
887            (const_string "XF")))])
888
889 (define_insn "*cmpfp_sf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:SF 1 "register_operand" "f")
894              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "SF")])
901
902 (define_insn "*cmpfp_df"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFP
906              (match_operand:DF 1 "register_operand" "f")
907              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387"
910   "* return output_fp_compare (insn, operands, 0, 0);"
911   [(set_attr "type" "multi")
912    (set_attr "unit" "i387")
913    (set_attr "mode" "DF")])
914
915 (define_insn "*cmpfp_xf"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand:XF 1 "register_operand" "f")
920              (match_operand:XF 2 "register_operand" "f"))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387"
923   "* return output_fp_compare (insn, operands, 0, 0);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set_attr "mode" "XF")])
927
928 (define_insn "*cmpfp_u"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFPU
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "register_operand" "f"))]
934           UNSPEC_FNSTSW))]
935   "TARGET_80387
936    && FLOAT_MODE_P (GET_MODE (operands[1]))
937    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938   "* return output_fp_compare (insn, operands, 0, 1);"
939   [(set_attr "type" "multi")
940    (set_attr "unit" "i387")
941    (set (attr "mode")
942      (cond [(match_operand:SF 1 "" "")
943               (const_string "SF")
944             (match_operand:DF 1 "" "")
945               (const_string "DF")
946            ]
947            (const_string "XF")))])
948
949 (define_insn "*cmpfp_<mode>"
950   [(set (match_operand:HI 0 "register_operand" "=a")
951         (unspec:HI
952           [(compare:CCFP
953              (match_operand 1 "register_operand" "f")
954              (match_operator 3 "float_operator"
955                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956           UNSPEC_FNSTSW))]
957   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958    && FLOAT_MODE_P (GET_MODE (operands[1]))
959    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960   "* return output_fp_compare (insn, operands, 0, 0);"
961   [(set_attr "type" "multi")
962    (set_attr "unit" "i387")
963    (set_attr "fp_int_src" "true")
964    (set_attr "mode" "<MODE>")])
965
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
968
969 (define_insn "x86_fnstsw_1"
970   [(set (match_operand:HI 0 "register_operand" "=a")
971         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972   "TARGET_80387"
973   "fnstsw\t%0"
974   [(set_attr "length" "2")
975    (set_attr "mode" "SI")
976    (set_attr "unit" "i387")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982   [(set (reg:CC FLAGS_REG)
983         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984   "!TARGET_64BIT"
985   "sahf"
986   [(set_attr "length" "1")
987    (set_attr "athlon_decode" "vector")
988    (set_attr "amdfam10_decode" "direct")
989    (set_attr "mode" "SI")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
993 (define_insn "*cmpfp_i_mixed"
994   [(set (reg:CCFP FLAGS_REG)
995         (compare:CCFP (match_operand 0 "register_operand" "f,x")
996                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
997   "TARGET_MIX_SSE_I387
998    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp,ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")
1007    (set_attr "amdfam10_decode" "direct")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010   [(set (reg:CCFP FLAGS_REG)
1011         (compare:CCFP (match_operand 0 "register_operand" "x")
1012                       (match_operand 1 "nonimmediate_operand" "xm")))]
1013   "TARGET_SSE_MATH
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 0);"
1017   [(set_attr "type" "ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")
1023    (set_attr "amdfam10_decode" "direct")])
1024
1025 (define_insn "*cmpfp_i_i387"
1026   [(set (reg:CCFP FLAGS_REG)
1027         (compare:CCFP (match_operand 0 "register_operand" "f")
1028                       (match_operand 1 "register_operand" "f")))]
1029   "TARGET_80387 && TARGET_CMOVE
1030    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031    && FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 0);"
1034   [(set_attr "type" "fcmp")
1035    (set (attr "mode")
1036      (cond [(match_operand:SF 1 "" "")
1037               (const_string "SF")
1038             (match_operand:DF 1 "" "")
1039               (const_string "DF")
1040            ]
1041            (const_string "XF")))
1042    (set_attr "athlon_decode" "vector")
1043    (set_attr "amdfam10_decode" "direct")])
1044
1045 (define_insn "*cmpfp_iu_mixed"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049   "TARGET_MIX_SSE_I387
1050    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052   "* return output_fp_compare (insn, operands, 1, 1);"
1053   [(set_attr "type" "fcmp,ssecomi")
1054    (set (attr "mode")
1055      (if_then_else (match_operand:SF 1 "" "")
1056         (const_string "SF")
1057         (const_string "DF")))
1058    (set_attr "athlon_decode" "vector")
1059    (set_attr "amdfam10_decode" "direct")])
1060
1061 (define_insn "*cmpfp_iu_sse"
1062   [(set (reg:CCFPU FLAGS_REG)
1063         (compare:CCFPU (match_operand 0 "register_operand" "x")
1064                        (match_operand 1 "nonimmediate_operand" "xm")))]
1065   "TARGET_SSE_MATH
1066    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068   "* return output_fp_compare (insn, operands, 1, 1);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")
1075    (set_attr "amdfam10_decode" "direct")])
1076
1077 (define_insn "*cmpfp_iu_387"
1078   [(set (reg:CCFPU FLAGS_REG)
1079         (compare:CCFPU (match_operand 0 "register_operand" "f")
1080                        (match_operand 1 "register_operand" "f")))]
1081   "TARGET_80387 && TARGET_CMOVE
1082    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083    && FLOAT_MODE_P (GET_MODE (operands[0]))
1084    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085   "* return output_fp_compare (insn, operands, 1, 1);"
1086   [(set_attr "type" "fcmp")
1087    (set (attr "mode")
1088      (cond [(match_operand:SF 1 "" "")
1089               (const_string "SF")
1090             (match_operand:DF 1 "" "")
1091               (const_string "DF")
1092            ]
1093            (const_string "XF")))
1094    (set_attr "athlon_decode" "vector")
1095    (set_attr "amdfam10_decode" "direct")])
1096 \f
1097 ;; Move instructions.
1098
1099 ;; General case of fullword move.
1100
1101 (define_expand "movsi"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103         (match_operand:SI 1 "general_operand" ""))]
1104   ""
1105   "ix86_expand_move (SImode, operands); DONE;")
1106
1107 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1108 ;; general_operand.
1109 ;;
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1115
1116 (define_insn "*pushsi2"
1117   [(set (match_operand:SI 0 "push_operand" "=<")
1118         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126   [(set (match_operand:SI 0 "push_operand" "=X")
1127         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1128   "TARGET_64BIT"
1129   "push{q}\t%q1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*pushsi2_prologue"
1134   [(set (match_operand:SI 0 "push_operand" "=<")
1135         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136    (clobber (mem:BLK (scratch)))]
1137   "!TARGET_64BIT"
1138   "push{l}\t%1"
1139   [(set_attr "type" "push")
1140    (set_attr "mode" "SI")])
1141
1142 (define_insn "*popsi1_epilogue"
1143   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144         (mem:SI (reg:SI SP_REG)))
1145    (set (reg:SI SP_REG)
1146         (plus:SI (reg:SI SP_REG) (const_int 4)))
1147    (clobber (mem:BLK (scratch)))]
1148   "!TARGET_64BIT"
1149   "pop{l}\t%0"
1150   [(set_attr "type" "pop")
1151    (set_attr "mode" "SI")])
1152
1153 (define_insn "popsi1"
1154   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155         (mem:SI (reg:SI SP_REG)))
1156    (set (reg:SI SP_REG)
1157         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1158   "!TARGET_64BIT"
1159   "pop{l}\t%0"
1160   [(set_attr "type" "pop")
1161    (set_attr "mode" "SI")])
1162
1163 (define_insn "*movsi_xor"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (match_operand:SI 1 "const0_operand" "i"))
1166    (clobber (reg:CC FLAGS_REG))]
1167   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168   "xor{l}\t{%0, %0|%0, %0}"
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "0")])
1172
1173 (define_insn "*movsi_or"
1174   [(set (match_operand:SI 0 "register_operand" "=r")
1175         (match_operand:SI 1 "immediate_operand" "i"))
1176    (clobber (reg:CC FLAGS_REG))]
1177   "reload_completed
1178    && operands[1] == constm1_rtx
1179    && (TARGET_PENTIUM || optimize_size)"
1180 {
1181   operands[1] = constm1_rtx;
1182   return "or{l}\t{%1, %0|%0, %1}";
1183 }
1184   [(set_attr "type" "alu1")
1185    (set_attr "mode" "SI")
1186    (set_attr "length_immediate" "1")])
1187
1188 (define_insn "*movsi_1"
1189   [(set (match_operand:SI 0 "nonimmediate_operand"
1190                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191         (match_operand:SI 1 "general_operand"
1192                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1193   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1194 {
1195   switch (get_attr_type (insn))
1196     {
1197     case TYPE_SSELOG1:
1198       if (get_attr_mode (insn) == MODE_TI)
1199         return "pxor\t%0, %0";
1200       return "xorps\t%0, %0";
1201
1202     case TYPE_SSEMOV:
1203       switch (get_attr_mode (insn))
1204         {
1205         case MODE_TI:
1206           return "movdqa\t{%1, %0|%0, %1}";
1207         case MODE_V4SF:
1208           return "movaps\t{%1, %0|%0, %1}";
1209         case MODE_SI:
1210           return "movd\t{%1, %0|%0, %1}";
1211         case MODE_SF:
1212           return "movss\t{%1, %0|%0, %1}";
1213         default:
1214           gcc_unreachable ();
1215         }
1216
1217     case TYPE_MMXADD:
1218       return "pxor\t%0, %0";
1219
1220     case TYPE_MMXMOV:
1221       if (get_attr_mode (insn) == MODE_DI)
1222         return "movq\t{%1, %0|%0, %1}";
1223       return "movd\t{%1, %0|%0, %1}";
1224
1225     case TYPE_LEA:
1226       return "lea{l}\t{%1, %0|%0, %1}";
1227
1228     default:
1229       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230       return "mov{l}\t{%1, %0|%0, %1}";
1231     }
1232 }
1233   [(set (attr "type")
1234      (cond [(eq_attr "alternative" "2")
1235               (const_string "mmxadd")
1236             (eq_attr "alternative" "3,4,5")
1237               (const_string "mmxmov")
1238             (eq_attr "alternative" "6")
1239               (const_string "sselog1")
1240             (eq_attr "alternative" "7,8,9,10,11")
1241               (const_string "ssemov")
1242             (match_operand:DI 1 "pic_32bit_operand" "")
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set (attr "mode")
1247      (cond [(eq_attr "alternative" "2,3")
1248               (const_string "DI")
1249             (eq_attr "alternative" "6,7")
1250               (if_then_else
1251                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252                 (const_string "V4SF")
1253                 (const_string "TI"))
1254             (and (eq_attr "alternative" "8,9,10,11")
1255                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1256               (const_string "SF")
1257            ]
1258            (const_string "SI")))])
1259
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1267   "@
1268    movabs{l}\t{%1, %P0|%P0, %1}
1269    mov{l}\t{%1, %a0|%a0, %1}"
1270   [(set_attr "type" "imov")
1271    (set_attr "modrm" "0,*")
1272    (set_attr "length_address" "8,0")
1273    (set_attr "length_immediate" "0,*")
1274    (set_attr "memory" "store")
1275    (set_attr "mode" "SI")])
1276
1277 (define_insn "*movabssi_2_rex64"
1278   [(set (match_operand:SI 0 "register_operand" "=a,r")
1279         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1281   "@
1282    movabs{l}\t{%P1, %0|%0, %P1}
1283    mov{l}\t{%a1, %0|%0, %a1}"
1284   [(set_attr "type" "imov")
1285    (set_attr "modrm" "0,*")
1286    (set_attr "length_address" "8,0")
1287    (set_attr "length_immediate" "0")
1288    (set_attr "memory" "load")
1289    (set_attr "mode" "SI")])
1290
1291 (define_insn "*swapsi"
1292   [(set (match_operand:SI 0 "register_operand" "+r")
1293         (match_operand:SI 1 "register_operand" "+r"))
1294    (set (match_dup 1)
1295         (match_dup 0))]
1296   ""
1297   "xchg{l}\t%1, %0"
1298   [(set_attr "type" "imov")
1299    (set_attr "mode" "SI")
1300    (set_attr "pent_pair" "np")
1301    (set_attr "athlon_decode" "vector")
1302    (set_attr "amdfam10_decode" "double")])   
1303
1304 (define_expand "movhi"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306         (match_operand:HI 1 "general_operand" ""))]
1307   ""
1308   "ix86_expand_move (HImode, operands); DONE;")
1309
1310 (define_insn "*pushhi2"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1313   "!TARGET_64BIT"
1314   "push{l}\t%k1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "SI")])
1317
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320   [(set (match_operand:HI 0 "push_operand" "=X")
1321         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1322   "TARGET_64BIT"
1323   "push{q}\t%q1"
1324   [(set_attr "type" "push")
1325    (set_attr "mode" "DI")])
1326
1327 (define_insn "*movhi_1"
1328   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1331 {
1332   switch (get_attr_type (insn))
1333     {
1334     case TYPE_IMOVX:
1335       /* movzwl is faster than movw on p2 due to partial word stalls,
1336          though not as fast as an aligned movl.  */
1337       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1338     default:
1339       if (get_attr_mode (insn) == MODE_SI)
1340         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1341       else
1342         return "mov{w}\t{%1, %0|%0, %1}";
1343     }
1344 }
1345   [(set (attr "type")
1346      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347               (const_string "imov")
1348             (and (eq_attr "alternative" "0")
1349                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350                           (const_int 0))
1351                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1352                           (const_int 0))))
1353               (const_string "imov")
1354             (and (eq_attr "alternative" "1,2")
1355                  (match_operand:HI 1 "aligned_operand" ""))
1356               (const_string "imov")
1357             (and (ne (symbol_ref "TARGET_MOVX")
1358                      (const_int 0))
1359                  (eq_attr "alternative" "0,2"))
1360               (const_string "imovx")
1361            ]
1362            (const_string "imov")))
1363     (set (attr "mode")
1364       (cond [(eq_attr "type" "imovx")
1365                (const_string "SI")
1366              (and (eq_attr "alternative" "1,2")
1367                   (match_operand:HI 1 "aligned_operand" ""))
1368                (const_string "SI")
1369              (and (eq_attr "alternative" "0")
1370                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1371                            (const_int 0))
1372                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1373                            (const_int 0))))
1374                (const_string "SI")
1375             ]
1376             (const_string "HI")))])
1377
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1385   "@
1386    movabs{w}\t{%1, %P0|%P0, %1}
1387    mov{w}\t{%1, %a0|%a0, %1}"
1388   [(set_attr "type" "imov")
1389    (set_attr "modrm" "0,*")
1390    (set_attr "length_address" "8,0")
1391    (set_attr "length_immediate" "0,*")
1392    (set_attr "memory" "store")
1393    (set_attr "mode" "HI")])
1394
1395 (define_insn "*movabshi_2_rex64"
1396   [(set (match_operand:HI 0 "register_operand" "=a,r")
1397         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1399   "@
1400    movabs{w}\t{%P1, %0|%0, %P1}
1401    mov{w}\t{%a1, %0|%0, %a1}"
1402   [(set_attr "type" "imov")
1403    (set_attr "modrm" "0,*")
1404    (set_attr "length_address" "8,0")
1405    (set_attr "length_immediate" "0")
1406    (set_attr "memory" "load")
1407    (set_attr "mode" "HI")])
1408
1409 (define_insn "*swaphi_1"
1410   [(set (match_operand:HI 0 "register_operand" "+r")
1411         (match_operand:HI 1 "register_operand" "+r"))
1412    (set (match_dup 1)
1413         (match_dup 0))]
1414   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1415   "xchg{l}\t%k1, %k0"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "SI")
1418    (set_attr "pent_pair" "np")
1419    (set_attr "athlon_decode" "vector")
1420    (set_attr "amdfam10_decode" "double")])   
1421
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424   [(set (match_operand:HI 0 "register_operand" "+r")
1425         (match_operand:HI 1 "register_operand" "+r"))
1426    (set (match_dup 1)
1427         (match_dup 0))]
1428   "TARGET_PARTIAL_REG_STALL"
1429   "xchg{w}\t%1, %0"
1430   [(set_attr "type" "imov")
1431    (set_attr "mode" "HI")
1432    (set_attr "pent_pair" "np")
1433    (set_attr "athlon_decode" "vector")])
1434
1435 (define_expand "movstricthi"
1436   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437         (match_operand:HI 1 "general_operand" ""))]
1438   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1439 {
1440   /* Don't generate memory->memory moves, go through a register */
1441   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442     operands[1] = force_reg (HImode, operands[1]);
1443 })
1444
1445 (define_insn "*movstricthi_1"
1446   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447         (match_operand:HI 1 "general_operand" "rn,m"))]
1448   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450   "mov{w}\t{%1, %0|%0, %1}"
1451   [(set_attr "type" "imov")
1452    (set_attr "mode" "HI")])
1453
1454 (define_insn "*movstricthi_xor"
1455   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456         (match_operand:HI 1 "const0_operand" "i"))
1457    (clobber (reg:CC FLAGS_REG))]
1458   "reload_completed
1459    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460   "xor{w}\t{%0, %0|%0, %0}"
1461   [(set_attr "type" "alu1")
1462    (set_attr "mode" "HI")
1463    (set_attr "length_immediate" "0")])
1464
1465 (define_expand "movqi"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467         (match_operand:QI 1 "general_operand" ""))]
1468   ""
1469   "ix86_expand_move (QImode, operands); DONE;")
1470
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte".  But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1474
1475 (define_insn "*pushqi2"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%k1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485   [(set (match_operand:QI 0 "push_operand" "=X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487   "TARGET_64BIT"
1488   "push{q}\t%q1"
1489   [(set_attr "type" "push")
1490    (set_attr "mode" "DI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there.  Then we use movzx.
1502 (define_insn "*movqi_1"
1503   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1505   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1506 {
1507   switch (get_attr_type (insn))
1508     {
1509     case TYPE_IMOVX:
1510       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1512     default:
1513       if (get_attr_mode (insn) == MODE_SI)
1514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1515       else
1516         return "mov{b}\t{%1, %0|%0, %1}";
1517     }
1518 }
1519   [(set (attr "type")
1520      (cond [(and (eq_attr "alternative" "5")
1521                  (not (match_operand:QI 1 "aligned_operand" "")))
1522               (const_string "imovx")
1523             (ne (symbol_ref "optimize_size") (const_int 0))
1524               (const_string "imov")
1525             (and (eq_attr "alternative" "3")
1526                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527                           (const_int 0))
1528                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1529                           (const_int 0))))
1530               (const_string "imov")
1531             (eq_attr "alternative" "3,5")
1532               (const_string "imovx")
1533             (and (ne (symbol_ref "TARGET_MOVX")
1534                      (const_int 0))
1535                  (eq_attr "alternative" "2"))
1536               (const_string "imovx")
1537            ]
1538            (const_string "imov")))
1539    (set (attr "mode")
1540       (cond [(eq_attr "alternative" "3,4,5")
1541                (const_string "SI")
1542              (eq_attr "alternative" "6")
1543                (const_string "QI")
1544              (eq_attr "type" "imovx")
1545                (const_string "SI")
1546              (and (eq_attr "type" "imov")
1547                   (and (eq_attr "alternative" "0,1")
1548                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1549                                 (const_int 0))
1550                             (and (eq (symbol_ref "optimize_size")
1551                                      (const_int 0))
1552                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                                      (const_int 0))))))
1554                (const_string "SI")
1555              ;; Avoid partial register stalls when not using QImode arithmetic
1556              (and (eq_attr "type" "imov")
1557                   (and (eq_attr "alternative" "0,1")
1558                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                                 (const_int 0))
1560                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1561                                 (const_int 0)))))
1562                (const_string "SI")
1563            ]
1564            (const_string "QI")))])
1565
1566 (define_expand "reload_outqi"
1567   [(parallel [(match_operand:QI 0 "" "=m")
1568               (match_operand:QI 1 "register_operand" "r")
1569               (match_operand:QI 2 "register_operand" "=&q")])]
1570   ""
1571 {
1572   rtx op0, op1, op2;
1573   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1574
1575   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576   if (! q_regs_operand (op1, QImode))
1577     {
1578       emit_insn (gen_movqi (op2, op1));
1579       op1 = op2;
1580     }
1581   emit_insn (gen_movqi (op0, op1));
1582   DONE;
1583 })
1584
1585 (define_insn "*swapqi_1"
1586   [(set (match_operand:QI 0 "register_operand" "+r")
1587         (match_operand:QI 1 "register_operand" "+r"))
1588    (set (match_dup 1)
1589         (match_dup 0))]
1590   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1591   "xchg{l}\t%k1, %k0"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "SI")
1594    (set_attr "pent_pair" "np")
1595    (set_attr "athlon_decode" "vector")
1596    (set_attr "amdfam10_decode" "vector")])   
1597
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600   [(set (match_operand:QI 0 "register_operand" "+q")
1601         (match_operand:QI 1 "register_operand" "+q"))
1602    (set (match_dup 1)
1603         (match_dup 0))]
1604   "TARGET_PARTIAL_REG_STALL"
1605   "xchg{b}\t%1, %0"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")
1608    (set_attr "pent_pair" "np")
1609    (set_attr "athlon_decode" "vector")])
1610
1611 (define_expand "movstrictqi"
1612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613         (match_operand:QI 1 "general_operand" ""))]
1614   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1615 {
1616   /* Don't generate memory->memory moves, go through a register.  */
1617   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618     operands[1] = force_reg (QImode, operands[1]);
1619 })
1620
1621 (define_insn "*movstrictqi_1"
1622   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623         (match_operand:QI 1 "general_operand" "*qn,m"))]
1624   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626   "mov{b}\t{%1, %0|%0, %1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "mode" "QI")])
1629
1630 (define_insn "*movstrictqi_xor"
1631   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632         (match_operand:QI 1 "const0_operand" "i"))
1633    (clobber (reg:CC FLAGS_REG))]
1634   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635   "xor{b}\t{%0, %0|%0, %0}"
1636   [(set_attr "type" "alu1")
1637    (set_attr "mode" "QI")
1638    (set_attr "length_immediate" "0")])
1639
1640 (define_insn "*movsi_extv_1"
1641   [(set (match_operand:SI 0 "register_operand" "=R")
1642         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   ""
1646   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647   [(set_attr "type" "imovx")
1648    (set_attr "mode" "SI")])
1649
1650 (define_insn "*movhi_extv_1"
1651   [(set (match_operand:HI 0 "register_operand" "=R")
1652         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1653                          (const_int 8)
1654                          (const_int 8)))]
1655   ""
1656   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657   [(set_attr "type" "imovx")
1658    (set_attr "mode" "SI")])
1659
1660 (define_insn "*movqi_extv_1"
1661   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663                          (const_int 8)
1664                          (const_int 8)))]
1665   "!TARGET_64BIT"
1666 {
1667   switch (get_attr_type (insn))
1668     {
1669     case TYPE_IMOVX:
1670       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671     default:
1672       return "mov{b}\t{%h1, %0|%0, %h1}";
1673     }
1674 }
1675   [(set (attr "type")
1676      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678                              (ne (symbol_ref "TARGET_MOVX")
1679                                  (const_int 0))))
1680         (const_string "imovx")
1681         (const_string "imov")))
1682    (set (attr "mode")
1683      (if_then_else (eq_attr "type" "imovx")
1684         (const_string "SI")
1685         (const_string "QI")))])
1686
1687 (define_insn "*movqi_extv_1_rex64"
1688   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1690                          (const_int 8)
1691                          (const_int 8)))]
1692   "TARGET_64BIT"
1693 {
1694   switch (get_attr_type (insn))
1695     {
1696     case TYPE_IMOVX:
1697       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1698     default:
1699       return "mov{b}\t{%h1, %0|%0, %h1}";
1700     }
1701 }
1702   [(set (attr "type")
1703      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705                              (ne (symbol_ref "TARGET_MOVX")
1706                                  (const_int 0))))
1707         (const_string "imovx")
1708         (const_string "imov")))
1709    (set (attr "mode")
1710      (if_then_else (eq_attr "type" "imovx")
1711         (const_string "SI")
1712         (const_string "QI")))])
1713
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1721   "@
1722    movabs{b}\t{%1, %P0|%P0, %1}
1723    mov{b}\t{%1, %a0|%a0, %1}"
1724   [(set_attr "type" "imov")
1725    (set_attr "modrm" "0,*")
1726    (set_attr "length_address" "8,0")
1727    (set_attr "length_immediate" "0,*")
1728    (set_attr "memory" "store")
1729    (set_attr "mode" "QI")])
1730
1731 (define_insn "*movabsqi_2_rex64"
1732   [(set (match_operand:QI 0 "register_operand" "=a,r")
1733         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1735   "@
1736    movabs{b}\t{%P1, %0|%0, %P1}
1737    mov{b}\t{%a1, %0|%0, %a1}"
1738   [(set_attr "type" "imov")
1739    (set_attr "modrm" "0,*")
1740    (set_attr "length_address" "8,0")
1741    (set_attr "length_immediate" "0")
1742    (set_attr "memory" "load")
1743    (set_attr "mode" "QI")])
1744
1745 (define_insn "*movdi_extzv_1"
1746   [(set (match_operand:DI 0 "register_operand" "=R")
1747         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1748                          (const_int 8)
1749                          (const_int 8)))]
1750   "TARGET_64BIT"
1751   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752   [(set_attr "type" "imovx")
1753    (set_attr "mode" "DI")])
1754
1755 (define_insn "*movsi_extzv_1"
1756   [(set (match_operand:SI 0 "register_operand" "=R")
1757         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1758                          (const_int 8)
1759                          (const_int 8)))]
1760   ""
1761   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762   [(set_attr "type" "imovx")
1763    (set_attr "mode" "SI")])
1764
1765 (define_insn "*movqi_extzv_2"
1766   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768                                     (const_int 8)
1769                                     (const_int 8)) 0))]
1770   "!TARGET_64BIT"
1771 {
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776     default:
1777       return "mov{b}\t{%h1, %0|%0, %h1}";
1778     }
1779 }
1780   [(set (attr "type")
1781      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783                              (ne (symbol_ref "TARGET_MOVX")
1784                                  (const_int 0))))
1785         (const_string "imovx")
1786         (const_string "imov")))
1787    (set (attr "mode")
1788      (if_then_else (eq_attr "type" "imovx")
1789         (const_string "SI")
1790         (const_string "QI")))])
1791
1792 (define_insn "*movqi_extzv_2_rex64"
1793   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1795                                     (const_int 8)
1796                                     (const_int 8)) 0))]
1797   "TARGET_64BIT"
1798 {
1799   switch (get_attr_type (insn))
1800     {
1801     case TYPE_IMOVX:
1802       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1803     default:
1804       return "mov{b}\t{%h1, %0|%0, %h1}";
1805     }
1806 }
1807   [(set (attr "type")
1808      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809                         (ne (symbol_ref "TARGET_MOVX")
1810                             (const_int 0)))
1811         (const_string "imovx")
1812         (const_string "imov")))
1813    (set (attr "mode")
1814      (if_then_else (eq_attr "type" "imovx")
1815         (const_string "SI")
1816         (const_string "QI")))])
1817
1818 (define_insn "movsi_insv_1"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (match_operand:SI 1 "general_operand" "Qmn"))]
1823   "!TARGET_64BIT"
1824   "mov{b}\t{%b1, %h0|%h0, %b1}"
1825   [(set_attr "type" "imov")
1826    (set_attr "mode" "QI")])
1827
1828 (define_insn "*movsi_insv_1_rex64"
1829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830                          (const_int 8)
1831                          (const_int 8))
1832         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1833   "TARGET_64BIT"
1834   "mov{b}\t{%b1, %h0|%h0, %b1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1837
1838 (define_insn "movdi_insv_1_rex64"
1839   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1840                          (const_int 8)
1841                          (const_int 8))
1842         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1843   "TARGET_64BIT"
1844   "mov{b}\t{%b1, %h0|%h0, %b1}"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "QI")])
1847
1848 (define_insn "*movqi_insv_2"
1849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1850                          (const_int 8)
1851                          (const_int 8))
1852         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1853                      (const_int 8)))]
1854   ""
1855   "mov{b}\t{%h1, %h0|%h0, %h1}"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "QI")])
1858
1859 (define_expand "movdi"
1860   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861         (match_operand:DI 1 "general_operand" ""))]
1862   ""
1863   "ix86_expand_move (DImode, operands); DONE;")
1864
1865 (define_insn "*pushdi"
1866   [(set (match_operand:DI 0 "push_operand" "=<")
1867         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1868   "!TARGET_64BIT"
1869   "#")
1870
1871 (define_insn "*pushdi2_rex64"
1872   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874   "TARGET_64BIT"
1875   "@
1876    push{q}\t%1
1877    #"
1878   [(set_attr "type" "push,multi")
1879    (set_attr "mode" "DI")])
1880
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it.  In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1885 (define_peephole2
1886   [(match_scratch:DI 2 "r")
1887    (set (match_operand:DI 0 "push_operand" "")
1888         (match_operand:DI 1 "immediate_operand" ""))]
1889   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890    && !x86_64_immediate_operand (operands[1], DImode)"
1891   [(set (match_dup 2) (match_dup 1))
1892    (set (match_dup 0) (match_dup 2))]
1893   "")
1894
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1898 (define_peephole2
1899   [(set (match_operand:DI 0 "push_operand" "")
1900         (match_operand:DI 1 "immediate_operand" ""))]
1901   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903   [(set (match_dup 0) (match_dup 1))
1904    (set (match_dup 2) (match_dup 3))]
1905   "split_di (operands + 1, 1, operands + 2, operands + 3);
1906    operands[1] = gen_lowpart (DImode, operands[2]);
1907    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1908                                                     GEN_INT (4)));
1909   ")
1910
1911 (define_split
1912   [(set (match_operand:DI 0 "push_operand" "")
1913         (match_operand:DI 1 "immediate_operand" ""))]
1914   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915                     ? flow2_completed : reload_completed)
1916    && !symbolic_operand (operands[1], DImode)
1917    && !x86_64_immediate_operand (operands[1], DImode)"
1918   [(set (match_dup 0) (match_dup 1))
1919    (set (match_dup 2) (match_dup 3))]
1920   "split_di (operands + 1, 1, operands + 2, operands + 3);
1921    operands[1] = gen_lowpart (DImode, operands[2]);
1922    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1923                                                     GEN_INT (4)));
1924   ")
1925
1926 (define_insn "*pushdi2_prologue_rex64"
1927   [(set (match_operand:DI 0 "push_operand" "=<")
1928         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929    (clobber (mem:BLK (scratch)))]
1930   "TARGET_64BIT"
1931   "push{q}\t%1"
1932   [(set_attr "type" "push")
1933    (set_attr "mode" "DI")])
1934
1935 (define_insn "*popdi1_epilogue_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937         (mem:DI (reg:DI SP_REG)))
1938    (set (reg:DI SP_REG)
1939         (plus:DI (reg:DI SP_REG) (const_int 8)))
1940    (clobber (mem:BLK (scratch)))]
1941   "TARGET_64BIT"
1942   "pop{q}\t%0"
1943   [(set_attr "type" "pop")
1944    (set_attr "mode" "DI")])
1945
1946 (define_insn "popdi1"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948         (mem:DI (reg:DI SP_REG)))
1949    (set (reg:DI SP_REG)
1950         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1951   "TARGET_64BIT"
1952   "pop{q}\t%0"
1953   [(set_attr "type" "pop")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movdi_xor_rex64"
1957   [(set (match_operand:DI 0 "register_operand" "=r")
1958         (match_operand:DI 1 "const0_operand" "i"))
1959    (clobber (reg:CC FLAGS_REG))]
1960   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961    && reload_completed"
1962   "xor{l}\t{%k0, %k0|%k0, %k0}"
1963   [(set_attr "type" "alu1")
1964    (set_attr "mode" "SI")
1965    (set_attr "length_immediate" "0")])
1966
1967 (define_insn "*movdi_or_rex64"
1968   [(set (match_operand:DI 0 "register_operand" "=r")
1969         (match_operand:DI 1 "const_int_operand" "i"))
1970    (clobber (reg:CC FLAGS_REG))]
1971   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1972    && reload_completed
1973    && operands[1] == constm1_rtx"
1974 {
1975   operands[1] = constm1_rtx;
1976   return "or{q}\t{%1, %0|%0, %1}";
1977 }
1978   [(set_attr "type" "alu1")
1979    (set_attr "mode" "DI")
1980    (set_attr "length_immediate" "1")])
1981
1982 (define_insn "*movdi_2"
1983   [(set (match_operand:DI 0 "nonimmediate_operand"
1984                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1985         (match_operand:DI 1 "general_operand"
1986                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1987   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988   "@
1989    #
1990    #
1991    pxor\t%0, %0
1992    movq\t{%1, %0|%0, %1}
1993    movq\t{%1, %0|%0, %1}
1994    pxor\t%0, %0
1995    movq\t{%1, %0|%0, %1}
1996    movdqa\t{%1, %0|%0, %1}
1997    movq\t{%1, %0|%0, %1}
1998    xorps\t%0, %0
1999    movlps\t{%1, %0|%0, %1}
2000    movaps\t{%1, %0|%0, %1}
2001    movlps\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2004
2005 (define_split
2006   [(set (match_operand:DI 0 "push_operand" "")
2007         (match_operand:DI 1 "general_operand" ""))]
2008   "!TARGET_64BIT && reload_completed
2009    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2010   [(const_int 0)]
2011   "ix86_split_long_move (operands); DONE;")
2012
2013 ;; %%% This multiword shite has got to go.
2014 (define_split
2015   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016         (match_operand:DI 1 "general_operand" ""))]
2017   "!TARGET_64BIT && reload_completed
2018    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2020   [(const_int 0)]
2021   "ix86_split_long_move (operands); DONE;")
2022
2023 (define_insn "*movdi_1_rex64"
2024   [(set (match_operand:DI 0 "nonimmediate_operand"
2025           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026         (match_operand:DI 1 "general_operand"
2027           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2028   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2029 {
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_SSECVT:
2033       if (SSE_REG_P (operands[0]))
2034         return "movq2dq\t{%1, %0|%0, %1}";
2035       else
2036         return "movdq2q\t{%1, %0|%0, %1}";
2037
2038     case TYPE_SSEMOV:
2039       if (get_attr_mode (insn) == MODE_TI)
2040         return "movdqa\t{%1, %0|%0, %1}";
2041       /* FALLTHRU */
2042
2043     case TYPE_MMXMOV:
2044       /* Moves from and into integer register is done using movd
2045          opcode with REX prefix.  */
2046       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047         return "movd\t{%1, %0|%0, %1}";
2048       return "movq\t{%1, %0|%0, %1}";
2049
2050     case TYPE_SSELOG1:
2051     case TYPE_MMXADD:
2052       return "pxor\t%0, %0";
2053
2054     case TYPE_MULTI:
2055       return "#";
2056
2057     case TYPE_LEA:
2058       return "lea{q}\t{%a1, %0|%0, %a1}";
2059
2060     default:
2061       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062       if (get_attr_mode (insn) == MODE_SI)
2063         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064       else if (which_alternative == 2)
2065         return "movabs{q}\t{%1, %0|%0, %1}";
2066       else
2067         return "mov{q}\t{%1, %0|%0, %1}";
2068     }
2069 }
2070   [(set (attr "type")
2071      (cond [(eq_attr "alternative" "5")
2072               (const_string "mmxadd")
2073             (eq_attr "alternative" "6,7,8,9,10")
2074               (const_string "mmxmov")
2075             (eq_attr "alternative" "11")
2076               (const_string "sselog1")
2077             (eq_attr "alternative" "12,13,14,15,16")
2078               (const_string "ssemov")
2079             (eq_attr "alternative" "17,18")
2080               (const_string "ssecvt")
2081             (eq_attr "alternative" "4")
2082               (const_string "multi")
2083             (match_operand:DI 1 "pic_32bit_operand" "")
2084               (const_string "lea")
2085            ]
2086            (const_string "imov")))
2087    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2090
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2098   "@
2099    movabs{q}\t{%1, %P0|%P0, %1}
2100    mov{q}\t{%1, %a0|%a0, %1}"
2101   [(set_attr "type" "imov")
2102    (set_attr "modrm" "0,*")
2103    (set_attr "length_address" "8,0")
2104    (set_attr "length_immediate" "0,*")
2105    (set_attr "memory" "store")
2106    (set_attr "mode" "DI")])
2107
2108 (define_insn "*movabsdi_2_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "=a,r")
2110         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2112   "@
2113    movabs{q}\t{%P1, %0|%0, %P1}
2114    mov{q}\t{%a1, %0|%0, %a1}"
2115   [(set_attr "type" "imov")
2116    (set_attr "modrm" "0,*")
2117    (set_attr "length_address" "8,0")
2118    (set_attr "length_immediate" "0")
2119    (set_attr "memory" "load")
2120    (set_attr "mode" "DI")])
2121
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it.  In case this
2124 ;; fails, move by 32bit parts.
2125 (define_peephole2
2126   [(match_scratch:DI 2 "r")
2127    (set (match_operand:DI 0 "memory_operand" "")
2128         (match_operand:DI 1 "immediate_operand" ""))]
2129   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode)"
2131   [(set (match_dup 2) (match_dup 1))
2132    (set (match_dup 0) (match_dup 2))]
2133   "")
2134
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2138 (define_peephole2
2139   [(set (match_operand:DI 0 "memory_operand" "")
2140         (match_operand:DI 1 "immediate_operand" ""))]
2141   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143   [(set (match_dup 2) (match_dup 3))
2144    (set (match_dup 4) (match_dup 5))]
2145   "split_di (operands, 2, operands + 2, operands + 4);")
2146
2147 (define_split
2148   [(set (match_operand:DI 0 "memory_operand" "")
2149         (match_operand:DI 1 "immediate_operand" ""))]
2150   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151                     ? flow2_completed : reload_completed)
2152    && !symbolic_operand (operands[1], DImode)
2153    && !x86_64_immediate_operand (operands[1], DImode)"
2154   [(set (match_dup 2) (match_dup 3))
2155    (set (match_dup 4) (match_dup 5))]
2156   "split_di (operands, 2, operands + 2, operands + 4);")
2157
2158 (define_insn "*swapdi_rex64"
2159   [(set (match_operand:DI 0 "register_operand" "+r")
2160         (match_operand:DI 1 "register_operand" "+r"))
2161    (set (match_dup 1)
2162         (match_dup 0))]
2163   "TARGET_64BIT"
2164   "xchg{q}\t%1, %0"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "DI")
2167    (set_attr "pent_pair" "np")
2168    (set_attr "athlon_decode" "vector")
2169    (set_attr "amdfam10_decode" "double")])   
2170
2171 (define_expand "movti"
2172   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173         (match_operand:TI 1 "nonimmediate_operand" ""))]
2174   "TARGET_SSE || TARGET_64BIT"
2175 {
2176   if (TARGET_64BIT)
2177     ix86_expand_move (TImode, operands);
2178   else
2179     ix86_expand_vector_move (TImode, operands);
2180   DONE;
2181 })
2182
2183 (define_insn "*movti_internal"
2184   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186   "TARGET_SSE && !TARGET_64BIT
2187    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 {
2189   switch (which_alternative)
2190     {
2191     case 0:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 1:
2197     case 2:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       gcc_unreachable ();
2204     }
2205 }
2206   [(set_attr "type" "sselog1,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209                     (ne (symbol_ref "optimize_size") (const_int 0)))
2210                  (const_string "V4SF")
2211                (and (eq_attr "alternative" "2")
2212                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2213                         (const_int 0)))
2214                  (const_string "V4SF")]
2215               (const_string "TI")))])
2216
2217 (define_insn "*movti_rex64"
2218   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2220   "TARGET_64BIT
2221    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2222 {
2223   switch (which_alternative)
2224     {
2225     case 0:
2226     case 1:
2227       return "#";
2228     case 2:
2229       if (get_attr_mode (insn) == MODE_V4SF)
2230         return "xorps\t%0, %0";
2231       else
2232         return "pxor\t%0, %0";
2233     case 3:
2234     case 4:
2235       if (get_attr_mode (insn) == MODE_V4SF)
2236         return "movaps\t{%1, %0|%0, %1}";
2237       else
2238         return "movdqa\t{%1, %0|%0, %1}";
2239     default:
2240       gcc_unreachable ();
2241     }
2242 }
2243   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "2,3")
2246                  (if_then_else
2247                    (ne (symbol_ref "optimize_size")
2248                        (const_int 0))
2249                    (const_string "V4SF")
2250                    (const_string "TI"))
2251                (eq_attr "alternative" "4")
2252                  (if_then_else
2253                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2254                             (const_int 0))
2255                         (ne (symbol_ref "optimize_size")
2256                             (const_int 0)))
2257                    (const_string "V4SF")
2258                    (const_string "TI"))]
2259                (const_string "DI")))])
2260
2261 (define_split
2262   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263         (match_operand:TI 1 "general_operand" ""))]
2264   "reload_completed && !SSE_REG_P (operands[0])
2265    && !SSE_REG_P (operands[1])"
2266   [(const_int 0)]
2267   "ix86_split_long_move (operands); DONE;")
2268
2269 (define_expand "movsf"
2270   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271         (match_operand:SF 1 "general_operand" ""))]
2272   ""
2273   "ix86_expand_move (SFmode, operands); DONE;")
2274
2275 (define_insn "*pushsf"
2276   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2278   "!TARGET_64BIT"
2279 {
2280   /* Anything else should be already split before reg-stack.  */
2281   gcc_assert (which_alternative == 1);
2282   return "push{l}\t%1";
2283 }
2284   [(set_attr "type" "multi,push,multi")
2285    (set_attr "unit" "i387,*,*")
2286    (set_attr "mode" "SF,SI,SF")])
2287
2288 (define_insn "*pushsf_rex64"
2289   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2291   "TARGET_64BIT"
2292 {
2293   /* Anything else should be already split before reg-stack.  */
2294   gcc_assert (which_alternative == 1);
2295   return "push{q}\t%q1";
2296 }
2297   [(set_attr "type" "multi,push,multi")
2298    (set_attr "unit" "i387,*,*")
2299    (set_attr "mode" "SF,DI,SF")])
2300
2301 (define_split
2302   [(set (match_operand:SF 0 "push_operand" "")
2303         (match_operand:SF 1 "memory_operand" ""))]
2304   "reload_completed
2305    && MEM_P (operands[1])
2306    && constant_pool_reference_p (operands[1])"
2307   [(set (match_dup 0)
2308         (match_dup 1))]
2309   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2310
2311
2312 ;; %%% Kill this when call knows how to work this out.
2313 (define_split
2314   [(set (match_operand:SF 0 "push_operand" "")
2315         (match_operand:SF 1 "any_fp_register_operand" ""))]
2316   "!TARGET_64BIT"
2317   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2319
2320 (define_split
2321   [(set (match_operand:SF 0 "push_operand" "")
2322         (match_operand:SF 1 "any_fp_register_operand" ""))]
2323   "TARGET_64BIT"
2324   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2326
2327 (define_insn "*movsf_1"
2328   [(set (match_operand:SF 0 "nonimmediate_operand"
2329           "=f,m,f,r  ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r  ")
2330         (match_operand:SF 1 "general_operand"
2331           "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r  ,*Ym"))]
2332   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333    && (reload_in_progress || reload_completed
2334        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335        || (!TARGET_SSE_MATH && optimize_size
2336            && standard_80387_constant_p (operands[1]))
2337        || GET_CODE (operands[1]) != CONST_DOUBLE
2338        || memory_operand (operands[0], SFmode))"
2339 {
2340   switch (which_alternative)
2341     {
2342     case 0:
2343       return output_387_reg_move (insn, operands);
2344
2345     case 1:
2346       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347         return "fstp%z0\t%y0";
2348       else
2349         return "fst%z0\t%y0";
2350
2351     case 2:
2352       return standard_80387_constant_opcode (operands[1]);
2353
2354     case 3:
2355     case 4:
2356       return "mov{l}\t{%1, %0|%0, %1}";
2357     case 5:
2358       if (get_attr_mode (insn) == MODE_TI)
2359         return "pxor\t%0, %0";
2360       else
2361         return "xorps\t%0, %0";
2362     case 6:
2363       if (get_attr_mode (insn) == MODE_V4SF)
2364         return "movaps\t{%1, %0|%0, %1}";
2365       else
2366         return "movss\t{%1, %0|%0, %1}";
2367     case 7: case 8:
2368       return "movss\t{%1, %0|%0, %1}";
2369
2370     case 9: case 10:
2371     case 12: case 13: case 14: case 15:
2372       return "movd\t{%1, %0|%0, %1}";
2373
2374     case 11:
2375       return "movq\t{%1, %0|%0, %1}";
2376
2377     default:
2378       gcc_unreachable ();
2379     }
2380 }
2381   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2382    (set (attr "mode")
2383         (cond [(eq_attr "alternative" "3,4,9,10")
2384                  (const_string "SI")
2385                (eq_attr "alternative" "5")
2386                  (if_then_else
2387                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2388                                  (const_int 0))
2389                              (ne (symbol_ref "TARGET_SSE2")
2390                                  (const_int 0)))
2391                         (eq (symbol_ref "optimize_size")
2392                             (const_int 0)))
2393                    (const_string "TI")
2394                    (const_string "V4SF"))
2395                /* For architectures resolving dependencies on
2396                   whole SSE registers use APS move to break dependency
2397                   chains, otherwise use short move to avoid extra work.
2398
2399                   Do the same for architectures resolving dependencies on
2400                   the parts.  While in DF mode it is better to always handle
2401                   just register parts, the SF mode is different due to lack
2402                   of instructions to load just part of the register.  It is
2403                   better to maintain the whole registers in single format
2404                   to avoid problems on using packed logical operations.  */
2405                (eq_attr "alternative" "6")
2406                  (if_then_else
2407                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2408                             (const_int 0))
2409                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2410                             (const_int 0)))
2411                    (const_string "V4SF")
2412                    (const_string "SF"))
2413                (eq_attr "alternative" "11")
2414                  (const_string "DI")]
2415                (const_string "SF")))])
2416
2417 (define_insn "*swapsf"
2418   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419         (match_operand:SF 1 "fp_register_operand" "+f"))
2420    (set (match_dup 1)
2421         (match_dup 0))]
2422   "reload_completed || TARGET_80387"
2423 {
2424   if (STACK_TOP_P (operands[0]))
2425     return "fxch\t%1";
2426   else
2427     return "fxch\t%0";
2428 }
2429   [(set_attr "type" "fxch")
2430    (set_attr "mode" "SF")])
2431
2432 (define_expand "movdf"
2433   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434         (match_operand:DF 1 "general_operand" ""))]
2435   ""
2436   "ix86_expand_move (DFmode, operands); DONE;")
2437
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter.  Allow this
2441 ;; pattern for optimize_size too.
2442
2443 (define_insn "*pushdf_nointeger"
2444   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2447 {
2448   /* This insn should be already split before reg-stack.  */
2449   gcc_unreachable ();
2450 }
2451   [(set_attr "type" "multi")
2452    (set_attr "unit" "i387,*,*,*")
2453    (set_attr "mode" "DF,SI,SI,DF")])
2454
2455 (define_insn "*pushdf_integer"
2456   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2459 {
2460   /* This insn should be already split before reg-stack.  */
2461   gcc_unreachable ();
2462 }
2463   [(set_attr "type" "multi")
2464    (set_attr "unit" "i387,*,*")
2465    (set_attr "mode" "DF,SI,DF")])
2466
2467 ;; %%% Kill this when call knows how to work this out.
2468 (define_split
2469   [(set (match_operand:DF 0 "push_operand" "")
2470         (match_operand:DF 1 "any_fp_register_operand" ""))]
2471   "!TARGET_64BIT && reload_completed"
2472   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2474   "")
2475
2476 (define_split
2477   [(set (match_operand:DF 0 "push_operand" "")
2478         (match_operand:DF 1 "any_fp_register_operand" ""))]
2479   "TARGET_64BIT && reload_completed"
2480   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2482   "")
2483
2484 (define_split
2485   [(set (match_operand:DF 0 "push_operand" "")
2486         (match_operand:DF 1 "general_operand" ""))]
2487   "reload_completed"
2488   [(const_int 0)]
2489   "ix86_split_long_move (operands); DONE;")
2490
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2494
2495 (define_insn "*movdf_nointeger"
2496   [(set (match_operand:DF 0 "nonimmediate_operand"
2497                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2498         (match_operand:DF 1 "general_operand"
2499                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2500   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502    && (reload_in_progress || reload_completed
2503        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505            && standard_80387_constant_p (operands[1]))
2506        || GET_CODE (operands[1]) != CONST_DOUBLE
2507        || memory_operand (operands[0], DFmode))"
2508 {
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       return output_387_reg_move (insn, operands);
2513
2514     case 1:
2515       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516         return "fstp%z0\t%y0";
2517       else
2518         return "fst%z0\t%y0";
2519
2520     case 2:
2521       return standard_80387_constant_opcode (operands[1]);
2522
2523     case 3:
2524     case 4:
2525       return "#";
2526     case 5:
2527       switch (get_attr_mode (insn))
2528         {
2529         case MODE_V4SF:
2530           return "xorps\t%0, %0";
2531         case MODE_V2DF:
2532           return "xorpd\t%0, %0";
2533         case MODE_TI:
2534           return "pxor\t%0, %0";
2535         default:
2536           gcc_unreachable ();
2537         }
2538     case 6:
2539     case 7:
2540     case 8:
2541       switch (get_attr_mode (insn))
2542         {
2543         case MODE_V4SF:
2544           return "movaps\t{%1, %0|%0, %1}";
2545         case MODE_V2DF:
2546           return "movapd\t{%1, %0|%0, %1}";
2547         case MODE_TI:
2548           return "movdqa\t{%1, %0|%0, %1}";
2549         case MODE_DI:
2550           return "movq\t{%1, %0|%0, %1}";
2551         case MODE_DF:
2552           return "movsd\t{%1, %0|%0, %1}";
2553         case MODE_V1DF:
2554           return "movlpd\t{%1, %0|%0, %1}";
2555         case MODE_V2SF:
2556           return "movlps\t{%1, %0|%0, %1}";
2557         default:
2558           gcc_unreachable ();
2559         }
2560
2561     default:
2562       gcc_unreachable ();
2563     }
2564 }
2565   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2566    (set (attr "mode")
2567         (cond [(eq_attr "alternative" "0,1,2")
2568                  (const_string "DF")
2569                (eq_attr "alternative" "3,4")
2570                  (const_string "SI")
2571
2572                /* For SSE1, we have many fewer alternatives.  */
2573                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574                  (cond [(eq_attr "alternative" "5,6")
2575                           (const_string "V4SF")
2576                        ]
2577                    (const_string "V2SF"))
2578
2579                /* xorps is one byte shorter.  */
2580                (eq_attr "alternative" "5")
2581                  (cond [(ne (symbol_ref "optimize_size")
2582                             (const_int 0))
2583                           (const_string "V4SF")
2584                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2585                             (const_int 0))
2586                           (const_string "TI")
2587                        ]
2588                        (const_string "V2DF"))
2589
2590                /* For architectures resolving dependencies on
2591                   whole SSE registers use APD move to break dependency
2592                   chains, otherwise use short move to avoid extra work.
2593
2594                   movaps encodes one byte shorter.  */
2595                (eq_attr "alternative" "6")
2596                  (cond
2597                    [(ne (symbol_ref "optimize_size")
2598                         (const_int 0))
2599                       (const_string "V4SF")
2600                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601                         (const_int 0))
2602                       (const_string "V2DF")
2603                    ]
2604                    (const_string "DF"))
2605                /* For architectures resolving dependencies on register
2606                   parts we may avoid extra work to zero out upper part
2607                   of register.  */
2608                (eq_attr "alternative" "7")
2609                  (if_then_else
2610                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611                        (const_int 0))
2612                    (const_string "V1DF")
2613                    (const_string "DF"))
2614               ]
2615               (const_string "DF")))])
2616
2617 (define_insn "*movdf_integer_rex64"
2618   [(set (match_operand:DF 0 "nonimmediate_operand"
2619                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2620         (match_operand:DF 1 "general_operand"
2621                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2622   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623    && (reload_in_progress || reload_completed
2624        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626            && standard_80387_constant_p (operands[1]))
2627        || GET_CODE (operands[1]) != CONST_DOUBLE
2628        || memory_operand (operands[0], DFmode))"
2629 {
2630   switch (which_alternative)
2631     {
2632     case 0:
2633       return output_387_reg_move (insn, operands);
2634
2635     case 1:
2636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637         return "fstp%z0\t%y0";
2638       else
2639         return "fst%z0\t%y0";
2640
2641     case 2:
2642       return standard_80387_constant_opcode (operands[1]);
2643
2644     case 3:
2645     case 4:
2646       return "#";
2647
2648     case 5:
2649       switch (get_attr_mode (insn))
2650         {
2651         case MODE_V4SF:
2652           return "xorps\t%0, %0";
2653         case MODE_V2DF:
2654           return "xorpd\t%0, %0";
2655         case MODE_TI:
2656           return "pxor\t%0, %0";
2657         default:
2658           gcc_unreachable ();
2659         }
2660     case 6:
2661     case 7:
2662     case 8:
2663       switch (get_attr_mode (insn))
2664         {
2665         case MODE_V4SF:
2666           return "movaps\t{%1, %0|%0, %1}";
2667         case MODE_V2DF:
2668           return "movapd\t{%1, %0|%0, %1}";
2669         case MODE_TI:
2670           return "movdqa\t{%1, %0|%0, %1}";
2671         case MODE_DI:
2672           return "movq\t{%1, %0|%0, %1}";
2673         case MODE_DF:
2674           return "movsd\t{%1, %0|%0, %1}";
2675         case MODE_V1DF:
2676           return "movlpd\t{%1, %0|%0, %1}";
2677         case MODE_V2SF:
2678           return "movlps\t{%1, %0|%0, %1}";
2679         default:
2680           gcc_unreachable ();
2681         }
2682
2683     case 9:
2684     case 10:
2685       return "movd\t{%1, %0|%0, %1}";
2686
2687     default:
2688       gcc_unreachable();
2689     }
2690 }
2691   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2692    (set (attr "mode")
2693         (cond [(eq_attr "alternative" "0,1,2")
2694                  (const_string "DF")
2695                (eq_attr "alternative" "3,4,9,10")
2696                  (const_string "DI")
2697
2698                /* For SSE1, we have many fewer alternatives.  */
2699                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700                  (cond [(eq_attr "alternative" "5,6")
2701                           (const_string "V4SF")
2702                        ]
2703                    (const_string "V2SF"))
2704
2705                /* xorps is one byte shorter.  */
2706                (eq_attr "alternative" "5")
2707                  (cond [(ne (symbol_ref "optimize_size")
2708                             (const_int 0))
2709                           (const_string "V4SF")
2710                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2711                             (const_int 0))
2712                           (const_string "TI")
2713                        ]
2714                        (const_string "V2DF"))
2715
2716                /* For architectures resolving dependencies on
2717                   whole SSE registers use APD move to break dependency
2718                   chains, otherwise use short move to avoid extra work.
2719
2720                   movaps encodes one byte shorter.  */
2721                (eq_attr "alternative" "6")
2722                  (cond
2723                    [(ne (symbol_ref "optimize_size")
2724                         (const_int 0))
2725                       (const_string "V4SF")
2726                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2727                         (const_int 0))
2728                       (const_string "V2DF")
2729                    ]
2730                    (const_string "DF"))
2731                /* For architectures resolving dependencies on register
2732                   parts we may avoid extra work to zero out upper part
2733                   of register.  */
2734                (eq_attr "alternative" "7")
2735                  (if_then_else
2736                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2737                        (const_int 0))
2738                    (const_string "V1DF")
2739                    (const_string "DF"))
2740               ]
2741               (const_string "DF")))])
2742
2743 (define_insn "*movdf_integer"
2744   [(set (match_operand:DF 0 "nonimmediate_operand"
2745                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2746         (match_operand:DF 1 "general_operand"
2747                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2748   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750    && (reload_in_progress || reload_completed
2751        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753            && standard_80387_constant_p (operands[1]))
2754        || GET_CODE (operands[1]) != CONST_DOUBLE
2755        || memory_operand (operands[0], DFmode))"
2756 {
2757   switch (which_alternative)
2758     {
2759     case 0:
2760       return output_387_reg_move (insn, operands);
2761
2762     case 1:
2763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764         return "fstp%z0\t%y0";
2765       else
2766         return "fst%z0\t%y0";
2767
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2770
2771     case 3:
2772     case 4:
2773       return "#";
2774
2775     case 5:
2776       switch (get_attr_mode (insn))
2777         {
2778         case MODE_V4SF:
2779           return "xorps\t%0, %0";
2780         case MODE_V2DF:
2781           return "xorpd\t%0, %0";
2782         case MODE_TI:
2783           return "pxor\t%0, %0";
2784         default:
2785           gcc_unreachable ();
2786         }
2787     case 6:
2788     case 7:
2789     case 8:
2790       switch (get_attr_mode (insn))
2791         {
2792         case MODE_V4SF:
2793           return "movaps\t{%1, %0|%0, %1}";
2794         case MODE_V2DF:
2795           return "movapd\t{%1, %0|%0, %1}";
2796         case MODE_TI:
2797           return "movdqa\t{%1, %0|%0, %1}";
2798         case MODE_DI:
2799           return "movq\t{%1, %0|%0, %1}";
2800         case MODE_DF:
2801           return "movsd\t{%1, %0|%0, %1}";
2802         case MODE_V1DF:
2803           return "movlpd\t{%1, %0|%0, %1}";
2804         case MODE_V2SF:
2805           return "movlps\t{%1, %0|%0, %1}";
2806         default:
2807           gcc_unreachable ();
2808         }
2809
2810     default:
2811       gcc_unreachable();
2812     }
2813 }
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "0,1,2")
2817                  (const_string "DF")
2818                (eq_attr "alternative" "3,4")
2819                  (const_string "SI")
2820
2821                /* For SSE1, we have many fewer alternatives.  */
2822                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823                  (cond [(eq_attr "alternative" "5,6")
2824                           (const_string "V4SF")
2825                        ]
2826                    (const_string "V2SF"))
2827
2828                /* xorps is one byte shorter.  */
2829                (eq_attr "alternative" "5")
2830                  (cond [(ne (symbol_ref "optimize_size")
2831                             (const_int 0))
2832                           (const_string "V4SF")
2833                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2834                             (const_int 0))
2835                           (const_string "TI")
2836                        ]
2837                        (const_string "V2DF"))
2838
2839                /* For architectures resolving dependencies on
2840                   whole SSE registers use APD move to break dependency
2841                   chains, otherwise use short move to avoid extra work.
2842
2843                   movaps encodes one byte shorter.  */
2844                (eq_attr "alternative" "6")
2845                  (cond
2846                    [(ne (symbol_ref "optimize_size")
2847                         (const_int 0))
2848                       (const_string "V4SF")
2849                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2850                         (const_int 0))
2851                       (const_string "V2DF")
2852                    ]
2853                    (const_string "DF"))
2854                /* For architectures resolving dependencies on register
2855                   parts we may avoid extra work to zero out upper part
2856                   of register.  */
2857                (eq_attr "alternative" "7")
2858                  (if_then_else
2859                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2860                        (const_int 0))
2861                    (const_string "V1DF")
2862                    (const_string "DF"))
2863               ]
2864               (const_string "DF")))])
2865
2866 (define_split
2867   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868         (match_operand:DF 1 "general_operand" ""))]
2869   "reload_completed
2870    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871    && ! (ANY_FP_REG_P (operands[0]) ||
2872          (GET_CODE (operands[0]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874    && ! (ANY_FP_REG_P (operands[1]) ||
2875          (GET_CODE (operands[1]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2877   [(const_int 0)]
2878   "ix86_split_long_move (operands); DONE;")
2879
2880 (define_insn "*swapdf"
2881   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882         (match_operand:DF 1 "fp_register_operand" "+f"))
2883    (set (match_dup 1)
2884         (match_dup 0))]
2885   "reload_completed || TARGET_80387"
2886 {
2887   if (STACK_TOP_P (operands[0]))
2888     return "fxch\t%1";
2889   else
2890     return "fxch\t%0";
2891 }
2892   [(set_attr "type" "fxch")
2893    (set_attr "mode" "DF")])
2894
2895 (define_expand "movxf"
2896   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897         (match_operand:XF 1 "general_operand" ""))]
2898   ""
2899   "ix86_expand_move (XFmode, operands); DONE;")
2900
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;;  handled elsewhere).
2907
2908 (define_insn "*pushxf_nointeger"
2909   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2911   "optimize_size"
2912 {
2913   /* This insn should be already split before reg-stack.  */
2914   gcc_unreachable ();
2915 }
2916   [(set_attr "type" "multi")
2917    (set_attr "unit" "i387,*,*")
2918    (set_attr "mode" "XF,SI,SI")])
2919
2920 (define_insn "*pushxf_integer"
2921   [(set (match_operand:XF 0 "push_operand" "=<,<")
2922         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2923   "!optimize_size"
2924 {
2925   /* This insn should be already split before reg-stack.  */
2926   gcc_unreachable ();
2927 }
2928   [(set_attr "type" "multi")
2929    (set_attr "unit" "i387,*")
2930    (set_attr "mode" "XF,SI")])
2931
2932 (define_split
2933   [(set (match_operand 0 "push_operand" "")
2934         (match_operand 1 "general_operand" ""))]
2935   "reload_completed
2936    && (GET_MODE (operands[0]) == XFmode
2937        || GET_MODE (operands[0]) == DFmode)
2938    && !ANY_FP_REG_P (operands[1])"
2939   [(const_int 0)]
2940   "ix86_split_long_move (operands); DONE;")
2941
2942 (define_split
2943   [(set (match_operand:XF 0 "push_operand" "")
2944         (match_operand:XF 1 "any_fp_register_operand" ""))]
2945   "!TARGET_64BIT"
2946   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2949
2950 (define_split
2951   [(set (match_operand:XF 0 "push_operand" "")
2952         (match_operand:XF 1 "any_fp_register_operand" ""))]
2953   "TARGET_64BIT"
2954   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2957
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2962   "optimize_size
2963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964    && (reload_in_progress || reload_completed
2965        || (optimize_size && standard_80387_constant_p (operands[1]))
2966        || GET_CODE (operands[1]) != CONST_DOUBLE
2967        || memory_operand (operands[0], XFmode))"
2968 {
2969   switch (which_alternative)
2970     {
2971     case 0:
2972       return output_387_reg_move (insn, operands);
2973
2974     case 1:
2975       /* There is no non-popping store to memory for XFmode.  So if
2976          we need one, follow the store with a load.  */
2977       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978         return "fstp%z0\t%y0\;fld%z0\t%y0";
2979       else
2980         return "fstp%z0\t%y0";
2981
2982     case 2:
2983       return standard_80387_constant_opcode (operands[1]);
2984
2985     case 3: case 4:
2986       return "#";
2987     default:
2988       gcc_unreachable ();
2989     }
2990 }
2991   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992    (set_attr "mode" "XF,XF,XF,SI,SI")])
2993
2994 (define_insn "*movxf_integer"
2995   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2997   "!optimize_size
2998    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999    && (reload_in_progress || reload_completed
3000        || (optimize_size && standard_80387_constant_p (operands[1]))
3001        || GET_CODE (operands[1]) != CONST_DOUBLE
3002        || memory_operand (operands[0], XFmode))"
3003 {
3004   switch (which_alternative)
3005     {
3006     case 0:
3007       return output_387_reg_move (insn, operands);
3008
3009     case 1:
3010       /* There is no non-popping store to memory for XFmode.  So if
3011          we need one, follow the store with a load.  */
3012       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013         return "fstp%z0\t%y0\;fld%z0\t%y0";
3014       else
3015         return "fstp%z0\t%y0";
3016
3017     case 2:
3018       return standard_80387_constant_opcode (operands[1]);
3019
3020     case 3: case 4:
3021       return "#";
3022
3023     default:
3024       gcc_unreachable ();
3025     }
3026 }
3027   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028    (set_attr "mode" "XF,XF,XF,SI,SI")])
3029
3030 (define_split
3031   [(set (match_operand 0 "nonimmediate_operand" "")
3032         (match_operand 1 "general_operand" ""))]
3033   "reload_completed
3034    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035    && GET_MODE (operands[0]) == XFmode
3036    && ! (ANY_FP_REG_P (operands[0]) ||
3037          (GET_CODE (operands[0]) == SUBREG
3038           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039    && ! (ANY_FP_REG_P (operands[1]) ||
3040          (GET_CODE (operands[1]) == SUBREG
3041           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3042   [(const_int 0)]
3043   "ix86_split_long_move (operands); DONE;")
3044
3045 (define_split
3046   [(set (match_operand 0 "register_operand" "")
3047         (match_operand 1 "memory_operand" ""))]
3048   "reload_completed
3049    && MEM_P (operands[1])
3050    && (GET_MODE (operands[0]) == XFmode
3051        || GET_MODE (operands[0]) == SFmode
3052        || GET_MODE (operands[0]) == DFmode)
3053    && constant_pool_reference_p (operands[1])"
3054   [(set (match_dup 0) (match_dup 1))]
3055 {
3056   rtx c = avoid_constant_pool_reference (operands[1]);
3057   rtx r = operands[0];
3058
3059   if (GET_CODE (r) == SUBREG)
3060     r = SUBREG_REG (r);
3061
3062   if (SSE_REG_P (r))
3063     {
3064       if (!standard_sse_constant_p (c))
3065         FAIL;
3066     }
3067   else if (FP_REG_P (r))
3068     {
3069       if (!standard_80387_constant_p (c))
3070         FAIL;
3071     }
3072   else if (MMX_REG_P (r))
3073     FAIL;
3074
3075   operands[1] = c;
3076 })
3077
3078 (define_split
3079   [(set (match_operand 0 "register_operand" "")
3080         (float_extend (match_operand 1 "memory_operand" "")))]
3081   "reload_completed
3082    && MEM_P (operands[1])
3083    && (GET_MODE (operands[0]) == XFmode
3084        || GET_MODE (operands[0]) == SFmode
3085        || GET_MODE (operands[0]) == DFmode)
3086    && constant_pool_reference_p (operands[1])"
3087   [(set (match_dup 0) (match_dup 1))]
3088 {
3089   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090   rtx r = operands[0];
3091
3092   if (GET_CODE (r) == SUBREG)
3093     r = SUBREG_REG (r);
3094
3095   if (SSE_REG_P (r))
3096     {
3097       if (!standard_sse_constant_p (c))
3098         FAIL;
3099     }
3100   else if (FP_REG_P (r))
3101     {
3102       if (!standard_80387_constant_p (c))
3103         FAIL;
3104     }
3105   else if (MMX_REG_P (r))
3106     FAIL;
3107
3108   operands[1] = c;
3109 })
3110
3111 (define_insn "swapxf"
3112   [(set (match_operand:XF 0 "register_operand" "+f")
3113         (match_operand:XF 1 "register_operand" "+f"))
3114    (set (match_dup 1)
3115         (match_dup 0))]
3116   "TARGET_80387"
3117 {
3118   if (STACK_TOP_P (operands[0]))
3119     return "fxch\t%1";
3120   else
3121     return "fxch\t%0";
3122 }
3123   [(set_attr "type" "fxch")
3124    (set_attr "mode" "XF")])
3125
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3127 (define_split
3128   [(set (match_operand:X87MODEF 0 "register_operand" "")
3129         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131    && (standard_80387_constant_p (operands[1]) == 8
3132        || standard_80387_constant_p (operands[1]) == 9)"
3133   [(set (match_dup 0)(match_dup 1))
3134    (set (match_dup 0)
3135         (neg:X87MODEF (match_dup 0)))]
3136 {
3137   REAL_VALUE_TYPE r;
3138
3139   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140   if (real_isnegzero (&r))
3141     operands[1] = CONST0_RTX (<MODE>mode);
3142   else
3143     operands[1] = CONST1_RTX (<MODE>mode);
3144 })
3145
3146 (define_expand "movtf"
3147   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148         (match_operand:TF 1 "nonimmediate_operand" ""))]
3149   "TARGET_64BIT"
3150 {
3151   ix86_expand_move (TFmode, operands);
3152   DONE;
3153 })
3154
3155 (define_insn "*movtf_internal"
3156   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3158   "TARGET_64BIT
3159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3160 {
3161   switch (which_alternative)
3162     {
3163     case 0:
3164     case 1:
3165       return "#";
3166     case 2:
3167       if (get_attr_mode (insn) == MODE_V4SF)
3168         return "xorps\t%0, %0";
3169       else
3170         return "pxor\t%0, %0";
3171     case 3:
3172     case 4:
3173       if (get_attr_mode (insn) == MODE_V4SF)
3174         return "movaps\t{%1, %0|%0, %1}";
3175       else
3176         return "movdqa\t{%1, %0|%0, %1}";
3177     default:
3178       gcc_unreachable ();
3179     }
3180 }
3181   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3182    (set (attr "mode")
3183         (cond [(eq_attr "alternative" "2,3")
3184                  (if_then_else
3185                    (ne (symbol_ref "optimize_size")
3186                        (const_int 0))
3187                    (const_string "V4SF")
3188                    (const_string "TI"))
3189                (eq_attr "alternative" "4")
3190                  (if_then_else
3191                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3192                             (const_int 0))
3193                         (ne (symbol_ref "optimize_size")
3194                             (const_int 0)))
3195                    (const_string "V4SF")
3196                    (const_string "TI"))]
3197                (const_string "DI")))])
3198
3199 (define_split
3200   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201         (match_operand:TF 1 "general_operand" ""))]
3202   "reload_completed && !SSE_REG_P (operands[0])
3203    && !SSE_REG_P (operands[1])"
3204   [(const_int 0)]
3205   "ix86_split_long_move (operands); DONE;")
3206 \f
3207 ;; Zero extension instructions
3208
3209 (define_expand "zero_extendhisi2"
3210   [(set (match_operand:SI 0 "register_operand" "")
3211      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3212   ""
3213 {
3214   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3215     {
3216       operands[1] = force_reg (HImode, operands[1]);
3217       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3218       DONE;
3219     }
3220 })
3221
3222 (define_insn "zero_extendhisi2_and"
3223   [(set (match_operand:SI 0 "register_operand" "=r")
3224      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225    (clobber (reg:CC FLAGS_REG))]
3226   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3227   "#"
3228   [(set_attr "type" "alu1")
3229    (set_attr "mode" "SI")])
3230
3231 (define_split
3232   [(set (match_operand:SI 0 "register_operand" "")
3233         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234    (clobber (reg:CC FLAGS_REG))]
3235   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237               (clobber (reg:CC FLAGS_REG))])]
3238   "")
3239
3240 (define_insn "*zero_extendhisi2_movzwl"
3241   [(set (match_operand:SI 0 "register_operand" "=r")
3242      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244   "movz{wl|x}\t{%1, %0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "SI")])
3247
3248 (define_expand "zero_extendqihi2"
3249   [(parallel
3250     [(set (match_operand:HI 0 "register_operand" "")
3251        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252      (clobber (reg:CC FLAGS_REG))])]
3253   ""
3254   "")
3255
3256 (define_insn "*zero_extendqihi2_and"
3257   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259    (clobber (reg:CC FLAGS_REG))]
3260   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3261   "#"
3262   [(set_attr "type" "alu1")
3263    (set_attr "mode" "HI")])
3264
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266   [(set (match_operand:HI 0 "register_operand" "=r,r")
3267      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268    (clobber (reg:CC FLAGS_REG))]
3269   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3270   "#"
3271   [(set_attr "type" "imovx,alu1")
3272    (set_attr "mode" "HI")])
3273
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276   [(set (match_operand:HI 0 "register_operand" "=r")
3277      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "SI")])
3282
3283 ;; For the movzbw case strip only the clobber
3284 (define_split
3285   [(set (match_operand:HI 0 "register_operand" "")
3286         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))]
3288   "reload_completed
3289    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291   [(set (match_operand:HI 0 "register_operand" "")
3292         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3293
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3296 (define_split
3297   [(set (match_operand:HI 0 "register_operand" "")
3298         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299    (clobber (reg:CC FLAGS_REG))]
3300   "reload_completed
3301    && ANY_QI_REG_P (operands[0])
3302    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304   [(set (match_dup 0) (const_int 0))
3305    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306   "operands[2] = gen_lowpart (QImode, operands[0]);")
3307
3308 ;; Rest is handled by single and.
3309 (define_split
3310   [(set (match_operand:HI 0 "register_operand" "")
3311         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312    (clobber (reg:CC FLAGS_REG))]
3313   "reload_completed
3314    && true_regnum (operands[0]) == true_regnum (operands[1])"
3315   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316               (clobber (reg:CC FLAGS_REG))])]
3317   "")
3318
3319 (define_expand "zero_extendqisi2"
3320   [(parallel
3321     [(set (match_operand:SI 0 "register_operand" "")
3322        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323      (clobber (reg:CC FLAGS_REG))])]
3324   ""
3325   "")
3326
3327 (define_insn "*zero_extendqisi2_and"
3328   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330    (clobber (reg:CC FLAGS_REG))]
3331   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3332   "#"
3333   [(set_attr "type" "alu1")
3334    (set_attr "mode" "SI")])
3335
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337   [(set (match_operand:SI 0 "register_operand" "=r,r")
3338      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339    (clobber (reg:CC FLAGS_REG))]
3340   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3341   "#"
3342   [(set_attr "type" "imovx,alu1")
3343    (set_attr "mode" "SI")])
3344
3345 (define_insn "*zero_extendqisi2_movzbw"
3346   [(set (match_operand:SI 0 "register_operand" "=r")
3347      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349   "movz{bl|x}\t{%1, %0|%0, %1}"
3350   [(set_attr "type" "imovx")
3351    (set_attr "mode" "SI")])
3352
3353 ;; For the movzbl case strip only the clobber
3354 (define_split
3355   [(set (match_operand:SI 0 "register_operand" "")
3356         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357    (clobber (reg:CC FLAGS_REG))]
3358   "reload_completed
3359    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3361   [(set (match_dup 0)
3362         (zero_extend:SI (match_dup 1)))])
3363
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3366 (define_split
3367   [(set (match_operand:SI 0 "register_operand" "")
3368         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369    (clobber (reg:CC FLAGS_REG))]
3370   "reload_completed
3371    && ANY_QI_REG_P (operands[0])
3372    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375   [(set (match_dup 0) (const_int 0))
3376    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377   "operands[2] = gen_lowpart (QImode, operands[0]);")
3378
3379 ;; Rest is handled by single and.
3380 (define_split
3381   [(set (match_operand:SI 0 "register_operand" "")
3382         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383    (clobber (reg:CC FLAGS_REG))]
3384   "reload_completed
3385    && true_regnum (operands[0]) == true_regnum (operands[1])"
3386   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387               (clobber (reg:CC FLAGS_REG))])]
3388   "")
3389
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392   [(set (match_operand:DI 0 "register_operand" "=r")
3393      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3394   ""
3395 {
3396   if (!TARGET_64BIT)
3397     {
3398       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3399       DONE;
3400     }
3401 })
3402
3403 (define_insn "zero_extendsidi2_32"
3404   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3405         (zero_extend:DI
3406          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m ,r   ,m")))
3407    (clobber (reg:CC FLAGS_REG))]
3408   "!TARGET_64BIT"
3409   "@
3410    #
3411    #
3412    #
3413    movd\t{%1, %0|%0, %1}
3414    movd\t{%1, %0|%0, %1}
3415    movd\t{%1, %0|%0, %1}
3416    movd\t{%1, %0|%0, %1}"
3417   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3419
3420 (define_insn "zero_extendsidi2_rex64"
3421   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3422      (zero_extend:DI
3423        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m ,r   ,m")))]
3424   "TARGET_64BIT"
3425   "@
3426    mov\t{%k1, %k0|%k0, %k1}
3427    #
3428    movd\t{%1, %0|%0, %1}
3429    movd\t{%1, %0|%0, %1}
3430    movd\t{%1, %0|%0, %1}
3431    movd\t{%1, %0|%0, %1}"
3432   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3434
3435 (define_split
3436   [(set (match_operand:DI 0 "memory_operand" "")
3437      (zero_extend:DI (match_dup 0)))]
3438   "TARGET_64BIT"
3439   [(set (match_dup 4) (const_int 0))]
3440   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441
3442 (define_split
3443   [(set (match_operand:DI 0 "register_operand" "")
3444         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445    (clobber (reg:CC FLAGS_REG))]
3446   "!TARGET_64BIT && reload_completed
3447    && true_regnum (operands[0]) == true_regnum (operands[1])"
3448   [(set (match_dup 4) (const_int 0))]
3449   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3450
3451 (define_split
3452   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "!TARGET_64BIT && reload_completed
3456    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457   [(set (match_dup 3) (match_dup 1))
3458    (set (match_dup 4) (const_int 0))]
3459   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3460
3461 (define_insn "zero_extendhidi2"
3462   [(set (match_operand:DI 0 "register_operand" "=r")
3463      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3464   "TARGET_64BIT"
3465   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466   [(set_attr "type" "imovx")
3467    (set_attr "mode" "DI")])
3468
3469 (define_insn "zero_extendqidi2"
3470   [(set (match_operand:DI 0 "register_operand" "=r")
3471      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3472   "TARGET_64BIT"
3473   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474   [(set_attr "type" "imovx")
3475    (set_attr "mode" "DI")])
3476 \f
3477 ;; Sign extension instructions
3478
3479 (define_expand "extendsidi2"
3480   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482               (clobber (reg:CC FLAGS_REG))
3483               (clobber (match_scratch:SI 2 ""))])]
3484   ""
3485 {
3486   if (TARGET_64BIT)
3487     {
3488       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3489       DONE;
3490     }
3491 })
3492
3493 (define_insn "*extendsidi2_1"
3494   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496    (clobber (reg:CC FLAGS_REG))
3497    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3498   "!TARGET_64BIT"
3499   "#")
3500
3501 (define_insn "extendsidi2_rex64"
3502   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3504   "TARGET_64BIT"
3505   "@
3506    {cltq|cdqe}
3507    movs{lq|x}\t{%1,%0|%0, %1}"
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "DI")
3510    (set_attr "prefix_0f" "0")
3511    (set_attr "modrm" "0,1")])
3512
3513 (define_insn "extendhidi2"
3514   [(set (match_operand:DI 0 "register_operand" "=r")
3515         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3516   "TARGET_64BIT"
3517   "movs{wq|x}\t{%1,%0|%0, %1}"
3518   [(set_attr "type" "imovx")
3519    (set_attr "mode" "DI")])
3520
3521 (define_insn "extendqidi2"
3522   [(set (match_operand:DI 0 "register_operand" "=r")
3523         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524   "TARGET_64BIT"
3525   "movs{bq|x}\t{%1,%0|%0, %1}"
3526    [(set_attr "type" "imovx")
3527     (set_attr "mode" "DI")])
3528
3529 ;; Extend to memory case when source register does die.
3530 (define_split
3531   [(set (match_operand:DI 0 "memory_operand" "")
3532         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533    (clobber (reg:CC FLAGS_REG))
3534    (clobber (match_operand:SI 2 "register_operand" ""))]
3535   "(reload_completed
3536     && dead_or_set_p (insn, operands[1])
3537     && !reg_mentioned_p (operands[1], operands[0]))"
3538   [(set (match_dup 3) (match_dup 1))
3539    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540               (clobber (reg:CC FLAGS_REG))])
3541    (set (match_dup 4) (match_dup 1))]
3542   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3543
3544 ;; Extend to memory case when source register does not die.
3545 (define_split
3546   [(set (match_operand:DI 0 "memory_operand" "")
3547         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548    (clobber (reg:CC FLAGS_REG))
3549    (clobber (match_operand:SI 2 "register_operand" ""))]
3550   "reload_completed"
3551   [(const_int 0)]
3552 {
3553   split_di (&operands[0], 1, &operands[3], &operands[4]);
3554
3555   emit_move_insn (operands[3], operands[1]);
3556
3557   /* Generate a cltd if possible and doing so it profitable.  */
3558   if (true_regnum (operands[1]) == 0
3559       && true_regnum (operands[2]) == 1
3560       && (optimize_size || TARGET_USE_CLTD))
3561     {
3562       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3563     }
3564   else
3565     {
3566       emit_move_insn (operands[2], operands[1]);
3567       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3568     }
3569   emit_move_insn (operands[4], operands[2]);
3570   DONE;
3571 })
3572
3573 ;; Extend to register case.  Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3575 (define_split
3576   [(set (match_operand:DI 0 "register_operand" "")
3577         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578    (clobber (reg:CC FLAGS_REG))
3579    (clobber (match_scratch:SI 2 ""))]
3580   "reload_completed"
3581   [(const_int 0)]
3582 {
3583   split_di (&operands[0], 1, &operands[3], &operands[4]);
3584
3585   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586     emit_move_insn (operands[3], operands[1]);
3587
3588   /* Generate a cltd if possible and doing so it profitable.  */
3589   if (true_regnum (operands[3]) == 0
3590       && (optimize_size || TARGET_USE_CLTD))
3591     {
3592       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3593       DONE;
3594     }
3595
3596   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597     emit_move_insn (operands[4], operands[1]);
3598
3599   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3600   DONE;
3601 })
3602
3603 (define_insn "extendhisi2"
3604   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3606   ""
3607 {
3608   switch (get_attr_prefix_0f (insn))
3609     {
3610     case 0:
3611       return "{cwtl|cwde}";
3612     default:
3613       return "movs{wl|x}\t{%1,%0|%0, %1}";
3614     }
3615 }
3616   [(set_attr "type" "imovx")
3617    (set_attr "mode" "SI")
3618    (set (attr "prefix_0f")
3619      ;; movsx is short decodable while cwtl is vector decoded.
3620      (if_then_else (and (eq_attr "cpu" "!k6")
3621                         (eq_attr "alternative" "0"))
3622         (const_string "0")
3623         (const_string "1")))
3624    (set (attr "modrm")
3625      (if_then_else (eq_attr "prefix_0f" "0")
3626         (const_string "0")
3627         (const_string "1")))])
3628
3629 (define_insn "*extendhisi2_zext"
3630   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3631         (zero_extend:DI
3632           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3633   "TARGET_64BIT"
3634 {
3635   switch (get_attr_prefix_0f (insn))
3636     {
3637     case 0:
3638       return "{cwtl|cwde}";
3639     default:
3640       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3641     }
3642 }
3643   [(set_attr "type" "imovx")
3644    (set_attr "mode" "SI")
3645    (set (attr "prefix_0f")
3646      ;; movsx is short decodable while cwtl is vector decoded.
3647      (if_then_else (and (eq_attr "cpu" "!k6")
3648                         (eq_attr "alternative" "0"))
3649         (const_string "0")
3650         (const_string "1")))
3651    (set (attr "modrm")
3652      (if_then_else (eq_attr "prefix_0f" "0")
3653         (const_string "0")
3654         (const_string "1")))])
3655
3656 (define_insn "extendqihi2"
3657   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3659   ""
3660 {
3661   switch (get_attr_prefix_0f (insn))
3662     {
3663     case 0:
3664       return "{cbtw|cbw}";
3665     default:
3666       return "movs{bw|x}\t{%1,%0|%0, %1}";
3667     }
3668 }
3669   [(set_attr "type" "imovx")
3670    (set_attr "mode" "HI")
3671    (set (attr "prefix_0f")
3672      ;; movsx is short decodable while cwtl is vector decoded.
3673      (if_then_else (and (eq_attr "cpu" "!k6")
3674                         (eq_attr "alternative" "0"))
3675         (const_string "0")
3676         (const_string "1")))
3677    (set (attr "modrm")
3678      (if_then_else (eq_attr "prefix_0f" "0")
3679         (const_string "0")
3680         (const_string "1")))])
3681
3682 (define_insn "extendqisi2"
3683   [(set (match_operand:SI 0 "register_operand" "=r")
3684         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3685   ""
3686   "movs{bl|x}\t{%1,%0|%0, %1}"
3687    [(set_attr "type" "imovx")
3688     (set_attr "mode" "SI")])
3689
3690 (define_insn "*extendqisi2_zext"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692         (zero_extend:DI
3693           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3694   "TARGET_64BIT"
3695   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696    [(set_attr "type" "imovx")
3697     (set_attr "mode" "SI")])
3698 \f
3699 ;; Conversions between float and double.
3700
3701 ;; These are all no-ops in the model used for the 80387.  So just
3702 ;; emit moves.
3703
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706   [(set (match_operand:DF 0 "push_operand" "=<")
3707         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3708   "0"
3709   "#")
3710
3711 (define_split
3712   [(set (match_operand:DF 0 "push_operand" "")
3713         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3714   "!TARGET_64BIT"
3715   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3717
3718 (define_split
3719   [(set (match_operand:DF 0 "push_operand" "")
3720         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3721   "TARGET_64BIT"
3722   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3724
3725 (define_insn "*dummy_extendsfxf2"
3726   [(set (match_operand:XF 0 "push_operand" "=<")
3727         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3728   "0"
3729   "#")
3730
3731 (define_split
3732   [(set (match_operand:XF 0 "push_operand" "")
3733         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3734   ""
3735   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3738
3739 (define_split
3740   [(set (match_operand:XF 0 "push_operand" "")
3741         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3742   "TARGET_64BIT"
3743   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3746
3747 (define_split
3748   [(set (match_operand:XF 0 "push_operand" "")
3749         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3750   ""
3751   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3754
3755 (define_split
3756   [(set (match_operand:XF 0 "push_operand" "")
3757         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3758   "TARGET_64BIT"
3759   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3762
3763 (define_expand "extendsfdf2"
3764   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3767 {
3768   /* ??? Needed for compress_float_constant since all fp constants
3769      are LEGITIMATE_CONSTANT_P.  */
3770   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3771     {
3772       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773           && standard_80387_constant_p (operands[1]) > 0)
3774         {
3775           operands[1] = simplify_const_unary_operation
3776             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777           emit_move_insn_1 (operands[0], operands[1]);
3778           DONE;
3779         }
3780       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3781     }
3782 })
3783
3784 (define_insn "*extendsfdf2_mixed"
3785   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3786         (float_extend:DF
3787           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3789 {
3790   switch (which_alternative)
3791     {
3792     case 0:
3793       return output_387_reg_move (insn, operands);
3794
3795     case 1:
3796       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797         return "fstp%z0\t%y0";
3798       else
3799         return "fst%z0\t%y0";
3800
3801     case 2:
3802       return "cvtss2sd\t{%1, %0|%0, %1}";
3803
3804     default:
3805       gcc_unreachable ();
3806     }
3807 }
3808   [(set_attr "type" "fmov,fmov,ssecvt")
3809    (set_attr "mode" "SF,XF,DF")])
3810
3811 (define_insn "*extendsfdf2_sse"
3812   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814   "TARGET_SSE2 && TARGET_SSE_MATH"
3815   "cvtss2sd\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "ssecvt")
3817    (set_attr "mode" "DF")])
3818
3819 (define_insn "*extendsfdf2_i387"
3820   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3822   "TARGET_80387"
3823 {
3824   switch (which_alternative)
3825     {
3826     case 0:
3827       return output_387_reg_move (insn, operands);
3828
3829     case 1:
3830       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831         return "fstp%z0\t%y0";
3832       else
3833         return "fst%z0\t%y0";
3834
3835     default:
3836       gcc_unreachable ();
3837     }
3838 }
3839   [(set_attr "type" "fmov")
3840    (set_attr "mode" "SF,XF")])
3841
3842 (define_expand "extendsfxf2"
3843   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3845   "TARGET_80387"
3846 {
3847   /* ??? Needed for compress_float_constant since all fp constants
3848      are LEGITIMATE_CONSTANT_P.  */
3849   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3850     {
3851       if (standard_80387_constant_p (operands[1]) > 0)
3852         {
3853           operands[1] = simplify_const_unary_operation
3854             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855           emit_move_insn_1 (operands[0], operands[1]);
3856           DONE;
3857         }
3858       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3859     }
3860 })
3861
3862 (define_insn "*extendsfxf2_i387"
3863   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3865   "TARGET_80387"
3866 {
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       return output_387_reg_move (insn, operands);
3871
3872     case 1:
3873       /* There is no non-popping store to memory for XFmode.  So if
3874          we need one, follow the store with a load.  */
3875       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876         return "fstp%z0\t%y0";
3877       else
3878         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3879
3880     default:
3881       gcc_unreachable ();
3882     }
3883 }
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF,XF")])
3886
3887 (define_expand "extenddfxf2"
3888   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3890   "TARGET_80387"
3891 {
3892   /* ??? Needed for compress_float_constant since all fp constants
3893      are LEGITIMATE_CONSTANT_P.  */
3894   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3895     {
3896       if (standard_80387_constant_p (operands[1]) > 0)
3897         {
3898           operands[1] = simplify_const_unary_operation
3899             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900           emit_move_insn_1 (operands[0], operands[1]);
3901           DONE;
3902         }
3903       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3904     }
3905 })
3906
3907 (define_insn "*extenddfxf2_i387"
3908   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3910   "TARGET_80387"
3911 {
3912   switch (which_alternative)
3913     {
3914     case 0:
3915       return output_387_reg_move (insn, operands);
3916
3917     case 1:
3918       /* There is no non-popping store to memory for XFmode.  So if
3919          we need one, follow the store with a load.  */
3920       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3922       else
3923         return "fstp%z0\t%y0";
3924
3925     default:
3926       gcc_unreachable ();
3927     }
3928 }
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "DF,XF")])
3931
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case.  Otherwise this is just like a simple move
3935 ;; insn.  So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3937
3938 ;; Conversion from DFmode to SFmode.
3939
3940 (define_expand "truncdfsf2"
3941   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3942         (float_truncate:SF
3943           (match_operand:DF 1 "nonimmediate_operand" "")))]
3944   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3945 {
3946   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3947     ;
3948   else if (flag_unsafe_math_optimizations)
3949     ;
3950   else
3951     {
3952       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3954       DONE;
3955     }
3956 })
3957
3958 (define_expand "truncdfsf2_with_temp"
3959   [(parallel [(set (match_operand:SF 0 "" "")
3960                    (float_truncate:SF (match_operand:DF 1 "" "")))
3961               (clobber (match_operand:SF 2 "" ""))])]
3962   "")
3963
3964 (define_insn "*truncdfsf_fast_mixed"
3965   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3966         (float_truncate:SF
3967           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3969 {
3970   switch (which_alternative)
3971     {
3972     case 0:
3973       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974         return "fstp%z0\t%y0";
3975       else
3976         return "fst%z0\t%y0";
3977     case 1:
3978       return output_387_reg_move (insn, operands);
3979     case 2:
3980       return "cvtsd2ss\t{%1, %0|%0, %1}";
3981     default:
3982       gcc_unreachable ();
3983     }
3984 }
3985   [(set_attr "type" "fmov,fmov,ssecvt")
3986    (set_attr "mode" "SF")])
3987
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3992         (float_truncate:SF
3993           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994   "TARGET_SSE2 && TARGET_SSE_MATH"
3995   "cvtsd2ss\t{%1, %0|%0, %1}"
3996   [(set_attr "type" "ssecvt")
3997    (set_attr "mode" "SF")])
3998
3999 (define_insn "*truncdfsf_fast_i387"
4000   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4001         (float_truncate:SF
4002           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003   "TARGET_80387 && flag_unsafe_math_optimizations"
4004   "* return output_387_reg_move (insn, operands);"
4005   [(set_attr "type" "fmov")
4006    (set_attr "mode" "SF")])
4007
4008 (define_insn "*truncdfsf_mixed"
4009   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4010         (float_truncate:SF
4011           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4012    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4013   "TARGET_MIX_SSE_I387"
4014 {
4015   switch (which_alternative)
4016     {
4017     case 0:
4018       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019         return "fstp%z0\t%y0";
4020       else
4021         return "fst%z0\t%y0";
4022     case 1:
4023       return "#";
4024     case 2:
4025       return "cvtsd2ss\t{%1, %0|%0, %1}";
4026     default:
4027       gcc_unreachable ();
4028     }
4029 }
4030   [(set_attr "type" "fmov,multi,ssecvt")
4031    (set_attr "unit" "*,i387,*")
4032    (set_attr "mode" "SF")])
4033
4034 (define_insn "*truncdfsf_i387"
4035   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4036         (float_truncate:SF
4037           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4039   "TARGET_80387"
4040 {
4041   switch (which_alternative)
4042     {
4043     case 0:
4044       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045         return "fstp%z0\t%y0";
4046       else
4047         return "fst%z0\t%y0";
4048     case 1:
4049       return "#";
4050     default:
4051       gcc_unreachable ();
4052     }
4053 }
4054   [(set_attr "type" "fmov,multi")
4055    (set_attr "unit" "*,i387")
4056    (set_attr "mode" "SF")])
4057
4058 (define_insn "*truncdfsf2_i387_1"
4059   [(set (match_operand:SF 0 "memory_operand" "=m")
4060         (float_truncate:SF
4061           (match_operand:DF 1 "register_operand" "f")))]
4062   "TARGET_80387
4063    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064    && !TARGET_MIX_SSE_I387"
4065 {
4066   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067     return "fstp%z0\t%y0";
4068   else
4069     return "fst%z0\t%y0";
4070 }
4071   [(set_attr "type" "fmov")
4072    (set_attr "mode" "SF")])
4073
4074 (define_split
4075   [(set (match_operand:SF 0 "register_operand" "")
4076         (float_truncate:SF
4077          (match_operand:DF 1 "fp_register_operand" "")))
4078    (clobber (match_operand 2 "" ""))]
4079   "reload_completed"
4080   [(set (match_dup 2) (match_dup 1))
4081    (set (match_dup 0) (match_dup 2))]
4082 {
4083   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4084 })
4085
4086 ;; Conversion from XFmode to SFmode.
4087
4088 (define_expand "truncxfsf2"
4089   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4090                    (float_truncate:SF
4091                     (match_operand:XF 1 "register_operand" "")))
4092               (clobber (match_dup 2))])]
4093   "TARGET_80387"
4094 {
4095   if (flag_unsafe_math_optimizations)
4096     {
4097       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099       if (reg != operands[0])
4100         emit_move_insn (operands[0], reg);
4101       DONE;
4102     }
4103   else
4104     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4105 })
4106
4107 (define_insn "*truncxfsf2_mixed"
4108   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4109         (float_truncate:SF
4110          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4112   "TARGET_80387"
4113 {
4114   gcc_assert (!which_alternative);
4115   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116     return "fstp%z0\t%y0";
4117   else
4118     return "fst%z0\t%y0";
4119 }
4120   [(set_attr "type" "fmov,multi,multi,multi")
4121    (set_attr "unit" "*,i387,i387,i387")
4122    (set_attr "mode" "SF")])
4123
4124 (define_insn "truncxfsf2_i387_noop"
4125   [(set (match_operand:SF 0 "register_operand" "=f")
4126         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127   "TARGET_80387 && flag_unsafe_math_optimizations"
4128   "* return output_387_reg_move (insn, operands);"
4129   [(set_attr "type" "fmov")
4130    (set_attr "mode" "SF")])
4131
4132 (define_insn "*truncxfsf2_i387"
4133   [(set (match_operand:SF 0 "memory_operand" "=m")
4134         (float_truncate:SF
4135          (match_operand:XF 1 "register_operand" "f")))]
4136   "TARGET_80387"
4137 {
4138   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139     return "fstp%z0\t%y0";
4140   else
4141     return "fst%z0\t%y0";
4142 }
4143   [(set_attr "type" "fmov")
4144    (set_attr "mode" "SF")])
4145
4146 (define_split
4147   [(set (match_operand:SF 0 "register_operand" "")
4148         (float_truncate:SF
4149          (match_operand:XF 1 "register_operand" "")))
4150    (clobber (match_operand:SF 2 "memory_operand" ""))]
4151   "TARGET_80387 && reload_completed"
4152   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153    (set (match_dup 0) (match_dup 2))]
4154   "")
4155
4156 (define_split
4157   [(set (match_operand:SF 0 "memory_operand" "")
4158         (float_truncate:SF
4159          (match_operand:XF 1 "register_operand" "")))
4160    (clobber (match_operand:SF 2 "memory_operand" ""))]
4161   "TARGET_80387"
4162   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4163   "")
4164
4165 ;; Conversion from XFmode to DFmode.
4166
4167 (define_expand "truncxfdf2"
4168   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4169                    (float_truncate:DF
4170                     (match_operand:XF 1 "register_operand" "")))
4171               (clobber (match_dup 2))])]
4172   "TARGET_80387"
4173 {
4174   if (flag_unsafe_math_optimizations)
4175     {
4176       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178       if (reg != operands[0])
4179         emit_move_insn (operands[0], reg);
4180       DONE;
4181     }
4182   else
4183     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4184 })
4185
4186 (define_insn "*truncxfdf2_mixed"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4188         (float_truncate:DF
4189          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4191   "TARGET_80387"
4192 {
4193   gcc_assert (!which_alternative);
4194   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195     return "fstp%z0\t%y0";
4196   else
4197     return "fst%z0\t%y0";
4198 }
4199   [(set_attr "type" "fmov,multi,multi,multi")
4200    (set_attr "unit" "*,i387,i387,i387")
4201    (set_attr "mode" "DF")])
4202
4203 (define_insn "truncxfdf2_i387_noop"
4204   [(set (match_operand:DF 0 "register_operand" "=f")
4205         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206   "TARGET_80387 && flag_unsafe_math_optimizations"
4207   "* return output_387_reg_move (insn, operands);"
4208   [(set_attr "type" "fmov")
4209    (set_attr "mode" "DF")])
4210
4211 (define_insn "*truncxfdf2_i387"
4212   [(set (match_operand:DF 0 "memory_operand" "=m")
4213         (float_truncate:DF
4214           (match_operand:XF 1 "register_operand" "f")))]
4215   "TARGET_80387"
4216 {
4217   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218     return "fstp%z0\t%y0";
4219   else
4220     return "fst%z0\t%y0";
4221 }
4222   [(set_attr "type" "fmov")
4223    (set_attr "mode" "DF")])
4224
4225 (define_split
4226   [(set (match_operand:DF 0 "register_operand" "")
4227         (float_truncate:DF
4228          (match_operand:XF 1 "register_operand" "")))
4229    (clobber (match_operand:DF 2 "memory_operand" ""))]
4230   "TARGET_80387 && reload_completed"
4231   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232    (set (match_dup 0) (match_dup 2))]
4233   "")
4234
4235 (define_split
4236   [(set (match_operand:DF 0 "memory_operand" "")
4237         (float_truncate:DF
4238          (match_operand:XF 1 "register_operand" "")))
4239    (clobber (match_operand:DF 2 "memory_operand" ""))]
4240   "TARGET_80387"
4241   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4242   "")
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387"
4251 {
4252   if (TARGET_FISTTP)
4253    {
4254      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255      DONE;
4256    }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265   if (TARGET_FISTTP
4266       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267    {
4268      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4271   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272    {
4273      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275      if (out != operands[0])
4276         emit_move_insn (operands[0], out);
4277      DONE;
4278    }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302   if (TARGET_FISTTP
4303       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387
4325    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327   if (TARGET_FISTTP)
4328    {
4329      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330      DONE;
4331    }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))]
4339   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4340    && TARGET_KEEPS_VECTOR_ALIGNED_STACK && !optimize_size"
4341 {
4342   ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
4343   DONE;
4344 })
4345
4346 ;; Unsigned conversion to HImode.
4347 ;; Without these patterns, we'll try the unsigned SI conversion which
4348 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4349
4350 (define_expand "fixuns_truncsfhi2"
4351   [(set (match_dup 2)
4352         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4353    (set (match_operand:HI 0 "nonimmediate_operand" "")
4354         (subreg:HI (match_dup 2) 0))]
4355   "TARGET_SSE_MATH"
4356   "operands[2] = gen_reg_rtx (SImode);")
4357
4358 (define_expand "fixuns_truncdfhi2"
4359   [(set (match_dup 2)
4360         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4361    (set (match_operand:HI 0 "nonimmediate_operand" "")
4362         (subreg:HI (match_dup 2) 0))]
4363   "TARGET_SSE_MATH"
4364   "operands[2] = gen_reg_rtx (SImode);")
4365
4366 ;; When SSE is available, it is always faster to use it!
4367 (define_insn "fix_truncsfdi_sse"
4368   [(set (match_operand:DI 0 "register_operand" "=r,r")
4369         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4370   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4371   "cvttss2si{q}\t{%1, %0|%0, %1}"
4372   [(set_attr "type" "sseicvt")
4373    (set_attr "mode" "SF")
4374    (set_attr "athlon_decode" "double,vector")
4375    (set_attr "amdfam10_decode" "double,double")])
4376
4377 (define_insn "fix_truncdfdi_sse"
4378   [(set (match_operand:DI 0 "register_operand" "=r,r")
4379         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4380   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4381   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4382   [(set_attr "type" "sseicvt")
4383    (set_attr "mode" "DF")
4384    (set_attr "athlon_decode" "double,vector")
4385    (set_attr "amdfam10_decode" "double,double")])
4386
4387 (define_insn "fix_truncsfsi_sse"
4388   [(set (match_operand:SI 0 "register_operand" "=r,r")
4389         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4390   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4391   "cvttss2si\t{%1, %0|%0, %1}"
4392   [(set_attr "type" "sseicvt")
4393    (set_attr "mode" "DF")
4394    (set_attr "athlon_decode" "double,vector")
4395    (set_attr "amdfam10_decode" "double,double")])
4396
4397 (define_insn "fix_truncdfsi_sse"
4398   [(set (match_operand:SI 0 "register_operand" "=r,r")
4399         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4400   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401   "cvttsd2si\t{%1, %0|%0, %1}"
4402   [(set_attr "type" "sseicvt")
4403    (set_attr "mode" "DF")
4404    (set_attr "athlon_decode" "double,vector")
4405    (set_attr "amdfam10_decode" "double,double")])
4406
4407 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4408 (define_peephole2
4409   [(set (match_operand:DF 0 "register_operand" "")
4410         (match_operand:DF 1 "memory_operand" ""))
4411    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4412         (fix:SSEMODEI24 (match_dup 0)))]
4413   "!TARGET_K8
4414    && peep2_reg_dead_p (2, operands[0])"
4415   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4416   "")
4417
4418 (define_peephole2
4419   [(set (match_operand:SF 0 "register_operand" "")
4420         (match_operand:SF 1 "memory_operand" ""))
4421    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422         (fix:SSEMODEI24 (match_dup 0)))]
4423   "!TARGET_K8
4424    && peep2_reg_dead_p (2, operands[0])"
4425   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4426   "")
4427
4428 ;; Avoid vector decoded forms of the instruction.
4429 (define_peephole2
4430   [(match_scratch:DF 2 "Y")
4431    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4434   [(set (match_dup 2) (match_dup 1))
4435    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4436   "")
4437
4438 (define_peephole2
4439   [(match_scratch:SF 2 "x")
4440    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4441         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4442   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4443   [(set (match_dup 2) (match_dup 1))
4444    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4445   "")
4446
4447 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4448   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4449         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4450   "TARGET_FISTTP
4451    && FLOAT_MODE_P (GET_MODE (operands[1]))
4452    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4453          && (TARGET_64BIT || <MODE>mode != DImode))
4454         && TARGET_SSE_MATH)
4455    && !(reload_completed || reload_in_progress)"
4456   "#"
4457   "&& 1"
4458   [(const_int 0)]
4459 {
4460   if (memory_operand (operands[0], VOIDmode))
4461     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4462   else
4463     {
4464       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4465       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4466                                                             operands[1],
4467                                                             operands[2]));
4468     }
4469   DONE;
4470 }
4471   [(set_attr "type" "fisttp")
4472    (set_attr "mode" "<MODE>")])
4473
4474 (define_insn "fix_trunc<mode>_i387_fisttp"
4475   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4476         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4477    (clobber (match_scratch:XF 2 "=&1f"))]
4478   "TARGET_FISTTP
4479    && FLOAT_MODE_P (GET_MODE (operands[1]))
4480    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4481          && (TARGET_64BIT || <MODE>mode != DImode))
4482         && TARGET_SSE_MATH)"
4483   "* return output_fix_trunc (insn, operands, 1);"
4484   [(set_attr "type" "fisttp")
4485    (set_attr "mode" "<MODE>")])
4486
4487 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4488   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4489         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4490    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4491    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4492   "TARGET_FISTTP
4493    && FLOAT_MODE_P (GET_MODE (operands[1]))
4494    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495         && (TARGET_64BIT || <MODE>mode != DImode))
4496         && TARGET_SSE_MATH)"
4497   "#"
4498   [(set_attr "type" "fisttp")
4499    (set_attr "mode" "<MODE>")])
4500
4501 (define_split
4502   [(set (match_operand:X87MODEI 0 "register_operand" "")
4503         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4504    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4505    (clobber (match_scratch 3 ""))]
4506   "reload_completed"
4507   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4508               (clobber (match_dup 3))])
4509    (set (match_dup 0) (match_dup 2))]
4510   "")
4511
4512 (define_split
4513   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4514         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4515    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4516    (clobber (match_scratch 3 ""))]
4517   "reload_completed"
4518   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4519               (clobber (match_dup 3))])]
4520   "")
4521
4522 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4523 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4524 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4525 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4526 ;; function in i386.c.
4527 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4528   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4529         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4530    (clobber (reg:CC FLAGS_REG))]
4531   "TARGET_80387 && !TARGET_FISTTP
4532    && FLOAT_MODE_P (GET_MODE (operands[1]))
4533    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534          && (TARGET_64BIT || <MODE>mode != DImode))
4535    && !(reload_completed || reload_in_progress)"
4536   "#"
4537   "&& 1"
4538   [(const_int 0)]
4539 {
4540   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4541
4542   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4543   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4544   if (memory_operand (operands[0], VOIDmode))
4545     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4546                                          operands[2], operands[3]));
4547   else
4548     {
4549       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4550       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4551                                                      operands[2], operands[3],
4552                                                      operands[4]));
4553     }
4554   DONE;
4555 }
4556   [(set_attr "type" "fistp")
4557    (set_attr "i387_cw" "trunc")
4558    (set_attr "mode" "<MODE>")])
4559
4560 (define_insn "fix_truncdi_i387"
4561   [(set (match_operand:DI 0 "memory_operand" "=m")
4562         (fix:DI (match_operand 1 "register_operand" "f")))
4563    (use (match_operand:HI 2 "memory_operand" "m"))
4564    (use (match_operand:HI 3 "memory_operand" "m"))
4565    (clobber (match_scratch:XF 4 "=&1f"))]
4566   "TARGET_80387 && !TARGET_FISTTP
4567    && FLOAT_MODE_P (GET_MODE (operands[1]))
4568    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4569   "* return output_fix_trunc (insn, operands, 0);"
4570   [(set_attr "type" "fistp")
4571    (set_attr "i387_cw" "trunc")
4572    (set_attr "mode" "DI")])
4573
4574 (define_insn "fix_truncdi_i387_with_temp"
4575   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4576         (fix:DI (match_operand 1 "register_operand" "f,f")))
4577    (use (match_operand:HI 2 "memory_operand" "m,m"))
4578    (use (match_operand:HI 3 "memory_operand" "m,m"))
4579    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4580    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4581   "TARGET_80387 && !TARGET_FISTTP
4582    && FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4584   "#"
4585   [(set_attr "type" "fistp")
4586    (set_attr "i387_cw" "trunc")
4587    (set_attr "mode" "DI")])
4588
4589 (define_split
4590   [(set (match_operand:DI 0 "register_operand" "")
4591         (fix:DI (match_operand 1 "register_operand" "")))
4592    (use (match_operand:HI 2 "memory_operand" ""))
4593    (use (match_operand:HI 3 "memory_operand" ""))
4594    (clobber (match_operand:DI 4 "memory_operand" ""))
4595    (clobber (match_scratch 5 ""))]
4596   "reload_completed"
4597   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4598               (use (match_dup 2))
4599               (use (match_dup 3))
4600               (clobber (match_dup 5))])
4601    (set (match_dup 0) (match_dup 4))]
4602   "")
4603
4604 (define_split
4605   [(set (match_operand:DI 0 "memory_operand" "")
4606         (fix:DI (match_operand 1 "register_operand" "")))
4607    (use (match_operand:HI 2 "memory_operand" ""))
4608    (use (match_operand:HI 3 "memory_operand" ""))
4609    (clobber (match_operand:DI 4 "memory_operand" ""))
4610    (clobber (match_scratch 5 ""))]
4611   "reload_completed"
4612   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4613               (use (match_dup 2))
4614               (use (match_dup 3))
4615               (clobber (match_dup 5))])]
4616   "")
4617
4618 (define_insn "fix_trunc<mode>_i387"
4619   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4620         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4621    (use (match_operand:HI 2 "memory_operand" "m"))
4622    (use (match_operand:HI 3 "memory_operand" "m"))]
4623   "TARGET_80387 && !TARGET_FISTTP
4624    && FLOAT_MODE_P (GET_MODE (operands[1]))
4625    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4626   "* return output_fix_trunc (insn, operands, 0);"
4627   [(set_attr "type" "fistp")
4628    (set_attr "i387_cw" "trunc")
4629    (set_attr "mode" "<MODE>")])
4630
4631 (define_insn "fix_trunc<mode>_i387_with_temp"
4632   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4633         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4634    (use (match_operand:HI 2 "memory_operand" "m,m"))
4635    (use (match_operand:HI 3 "memory_operand" "m,m"))
4636    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4637   "TARGET_80387 && !TARGET_FISTTP
4638    && FLOAT_MODE_P (GET_MODE (operands[1]))
4639    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640   "#"
4641   [(set_attr "type" "fistp")
4642    (set_attr "i387_cw" "trunc")
4643    (set_attr "mode" "<MODE>")])
4644
4645 (define_split
4646   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4647         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4648    (use (match_operand:HI 2 "memory_operand" ""))
4649    (use (match_operand:HI 3 "memory_operand" ""))
4650    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4651   "reload_completed"
4652   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4653               (use (match_dup 2))
4654               (use (match_dup 3))])
4655    (set (match_dup 0) (match_dup 4))]
4656   "")
4657
4658 (define_split
4659   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4660         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661    (use (match_operand:HI 2 "memory_operand" ""))
4662    (use (match_operand:HI 3 "memory_operand" ""))
4663    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4664   "reload_completed"
4665   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4666               (use (match_dup 2))
4667               (use (match_dup 3))])]
4668   "")
4669
4670 (define_insn "x86_fnstcw_1"
4671   [(set (match_operand:HI 0 "memory_operand" "=m")
4672         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4673   "TARGET_80387"
4674   "fnstcw\t%0"
4675   [(set_attr "length" "2")
4676    (set_attr "mode" "HI")
4677    (set_attr "unit" "i387")])
4678
4679 (define_insn "x86_fldcw_1"
4680   [(set (reg:HI FPCR_REG)
4681         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4682   "TARGET_80387"
4683   "fldcw\t%0"
4684   [(set_attr "length" "2")
4685    (set_attr "mode" "HI")
4686    (set_attr "unit" "i387")
4687    (set_attr "athlon_decode" "vector")
4688    (set_attr "amdfam10_decode" "vector")])   
4689 \f
4690 ;; Conversion between fixed point and floating point.
4691
4692 ;; Even though we only accept memory inputs, the backend _really_
4693 ;; wants to be able to do this between registers.
4694
4695 (define_expand "floathisf2"
4696   [(set (match_operand:SF 0 "register_operand" "")
4697         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4698   "TARGET_80387 || TARGET_SSE_MATH"
4699 {
4700   if (TARGET_SSE_MATH)
4701     {
4702       emit_insn (gen_floatsisf2 (operands[0],
4703                                  convert_to_mode (SImode, operands[1], 0)));
4704       DONE;
4705     }
4706 })
4707
4708 (define_insn "*floathisf2_i387"
4709   [(set (match_operand:SF 0 "register_operand" "=f,f")
4710         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4712   "@
4713    fild%z1\t%1
4714    #"
4715   [(set_attr "type" "fmov,multi")
4716    (set_attr "mode" "SF")
4717    (set_attr "unit" "*,i387")
4718    (set_attr "fp_int_src" "true")])
4719
4720 (define_expand "floatsisf2"
4721   [(set (match_operand:SF 0 "register_operand" "")
4722         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4723   "TARGET_80387 || TARGET_SSE_MATH"
4724   "")
4725
4726 (define_insn "*floatsisf2_mixed"
4727   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4728         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4729   "TARGET_MIX_SSE_I387"
4730   "@
4731    fild%z1\t%1
4732    #
4733    cvtsi2ss\t{%1, %0|%0, %1}
4734    cvtsi2ss\t{%1, %0|%0, %1}"
4735   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4736    (set_attr "mode" "SF")
4737    (set_attr "unit" "*,i387,*,*")
4738    (set_attr "athlon_decode" "*,*,vector,double")
4739    (set_attr "amdfam10_decode" "*,*,vector,double")
4740    (set_attr "fp_int_src" "true")])
4741
4742 (define_insn "*floatsisf2_sse"
4743   [(set (match_operand:SF 0 "register_operand" "=x,x")
4744         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4745   "TARGET_SSE_MATH"
4746   "cvtsi2ss\t{%1, %0|%0, %1}"
4747   [(set_attr "type" "sseicvt")
4748    (set_attr "mode" "SF")
4749    (set_attr "athlon_decode" "vector,double")
4750    (set_attr "amdfam10_decode" "vector,double")
4751    (set_attr "fp_int_src" "true")])
4752
4753 (define_insn "*floatsisf2_i387"
4754   [(set (match_operand:SF 0 "register_operand" "=f,f")
4755         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4756   "TARGET_80387"
4757   "@
4758    fild%z1\t%1
4759    #"
4760   [(set_attr "type" "fmov,multi")
4761    (set_attr "mode" "SF")
4762    (set_attr "unit" "*,i387")
4763    (set_attr "fp_int_src" "true")])
4764
4765 (define_expand "floatdisf2"
4766   [(set (match_operand:SF 0 "register_operand" "")
4767         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4768   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4769   "")
4770
4771 (define_insn "*floatdisf2_mixed"
4772   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4773         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4774   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4775   "@
4776    fild%z1\t%1
4777    #
4778    cvtsi2ss{q}\t{%1, %0|%0, %1}
4779    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4780   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4781    (set_attr "mode" "SF")
4782    (set_attr "unit" "*,i387,*,*")
4783    (set_attr "athlon_decode" "*,*,vector,double")
4784    (set_attr "amdfam10_decode" "*,*,vector,double")
4785    (set_attr "fp_int_src" "true")])
4786
4787 (define_insn "*floatdisf2_sse"
4788   [(set (match_operand:SF 0 "register_operand" "=x,x")
4789         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4790   "TARGET_64BIT && TARGET_SSE_MATH"
4791   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4792   [(set_attr "type" "sseicvt")
4793    (set_attr "mode" "SF")
4794    (set_attr "athlon_decode" "vector,double")
4795    (set_attr "amdfam10_decode" "vector,double")
4796    (set_attr "fp_int_src" "true")])
4797
4798 (define_insn "*floatdisf2_i387"
4799   [(set (match_operand:SF 0 "register_operand" "=f,f")
4800         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4801   "TARGET_80387"
4802   "@
4803    fild%z1\t%1
4804    #"
4805   [(set_attr "type" "fmov,multi")
4806    (set_attr "mode" "SF")
4807    (set_attr "unit" "*,i387")
4808    (set_attr "fp_int_src" "true")])
4809
4810 (define_expand "floathidf2"
4811   [(set (match_operand:DF 0 "register_operand" "")
4812         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4813   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4814 {
4815   if (TARGET_SSE2 && TARGET_SSE_MATH)
4816     {
4817       emit_insn (gen_floatsidf2 (operands[0],
4818                                  convert_to_mode (SImode, operands[1], 0)));
4819       DONE;
4820     }
4821 })
4822
4823 (define_insn "*floathidf2_i387"
4824   [(set (match_operand:DF 0 "register_operand" "=f,f")
4825         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4826   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4827   "@
4828    fild%z1\t%1
4829    #"
4830   [(set_attr "type" "fmov,multi")
4831    (set_attr "mode" "DF")
4832    (set_attr "unit" "*,i387")
4833    (set_attr "fp_int_src" "true")])
4834
4835 (define_expand "floatsidf2"
4836   [(set (match_operand:DF 0 "register_operand" "")
4837         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4838   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4839   "")
4840
4841 (define_insn "*floatsidf2_mixed"
4842   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4843         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4844   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4845   "@
4846    fild%z1\t%1
4847    #
4848    cvtsi2sd\t{%1, %0|%0, %1}
4849    cvtsi2sd\t{%1, %0|%0, %1}"
4850   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4851    (set_attr "mode" "DF")
4852    (set_attr "unit" "*,i387,*,*")
4853    (set_attr "athlon_decode" "*,*,double,direct")
4854    (set_attr "amdfam10_decode" "*,*,vector,double")
4855    (set_attr "fp_int_src" "true")])
4856
4857 (define_insn "*floatsidf2_sse"
4858   [(set (match_operand:DF 0 "register_operand" "=x,x")
4859         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4860   "TARGET_SSE2 && TARGET_SSE_MATH"
4861   "cvtsi2sd\t{%1, %0|%0, %1}"
4862   [(set_attr "type" "sseicvt")
4863    (set_attr "mode" "DF")
4864    (set_attr "athlon_decode" "double,direct")
4865    (set_attr "amdfam10_decode" "vector,double")
4866    (set_attr "fp_int_src" "true")])
4867
4868 (define_insn "*floatsidf2_i387"
4869   [(set (match_operand:DF 0 "register_operand" "=f,f")
4870         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4871   "TARGET_80387"
4872   "@
4873    fild%z1\t%1
4874    #"
4875   [(set_attr "type" "fmov,multi")
4876    (set_attr "mode" "DF")
4877    (set_attr "unit" "*,i387")
4878    (set_attr "fp_int_src" "true")])
4879
4880 (define_expand "floatdidf2"
4881   [(set (match_operand:DF 0 "register_operand" "")
4882         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4883   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4884 {
4885   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4886     {
4887       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4888       DONE;
4889     }
4890 })
4891
4892 (define_insn "*floatdidf2_mixed"
4893   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4894         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4895   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4896   "@
4897    fild%z1\t%1
4898    #
4899    cvtsi2sd{q}\t{%1, %0|%0, %1}
4900    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4901   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902    (set_attr "mode" "DF")
4903    (set_attr "unit" "*,i387,*,*")
4904    (set_attr "athlon_decode" "*,*,double,direct")
4905    (set_attr "amdfam10_decode" "*,*,vector,double")
4906    (set_attr "fp_int_src" "true")])
4907
4908 (define_insn "*floatdidf2_sse"
4909   [(set (match_operand:DF 0 "register_operand" "=x,x")
4910         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4911   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4912   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4913   [(set_attr "type" "sseicvt")
4914    (set_attr "mode" "DF")
4915    (set_attr "athlon_decode" "double,direct")
4916    (set_attr "amdfam10_decode" "vector,double")
4917    (set_attr "fp_int_src" "true")])
4918
4919 (define_insn "*floatdidf2_i387"
4920   [(set (match_operand:DF 0 "register_operand" "=f,f")
4921         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4922   "TARGET_80387"
4923   "@
4924    fild%z1\t%1
4925    #"
4926   [(set_attr "type" "fmov,multi")
4927    (set_attr "mode" "DF")
4928    (set_attr "unit" "*,i387")
4929    (set_attr "fp_int_src" "true")])
4930
4931 (define_insn "floathixf2"
4932   [(set (match_operand:XF 0 "register_operand" "=f,f")
4933         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4934   "TARGET_80387"
4935   "@
4936    fild%z1\t%1
4937    #"
4938   [(set_attr "type" "fmov,multi")
4939    (set_attr "mode" "XF")
4940    (set_attr "unit" "*,i387")
4941    (set_attr "fp_int_src" "true")])
4942
4943 (define_insn "floatsixf2"
4944   [(set (match_operand:XF 0 "register_operand" "=f,f")
4945         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4946   "TARGET_80387"
4947   "@
4948    fild%z1\t%1
4949    #"
4950   [(set_attr "type" "fmov,multi")
4951    (set_attr "mode" "XF")
4952    (set_attr "unit" "*,i387")
4953    (set_attr "fp_int_src" "true")])
4954
4955 (define_insn "floatdixf2"
4956   [(set (match_operand:XF 0 "register_operand" "=f,f")
4957         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4958   "TARGET_80387"
4959   "@
4960    fild%z1\t%1
4961    #"
4962   [(set_attr "type" "fmov,multi")
4963    (set_attr "mode" "XF")
4964    (set_attr "unit" "*,i387")
4965    (set_attr "fp_int_src" "true")])
4966
4967 ;; %%% Kill these when reload knows how to do it.
4968 (define_split
4969   [(set (match_operand 0 "fp_register_operand" "")
4970         (float (match_operand 1 "register_operand" "")))]
4971   "reload_completed
4972    && TARGET_80387
4973    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4974   [(const_int 0)]
4975 {
4976   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4977   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4978   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4979   ix86_free_from_memory (GET_MODE (operands[1]));
4980   DONE;
4981 })
4982
4983 (define_expand "floatunssisf2"
4984   [(use (match_operand:SF 0 "register_operand" ""))
4985    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4986   "!TARGET_64BIT"
4987 {
4988   if (TARGET_SSE_MATH && TARGET_SSE2)
4989     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4990   else
4991     x86_emit_floatuns (operands);
4992   DONE;
4993 })
4994
4995 (define_expand "floatunssidf2"
4996   [(use (match_operand:DF 0 "register_operand" ""))
4997    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4998   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4999   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5000
5001 (define_expand "floatunsdisf2"
5002   [(use (match_operand:SF 0 "register_operand" ""))
5003    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5004   "TARGET_64BIT && TARGET_SSE_MATH"
5005   "x86_emit_floatuns (operands); DONE;")
5006
5007 (define_expand "floatunsdidf2"
5008   [(use (match_operand:DF 0 "register_operand" ""))
5009    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5010   "TARGET_SSE_MATH && TARGET_SSE2
5011    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5012 {
5013   if (TARGET_64BIT)
5014     x86_emit_floatuns (operands);
5015   else
5016     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5017   DONE;
5018 })
5019 \f
5020 ;; SSE extract/set expanders
5021
5022 \f
5023 ;; Add instructions
5024
5025 ;; %%% splits for addditi3
5026
5027 (define_expand "addti3"
5028   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5029         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5030                  (match_operand:TI 2 "x86_64_general_operand" "")))
5031    (clobber (reg:CC FLAGS_REG))]
5032   "TARGET_64BIT"
5033   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5034
5035 (define_insn "*addti3_1"
5036   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5037         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5038                  (match_operand:TI 2 "general_operand" "roiF,riF")))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5041   "#")
5042
5043 (define_split
5044   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5045         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5046                  (match_operand:TI 2 "general_operand" "")))
5047    (clobber (reg:CC FLAGS_REG))]
5048   "TARGET_64BIT && reload_completed"
5049   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5050                                           UNSPEC_ADD_CARRY))
5051               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5052    (parallel [(set (match_dup 3)
5053                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5054                                      (match_dup 4))
5055                             (match_dup 5)))
5056               (clobber (reg:CC FLAGS_REG))])]
5057   "split_ti (operands+0, 1, operands+0, operands+3);
5058    split_ti (operands+1, 1, operands+1, operands+4);
5059    split_ti (operands+2, 1, operands+2, operands+5);")
5060
5061 ;; %%% splits for addsidi3
5062 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5063 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5064 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5065
5066 (define_expand "adddi3"
5067   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5068         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5069                  (match_operand:DI 2 "x86_64_general_operand" "")))
5070    (clobber (reg:CC FLAGS_REG))]
5071   ""
5072   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5073
5074 (define_insn "*adddi3_1"
5075   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5076         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5077                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5078    (clobber (reg:CC FLAGS_REG))]
5079   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5080   "#")
5081
5082 (define_split
5083   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5084         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5085                  (match_operand:DI 2 "general_operand" "")))
5086    (clobber (reg:CC FLAGS_REG))]
5087   "!TARGET_64BIT && reload_completed"
5088   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5089                                           UNSPEC_ADD_CARRY))
5090               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5091    (parallel [(set (match_dup 3)
5092                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5093                                      (match_dup 4))
5094                             (match_dup 5)))
5095               (clobber (reg:CC FLAGS_REG))])]
5096   "split_di (operands+0, 1, operands+0, operands+3);
5097    split_di (operands+1, 1, operands+1, operands+4);
5098    split_di (operands+2, 1, operands+2, operands+5);")
5099
5100 (define_insn "adddi3_carry_rex64"
5101   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5102           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5103                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5104                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5105    (clobber (reg:CC FLAGS_REG))]
5106   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107   "adc{q}\t{%2, %0|%0, %2}"
5108   [(set_attr "type" "alu")
5109    (set_attr "pent_pair" "pu")
5110    (set_attr "mode" "DI")])
5111
5112 (define_insn "*adddi3_cc_rex64"
5113   [(set (reg:CC FLAGS_REG)
5114         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5115                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5116                    UNSPEC_ADD_CARRY))
5117    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5118         (plus:DI (match_dup 1) (match_dup 2)))]
5119   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120   "add{q}\t{%2, %0|%0, %2}"
5121   [(set_attr "type" "alu")
5122    (set_attr "mode" "DI")])
5123
5124 (define_insn "addqi3_carry"
5125   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5126           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5127                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5128                    (match_operand:QI 2 "general_operand" "qi,qm")))
5129    (clobber (reg:CC FLAGS_REG))]
5130   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131   "adc{b}\t{%2, %0|%0, %2}"
5132   [(set_attr "type" "alu")
5133    (set_attr "pent_pair" "pu")
5134    (set_attr "mode" "QI")])
5135
5136 (define_insn "addhi3_carry"
5137   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5138           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5139                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5140                    (match_operand:HI 2 "general_operand" "ri,rm")))
5141    (clobber (reg:CC FLAGS_REG))]
5142   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5143   "adc{w}\t{%2, %0|%0, %2}"
5144   [(set_attr "type" "alu")
5145    (set_attr "pent_pair" "pu")
5146    (set_attr "mode" "HI")])
5147
5148 (define_insn "addsi3_carry"
5149   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5150           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5151                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5152                    (match_operand:SI 2 "general_operand" "ri,rm")))
5153    (clobber (reg:CC FLAGS_REG))]
5154   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5155   "adc{l}\t{%2, %0|%0, %2}"
5156   [(set_attr "type" "alu")
5157    (set_attr "pent_pair" "pu")
5158    (set_attr "mode" "SI")])
5159
5160 (define_insn "*addsi3_carry_zext"
5161   [(set (match_operand:DI 0 "register_operand" "=r")
5162           (zero_extend:DI
5163             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5165                      (match_operand:SI 2 "general_operand" "rim"))))
5166    (clobber (reg:CC FLAGS_REG))]
5167   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5168   "adc{l}\t{%2, %k0|%k0, %2}"
5169   [(set_attr "type" "alu")
5170    (set_attr "pent_pair" "pu")
5171    (set_attr "mode" "SI")])
5172
5173 (define_insn "*addsi3_cc"
5174   [(set (reg:CC FLAGS_REG)
5175         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5176                     (match_operand:SI 2 "general_operand" "ri,rm")]
5177                    UNSPEC_ADD_CARRY))
5178    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5179         (plus:SI (match_dup 1) (match_dup 2)))]
5180   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5181   "add{l}\t{%2, %0|%0, %2}"
5182   [(set_attr "type" "alu")
5183    (set_attr "mode" "SI")])
5184
5185 (define_insn "addqi3_cc"
5186   [(set (reg:CC FLAGS_REG)
5187         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5188                     (match_operand:QI 2 "general_operand" "qi,qm")]
5189                    UNSPEC_ADD_CARRY))
5190    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5191         (plus:QI (match_dup 1) (match_dup 2)))]
5192   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5193   "add{b}\t{%2, %0|%0, %2}"
5194   [(set_attr "type" "alu")
5195    (set_attr "mode" "QI")])
5196
5197 (define_expand "addsi3"
5198   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5199                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5200                             (match_operand:SI 2 "general_operand" "")))
5201               (clobber (reg:CC FLAGS_REG))])]
5202   ""
5203   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5204
5205 (define_insn "*lea_1"
5206   [(set (match_operand:SI 0 "register_operand" "=r")
5207         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5208   "!TARGET_64BIT"
5209   "lea{l}\t{%a1, %0|%0, %a1}"
5210   [(set_attr "type" "lea")
5211    (set_attr "mode" "SI")])
5212
5213 (define_insn "*lea_1_rex64"
5214   [(set (match_operand:SI 0 "register_operand" "=r")
5215         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5216   "TARGET_64BIT"
5217   "lea{l}\t{%a1, %0|%0, %a1}"
5218   [(set_attr "type" "lea")
5219    (set_attr "mode" "SI")])
5220
5221 (define_insn "*lea_1_zext"
5222   [(set (match_operand:DI 0 "register_operand" "=r")
5223         (zero_extend:DI
5224          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5225   "TARGET_64BIT"
5226   "lea{l}\t{%a1, %k0|%k0, %a1}"
5227   [(set_attr "type" "lea")
5228    (set_attr "mode" "SI")])
5229
5230 (define_insn "*lea_2_rex64"
5231   [(set (match_operand:DI 0 "register_operand" "=r")
5232         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5233   "TARGET_64BIT"
5234   "lea{q}\t{%a1, %0|%0, %a1}"
5235   [(set_attr "type" "lea")
5236    (set_attr "mode" "DI")])
5237
5238 ;; The lea patterns for non-Pmodes needs to be matched by several
5239 ;; insns converted to real lea by splitters.
5240
5241 (define_insn_and_split "*lea_general_1"
5242   [(set (match_operand 0 "register_operand" "=r")
5243         (plus (plus (match_operand 1 "index_register_operand" "l")
5244                     (match_operand 2 "register_operand" "r"))
5245               (match_operand 3 "immediate_operand" "i")))]
5246   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5247     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5248    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5249    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5250    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5251    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5252        || GET_MODE (operands[3]) == VOIDmode)"
5253   "#"
5254   "&& reload_completed"
5255   [(const_int 0)]
5256 {
5257   rtx pat;
5258   operands[0] = gen_lowpart (SImode, operands[0]);
5259   operands[1] = gen_lowpart (Pmode, operands[1]);
5260   operands[2] = gen_lowpart (Pmode, operands[2]);
5261   operands[3] = gen_lowpart (Pmode, operands[3]);
5262   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5263                       operands[3]);
5264   if (Pmode != SImode)
5265     pat = gen_rtx_SUBREG (SImode, pat, 0);
5266   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5267   DONE;
5268 }
5269   [(set_attr "type" "lea")
5270    (set_attr "mode" "SI")])
5271
5272 (define_insn_and_split "*lea_general_1_zext"
5273   [(set (match_operand:DI 0 "register_operand" "=r")
5274         (zero_extend:DI
5275           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5276                             (match_operand:SI 2 "register_operand" "r"))
5277                    (match_operand:SI 3 "immediate_operand" "i"))))]
5278   "TARGET_64BIT"
5279   "#"
5280   "&& reload_completed"
5281   [(set (match_dup 0)
5282         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5283                                                      (match_dup 2))
5284                                             (match_dup 3)) 0)))]
5285 {
5286   operands[1] = gen_lowpart (Pmode, operands[1]);
5287   operands[2] = gen_lowpart (Pmode, operands[2]);
5288   operands[3] = gen_lowpart (Pmode, operands[3]);
5289 }
5290   [(set_attr "type" "lea")
5291    (set_attr "mode" "SI")])
5292
5293 (define_insn_and_split "*lea_general_2"
5294   [(set (match_operand 0 "register_operand" "=r")
5295         (plus (mult (match_operand 1 "index_register_operand" "l")
5296                     (match_operand 2 "const248_operand" "i"))
5297               (match_operand 3 "nonmemory_operand" "ri")))]
5298   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5299     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5300    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5301    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5302    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5303        || GET_MODE (operands[3]) == VOIDmode)"
5304   "#"
5305   "&& reload_completed"
5306   [(const_int 0)]
5307 {
5308   rtx pat;
5309   operands[0] = gen_lowpart (SImode, operands[0]);
5310   operands[1] = gen_lowpart (Pmode, operands[1]);
5311   operands[3] = gen_lowpart (Pmode, operands[3]);
5312   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5313                       operands[3]);
5314   if (Pmode != SImode)
5315     pat = gen_rtx_SUBREG (SImode, pat, 0);
5316   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5317   DONE;
5318 }
5319   [(set_attr "type" "lea")
5320    (set_attr "mode" "SI")])
5321
5322 (define_insn_and_split "*lea_general_2_zext"
5323   [(set (match_operand:DI 0 "register_operand" "=r")
5324         (zero_extend:DI
5325           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5326                             (match_operand:SI 2 "const248_operand" "n"))
5327                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5328   "TARGET_64BIT"
5329   "#"
5330   "&& reload_completed"
5331   [(set (match_dup 0)
5332         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5333                                                      (match_dup 2))
5334                                             (match_dup 3)) 0)))]
5335 {
5336   operands[1] = gen_lowpart (Pmode, operands[1]);
5337   operands[3] = gen_lowpart (Pmode, operands[3]);
5338 }
5339   [(set_attr "type" "lea")
5340    (set_attr "mode" "SI")])
5341
5342 (define_insn_and_split "*lea_general_3"
5343   [(set (match_operand 0 "register_operand" "=r")
5344         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5345                           (match_operand 2 "const248_operand" "i"))
5346                     (match_operand 3 "register_operand" "r"))
5347               (match_operand 4 "immediate_operand" "i")))]
5348   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5349     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5350    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5351    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5352    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5353   "#"
5354   "&& reload_completed"
5355   [(const_int 0)]
5356 {
5357   rtx pat;
5358   operands[0] = gen_lowpart (SImode, operands[0]);
5359   operands[1] = gen_lowpart (Pmode, operands[1]);
5360   operands[3] = gen_lowpart (Pmode, operands[3]);
5361   operands[4] = gen_lowpart (Pmode, operands[4]);
5362   pat = gen_rtx_PLUS (Pmode,
5363                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5364                                                          operands[2]),
5365                                     operands[3]),
5366                       operands[4]);
5367   if (Pmode != SImode)
5368     pat = gen_rtx_SUBREG (SImode, pat, 0);
5369   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5370   DONE;
5371 }
5372   [(set_attr "type" "lea")
5373    (set_attr "mode" "SI")])
5374
5375 (define_insn_and_split "*lea_general_3_zext"
5376   [(set (match_operand:DI 0 "register_operand" "=r")
5377         (zero_extend:DI
5378           (plus:SI (plus:SI (mult:SI
5379                               (match_operand:SI 1 "index_register_operand" "l")
5380                               (match_operand:SI 2 "const248_operand" "n"))
5381                             (match_operand:SI 3 "register_operand" "r"))
5382                    (match_operand:SI 4 "immediate_operand" "i"))))]
5383   "TARGET_64BIT"
5384   "#"
5385   "&& reload_completed"
5386   [(set (match_dup 0)
5387         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5388                                                               (match_dup 2))
5389                                                      (match_dup 3))
5390                                             (match_dup 4)) 0)))]
5391 {
5392   operands[1] = gen_lowpart (Pmode, operands[1]);
5393   operands[3] = gen_lowpart (Pmode, operands[3]);
5394   operands[4] = gen_lowpart (Pmode, operands[4]);
5395 }
5396   [(set_attr "type" "lea")
5397    (set_attr "mode" "SI")])
5398
5399 (define_insn "*adddi_1_rex64"
5400   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5401         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5402                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5403    (clobber (reg:CC FLAGS_REG))]
5404   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5405 {
5406   switch (get_attr_type (insn))
5407     {
5408     case TYPE_LEA:
5409       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5410       return "lea{q}\t{%a2, %0|%0, %a2}";
5411
5412     case TYPE_INCDEC:
5413       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5414       if (operands[2] == const1_rtx)
5415         return "inc{q}\t%0";
5416       else
5417         {
5418           gcc_assert (operands[2] == constm1_rtx);
5419           return "dec{q}\t%0";
5420         }
5421
5422     default:
5423       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5424
5425       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5426          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5427       if (CONST_INT_P (operands[2])
5428           /* Avoid overflows.  */
5429           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5430           && (INTVAL (operands[2]) == 128
5431               || (INTVAL (operands[2]) < 0
5432                   && INTVAL (operands[2]) != -128)))
5433         {
5434           operands[2] = GEN_INT (-INTVAL (operands[2]));
5435           return "sub{q}\t{%2, %0|%0, %2}";
5436         }
5437       return "add{q}\t{%2, %0|%0, %2}";
5438     }
5439 }
5440   [(set (attr "type")
5441      (cond [(eq_attr "alternative" "2")
5442               (const_string "lea")
5443             ; Current assemblers are broken and do not allow @GOTOFF in
5444             ; ought but a memory context.
5445             (match_operand:DI 2 "pic_symbolic_operand" "")
5446               (const_string "lea")
5447             (match_operand:DI 2 "incdec_operand" "")
5448               (const_string "incdec")
5449            ]
5450            (const_string "alu")))
5451    (set_attr "mode" "DI")])
5452
5453 ;; Convert lea to the lea pattern to avoid flags dependency.
5454 (define_split
5455   [(set (match_operand:DI 0 "register_operand" "")
5456         (plus:DI (match_operand:DI 1 "register_operand" "")
5457                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5458    (clobber (reg:CC FLAGS_REG))]
5459   "TARGET_64BIT && reload_completed
5460    && true_regnum (operands[0]) != true_regnum (operands[1])"
5461   [(set (match_dup 0)
5462         (plus:DI (match_dup 1)
5463                  (match_dup 2)))]
5464   "")
5465
5466 (define_insn "*adddi_2_rex64"
5467   [(set (reg FLAGS_REG)
5468         (compare
5469           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5470                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5471           (const_int 0)))
5472    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5473         (plus:DI (match_dup 1) (match_dup 2)))]
5474   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5475    && ix86_binary_operator_ok (PLUS, DImode, operands)
5476    /* Current assemblers are broken and do not allow @GOTOFF in
5477       ought but a memory context.  */
5478    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5479 {
5480   switch (get_attr_type (insn))
5481     {
5482     case TYPE_INCDEC:
5483       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484       if (operands[2] == const1_rtx)
5485         return "inc{q}\t%0";
5486       else
5487         {
5488           gcc_assert (operands[2] == constm1_rtx);
5489           return "dec{q}\t%0";
5490         }
5491
5492     default:
5493       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494       /* ???? We ought to handle there the 32bit case too
5495          - do we need new constraint?  */
5496       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5497          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5498       if (CONST_INT_P (operands[2])
5499           /* Avoid overflows.  */
5500           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5501           && (INTVAL (operands[2]) == 128
5502               || (INTVAL (operands[2]) < 0
5503                   && INTVAL (operands[2]) != -128)))
5504         {
5505           operands[2] = GEN_INT (-INTVAL (operands[2]));
5506           return "sub{q}\t{%2, %0|%0, %2}";
5507         }
5508       return "add{q}\t{%2, %0|%0, %2}";
5509     }
5510 }
5511   [(set (attr "type")
5512      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513         (const_string "incdec")
5514         (const_string "alu")))
5515    (set_attr "mode" "DI")])
5516
5517 (define_insn "*adddi_3_rex64"
5518   [(set (reg FLAGS_REG)
5519         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5520                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5521    (clobber (match_scratch:DI 0 "=r"))]
5522   "TARGET_64BIT
5523    && ix86_match_ccmode (insn, CCZmode)
5524    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5525    /* Current assemblers are broken and do not allow @GOTOFF in
5526       ought but a memory context.  */
5527    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5528 {
5529   switch (get_attr_type (insn))
5530     {
5531     case TYPE_INCDEC:
5532       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533       if (operands[2] == const1_rtx)
5534         return "inc{q}\t%0";
5535       else
5536         {
5537           gcc_assert (operands[2] == constm1_rtx);
5538           return "dec{q}\t%0";
5539         }
5540
5541     default:
5542       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543       /* ???? We ought to handle there the 32bit case too
5544          - do we need new constraint?  */
5545       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5547       if (CONST_INT_P (operands[2])
5548           /* Avoid overflows.  */
5549           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550           && (INTVAL (operands[2]) == 128
5551               || (INTVAL (operands[2]) < 0
5552                   && INTVAL (operands[2]) != -128)))
5553         {
5554           operands[2] = GEN_INT (-INTVAL (operands[2]));
5555           return "sub{q}\t{%2, %0|%0, %2}";
5556         }
5557       return "add{q}\t{%2, %0|%0, %2}";
5558     }
5559 }
5560   [(set (attr "type")
5561      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5562         (const_string "incdec")
5563         (const_string "alu")))
5564    (set_attr "mode" "DI")])
5565
5566 ; For comparisons against 1, -1 and 128, we may generate better code
5567 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5568 ; is matched then.  We can't accept general immediate, because for
5569 ; case of overflows,  the result is messed up.
5570 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5571 ; when negated.
5572 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5573 ; only for comparisons not depending on it.
5574 (define_insn "*adddi_4_rex64"
5575   [(set (reg FLAGS_REG)
5576         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5577                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5578    (clobber (match_scratch:DI 0 "=rm"))]
5579   "TARGET_64BIT
5580    &&  ix86_match_ccmode (insn, CCGCmode)"
5581 {
5582   switch (get_attr_type (insn))
5583     {
5584     case TYPE_INCDEC:
5585       if (operands[2] == constm1_rtx)
5586         return "inc{q}\t%0";
5587       else
5588         {
5589           gcc_assert (operands[2] == const1_rtx);
5590           return "dec{q}\t%0";
5591         }
5592
5593     default:
5594       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5597       if ((INTVAL (operands[2]) == -128
5598            || (INTVAL (operands[2]) > 0
5599                && INTVAL (operands[2]) != 128))
5600           /* Avoid overflows.  */
5601           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5602         return "sub{q}\t{%2, %0|%0, %2}";
5603       operands[2] = GEN_INT (-INTVAL (operands[2]));
5604       return "add{q}\t{%2, %0|%0, %2}";
5605     }
5606 }
5607   [(set (attr "type")
5608      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5609         (const_string "incdec")
5610         (const_string "alu")))
5611    (set_attr "mode" "DI")])
5612
5613 (define_insn "*adddi_5_rex64"
5614   [(set (reg FLAGS_REG)
5615         (compare
5616           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5617                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5618           (const_int 0)))
5619    (clobber (match_scratch:DI 0 "=r"))]
5620   "TARGET_64BIT
5621    && ix86_match_ccmode (insn, CCGOCmode)
5622    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5623    /* Current assemblers are broken and do not allow @GOTOFF in
5624       ought but a memory context.  */
5625    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5626 {
5627   switch (get_attr_type (insn))
5628     {
5629     case TYPE_INCDEC:
5630       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631       if (operands[2] == const1_rtx)
5632         return "inc{q}\t%0";
5633       else
5634         {
5635           gcc_assert (operands[2] == constm1_rtx);
5636           return "dec{q}\t%0";
5637         }
5638
5639     default:
5640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5642          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5643       if (CONST_INT_P (operands[2])
5644           /* Avoid overflows.  */
5645           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5646           && (INTVAL (operands[2]) == 128
5647               || (INTVAL (operands[2]) < 0
5648                   && INTVAL (operands[2]) != -128)))
5649         {
5650           operands[2] = GEN_INT (-INTVAL (operands[2]));
5651           return "sub{q}\t{%2, %0|%0, %2}";
5652         }
5653       return "add{q}\t{%2, %0|%0, %2}";
5654     }
5655 }
5656   [(set (attr "type")
5657      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5658         (const_string "incdec")
5659         (const_string "alu")))
5660    (set_attr "mode" "DI")])
5661
5662
5663 (define_insn "*addsi_1"
5664   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5665         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5666                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5667    (clobber (reg:CC FLAGS_REG))]
5668   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5669 {
5670   switch (get_attr_type (insn))
5671     {
5672     case TYPE_LEA:
5673       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5674       return "lea{l}\t{%a2, %0|%0, %a2}";
5675
5676     case TYPE_INCDEC:
5677       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678       if (operands[2] == const1_rtx)
5679         return "inc{l}\t%0";
5680       else
5681         {
5682           gcc_assert (operands[2] == constm1_rtx);
5683           return "dec{l}\t%0";
5684         }
5685
5686     default:
5687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688
5689       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5691       if (CONST_INT_P (operands[2])
5692           && (INTVAL (operands[2]) == 128
5693               || (INTVAL (operands[2]) < 0
5694                   && INTVAL (operands[2]) != -128)))
5695         {
5696           operands[2] = GEN_INT (-INTVAL (operands[2]));
5697           return "sub{l}\t{%2, %0|%0, %2}";
5698         }
5699       return "add{l}\t{%2, %0|%0, %2}";
5700     }
5701 }
5702   [(set (attr "type")
5703      (cond [(eq_attr "alternative" "2")
5704               (const_string "lea")
5705             ; Current assemblers are broken and do not allow @GOTOFF in
5706             ; ought but a memory context.
5707             (match_operand:SI 2 "pic_symbolic_operand" "")
5708               (const_string "lea")
5709             (match_operand:SI 2 "incdec_operand" "")
5710               (const_string "incdec")
5711            ]
5712            (const_string "alu")))
5713    (set_attr "mode" "SI")])
5714
5715 ;; Convert lea to the lea pattern to avoid flags dependency.
5716 (define_split
5717   [(set (match_operand 0 "register_operand" "")
5718         (plus (match_operand 1 "register_operand" "")
5719               (match_operand 2 "nonmemory_operand" "")))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "reload_completed
5722    && true_regnum (operands[0]) != true_regnum (operands[1])"
5723   [(const_int 0)]
5724 {
5725   rtx pat;
5726   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5727      may confuse gen_lowpart.  */
5728   if (GET_MODE (operands[0]) != Pmode)
5729     {
5730       operands[1] = gen_lowpart (Pmode, operands[1]);
5731       operands[2] = gen_lowpart (Pmode, operands[2]);
5732     }
5733   operands[0] = gen_lowpart (SImode, operands[0]);
5734   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5735   if (Pmode != SImode)
5736     pat = gen_rtx_SUBREG (SImode, pat, 0);
5737   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5738   DONE;
5739 })
5740
5741 ;; It may seem that nonimmediate operand is proper one for operand 1.
5742 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5743 ;; we take care in ix86_binary_operator_ok to not allow two memory
5744 ;; operands so proper swapping will be done in reload.  This allow
5745 ;; patterns constructed from addsi_1 to match.
5746 (define_insn "addsi_1_zext"
5747   [(set (match_operand:DI 0 "register_operand" "=r,r")
5748         (zero_extend:DI
5749           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5750                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5751    (clobber (reg:CC FLAGS_REG))]
5752   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5753 {
5754   switch (get_attr_type (insn))
5755     {
5756     case TYPE_LEA:
5757       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5758       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5759
5760     case TYPE_INCDEC:
5761       if (operands[2] == const1_rtx)
5762         return "inc{l}\t%k0";
5763       else
5764         {
5765           gcc_assert (operands[2] == constm1_rtx);
5766           return "dec{l}\t%k0";
5767         }
5768
5769     default:
5770       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5772       if (CONST_INT_P (operands[2])
5773           && (INTVAL (operands[2]) == 128
5774               || (INTVAL (operands[2]) < 0
5775                   && INTVAL (operands[2]) != -128)))
5776         {
5777           operands[2] = GEN_INT (-INTVAL (operands[2]));
5778           return "sub{l}\t{%2, %k0|%k0, %2}";
5779         }
5780       return "add{l}\t{%2, %k0|%k0, %2}";
5781     }
5782 }
5783   [(set (attr "type")
5784      (cond [(eq_attr "alternative" "1")
5785               (const_string "lea")
5786             ; Current assemblers are broken and do not allow @GOTOFF in
5787             ; ought but a memory context.
5788             (match_operand:SI 2 "pic_symbolic_operand" "")
5789               (const_string "lea")
5790             (match_operand:SI 2 "incdec_operand" "")
5791               (const_string "incdec")
5792            ]
5793            (const_string "alu")))
5794    (set_attr "mode" "SI")])
5795
5796 ;; Convert lea to the lea pattern to avoid flags dependency.
5797 (define_split
5798   [(set (match_operand:DI 0 "register_operand" "")
5799         (zero_extend:DI
5800           (plus:SI (match_operand:SI 1 "register_operand" "")
5801                    (match_operand:SI 2 "nonmemory_operand" ""))))
5802    (clobber (reg:CC FLAGS_REG))]
5803   "TARGET_64BIT && reload_completed
5804    && true_regnum (operands[0]) != true_regnum (operands[1])"
5805   [(set (match_dup 0)
5806         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5807 {
5808   operands[1] = gen_lowpart (Pmode, operands[1]);
5809   operands[2] = gen_lowpart (Pmode, operands[2]);
5810 })
5811
5812 (define_insn "*addsi_2"
5813   [(set (reg FLAGS_REG)
5814         (compare
5815           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5816                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5817           (const_int 0)))
5818    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5819         (plus:SI (match_dup 1) (match_dup 2)))]
5820   "ix86_match_ccmode (insn, CCGOCmode)
5821    && ix86_binary_operator_ok (PLUS, SImode, operands)
5822    /* Current assemblers are broken and do not allow @GOTOFF in
5823       ought but a memory context.  */
5824    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5825 {
5826   switch (get_attr_type (insn))
5827     {
5828     case TYPE_INCDEC:
5829       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5830       if (operands[2] == const1_rtx)
5831         return "inc{l}\t%0";
5832       else
5833         {
5834           gcc_assert (operands[2] == constm1_rtx);
5835           return "dec{l}\t%0";
5836         }
5837
5838     default:
5839       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5842       if (CONST_INT_P (operands[2])
5843           && (INTVAL (operands[2]) == 128
5844               || (INTVAL (operands[2]) < 0
5845                   && INTVAL (operands[2]) != -128)))
5846         {
5847           operands[2] = GEN_INT (-INTVAL (operands[2]));
5848           return "sub{l}\t{%2, %0|%0, %2}";
5849         }
5850       return "add{l}\t{%2, %0|%0, %2}";
5851     }
5852 }
5853   [(set (attr "type")
5854      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5855         (const_string "incdec")
5856         (const_string "alu")))
5857    (set_attr "mode" "SI")])
5858
5859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5860 (define_insn "*addsi_2_zext"
5861   [(set (reg FLAGS_REG)
5862         (compare
5863           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5864                    (match_operand:SI 2 "general_operand" "rmni"))
5865           (const_int 0)))
5866    (set (match_operand:DI 0 "register_operand" "=r")
5867         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5869    && ix86_binary_operator_ok (PLUS, SImode, operands)
5870    /* Current assemblers are broken and do not allow @GOTOFF in
5871       ought but a memory context.  */
5872    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5873 {
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{l}\t%k0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{l}\t%k0";
5883         }
5884
5885     default:
5886       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5888       if (CONST_INT_P (operands[2])
5889           && (INTVAL (operands[2]) == 128
5890               || (INTVAL (operands[2]) < 0
5891                   && INTVAL (operands[2]) != -128)))
5892         {
5893           operands[2] = GEN_INT (-INTVAL (operands[2]));
5894           return "sub{l}\t{%2, %k0|%k0, %2}";
5895         }
5896       return "add{l}\t{%2, %k0|%k0, %2}";
5897     }
5898 }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set_attr "mode" "SI")])
5904
5905 (define_insn "*addsi_3"
5906   [(set (reg FLAGS_REG)
5907         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5908                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5909    (clobber (match_scratch:SI 0 "=r"))]
5910   "ix86_match_ccmode (insn, CCZmode)
5911    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5912    /* Current assemblers are broken and do not allow @GOTOFF in
5913       ought but a memory context.  */
5914    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5915 {
5916   switch (get_attr_type (insn))
5917     {
5918     case TYPE_INCDEC:
5919       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920       if (operands[2] == const1_rtx)
5921         return "inc{l}\t%0";
5922       else
5923         {
5924           gcc_assert (operands[2] == constm1_rtx);
5925           return "dec{l}\t%0";
5926         }
5927
5928     default:
5929       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5930       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5932       if (CONST_INT_P (operands[2])
5933           && (INTVAL (operands[2]) == 128
5934               || (INTVAL (operands[2]) < 0
5935                   && INTVAL (operands[2]) != -128)))
5936         {
5937           operands[2] = GEN_INT (-INTVAL (operands[2]));
5938           return "sub{l}\t{%2, %0|%0, %2}";
5939         }
5940       return "add{l}\t{%2, %0|%0, %2}";
5941     }
5942 }
5943   [(set (attr "type")
5944      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945         (const_string "incdec")
5946         (const_string "alu")))
5947    (set_attr "mode" "SI")])
5948
5949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5950 (define_insn "*addsi_3_zext"
5951   [(set (reg FLAGS_REG)
5952         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5953                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5954    (set (match_operand:DI 0 "register_operand" "=r")
5955         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5956   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5957    && ix86_binary_operator_ok (PLUS, SImode, operands)
5958    /* Current assemblers are broken and do not allow @GOTOFF in
5959       ought but a memory context.  */
5960    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5961 {
5962   switch (get_attr_type (insn))
5963     {
5964     case TYPE_INCDEC:
5965       if (operands[2] == const1_rtx)
5966         return "inc{l}\t%k0";
5967       else
5968         {
5969           gcc_assert (operands[2] == constm1_rtx);
5970           return "dec{l}\t%k0";
5971         }
5972
5973     default:
5974       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5976       if (CONST_INT_P (operands[2])
5977           && (INTVAL (operands[2]) == 128
5978               || (INTVAL (operands[2]) < 0
5979                   && INTVAL (operands[2]) != -128)))
5980         {
5981           operands[2] = GEN_INT (-INTVAL (operands[2]));
5982           return "sub{l}\t{%2, %k0|%k0, %2}";
5983         }
5984       return "add{l}\t{%2, %k0|%k0, %2}";
5985     }
5986 }
5987   [(set (attr "type")
5988      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5989         (const_string "incdec")
5990         (const_string "alu")))
5991    (set_attr "mode" "SI")])
5992
5993 ; For comparisons against 1, -1 and 128, we may generate better code
5994 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5995 ; is matched then.  We can't accept general immediate, because for
5996 ; case of overflows,  the result is messed up.
5997 ; This pattern also don't hold of 0x80000000, since the value overflows
5998 ; when negated.
5999 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6000 ; only for comparisons not depending on it.
6001 (define_insn "*addsi_4"
6002   [(set (reg FLAGS_REG)
6003         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6004                  (match_operand:SI 2 "const_int_operand" "n")))
6005    (clobber (match_scratch:SI 0 "=rm"))]
6006   "ix86_match_ccmode (insn, CCGCmode)
6007    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6008 {
6009   switch (get_attr_type (insn))
6010     {
6011     case TYPE_INCDEC:
6012       if (operands[2] == constm1_rtx)
6013         return "inc{l}\t%0";
6014       else
6015         {
6016           gcc_assert (operands[2] == const1_rtx);
6017           return "dec{l}\t%0";
6018         }
6019
6020     default:
6021       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6024       if ((INTVAL (operands[2]) == -128
6025            || (INTVAL (operands[2]) > 0
6026                && INTVAL (operands[2]) != 128)))
6027         return "sub{l}\t{%2, %0|%0, %2}";
6028       operands[2] = GEN_INT (-INTVAL (operands[2]));
6029       return "add{l}\t{%2, %0|%0, %2}";
6030     }
6031 }
6032   [(set (attr "type")
6033      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6034         (const_string "incdec")
6035         (const_string "alu")))
6036    (set_attr "mode" "SI")])
6037
6038 (define_insn "*addsi_5"
6039   [(set (reg FLAGS_REG)
6040         (compare
6041           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6042                    (match_operand:SI 2 "general_operand" "rmni"))
6043           (const_int 0)))
6044    (clobber (match_scratch:SI 0 "=r"))]
6045   "ix86_match_ccmode (insn, CCGOCmode)
6046    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6047    /* Current assemblers are broken and do not allow @GOTOFF in
6048       ought but a memory context.  */
6049    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6050 {
6051   switch (get_attr_type (insn))
6052     {
6053     case TYPE_INCDEC:
6054       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055       if (operands[2] == const1_rtx)
6056         return "inc{l}\t%0";
6057       else
6058         {
6059           gcc_assert (operands[2] == constm1_rtx);
6060           return "dec{l}\t%0";
6061         }
6062
6063     default:
6064       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6065       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6066          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6067       if (CONST_INT_P (operands[2])
6068           && (INTVAL (operands[2]) == 128
6069               || (INTVAL (operands[2]) < 0
6070                   && INTVAL (operands[2]) != -128)))
6071         {
6072           operands[2] = GEN_INT (-INTVAL (operands[2]));
6073           return "sub{l}\t{%2, %0|%0, %2}";
6074         }
6075       return "add{l}\t{%2, %0|%0, %2}";
6076     }
6077 }
6078   [(set (attr "type")
6079      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6080         (const_string "incdec")
6081         (const_string "alu")))
6082    (set_attr "mode" "SI")])
6083
6084 (define_expand "addhi3"
6085   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6086                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6087                             (match_operand:HI 2 "general_operand" "")))
6088               (clobber (reg:CC FLAGS_REG))])]
6089   "TARGET_HIMODE_MATH"
6090   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6091
6092 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6093 ;; type optimizations enabled by define-splits.  This is not important
6094 ;; for PII, and in fact harmful because of partial register stalls.
6095
6096 (define_insn "*addhi_1_lea"
6097   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6098         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6099                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6100    (clobber (reg:CC FLAGS_REG))]
6101   "!TARGET_PARTIAL_REG_STALL
6102    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6103 {
6104   switch (get_attr_type (insn))
6105     {
6106     case TYPE_LEA:
6107       return "#";
6108     case TYPE_INCDEC:
6109       if (operands[2] == const1_rtx)
6110         return "inc{w}\t%0";
6111       else
6112         {
6113           gcc_assert (operands[2] == constm1_rtx);
6114           return "dec{w}\t%0";
6115         }
6116
6117     default:
6118       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6119          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6120       if (CONST_INT_P (operands[2])
6121           && (INTVAL (operands[2]) == 128
6122               || (INTVAL (operands[2]) < 0
6123                   && INTVAL (operands[2]) != -128)))
6124         {
6125           operands[2] = GEN_INT (-INTVAL (operands[2]));
6126           return "sub{w}\t{%2, %0|%0, %2}";
6127         }
6128       return "add{w}\t{%2, %0|%0, %2}";
6129     }
6130 }
6131   [(set (attr "type")
6132      (if_then_else (eq_attr "alternative" "2")
6133         (const_string "lea")
6134         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135            (const_string "incdec")
6136            (const_string "alu"))))
6137    (set_attr "mode" "HI,HI,SI")])
6138
6139 (define_insn "*addhi_1"
6140   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6141         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6142                  (match_operand:HI 2 "general_operand" "ri,rm")))
6143    (clobber (reg:CC FLAGS_REG))]
6144   "TARGET_PARTIAL_REG_STALL
6145    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6146 {
6147   switch (get_attr_type (insn))
6148     {
6149     case TYPE_INCDEC:
6150       if (operands[2] == const1_rtx)
6151         return "inc{w}\t%0";
6152       else
6153         {
6154           gcc_assert (operands[2] == constm1_rtx);
6155           return "dec{w}\t%0";
6156         }
6157
6158     default:
6159       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6161       if (CONST_INT_P (operands[2])
6162           && (INTVAL (operands[2]) == 128
6163               || (INTVAL (operands[2]) < 0
6164                   && INTVAL (operands[2]) != -128)))
6165         {
6166           operands[2] = GEN_INT (-INTVAL (operands[2]));
6167           return "sub{w}\t{%2, %0|%0, %2}";
6168         }
6169       return "add{w}\t{%2, %0|%0, %2}";
6170     }
6171 }
6172   [(set (attr "type")
6173      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6174         (const_string "incdec")
6175         (const_string "alu")))
6176    (set_attr "mode" "HI")])
6177
6178 (define_insn "*addhi_2"
6179   [(set (reg FLAGS_REG)
6180         (compare
6181           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6182                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6183           (const_int 0)))
6184    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6185         (plus:HI (match_dup 1) (match_dup 2)))]
6186   "ix86_match_ccmode (insn, CCGOCmode)
6187    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6188 {
6189   switch (get_attr_type (insn))
6190     {
6191     case TYPE_INCDEC:
6192       if (operands[2] == const1_rtx)
6193         return "inc{w}\t%0";
6194       else
6195         {
6196           gcc_assert (operands[2] == constm1_rtx);
6197           return "dec{w}\t%0";
6198         }
6199
6200     default:
6201       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6203       if (CONST_INT_P (operands[2])
6204           && (INTVAL (operands[2]) == 128
6205               || (INTVAL (operands[2]) < 0
6206                   && INTVAL (operands[2]) != -128)))
6207         {
6208           operands[2] = GEN_INT (-INTVAL (operands[2]));
6209           return "sub{w}\t{%2, %0|%0, %2}";
6210         }
6211       return "add{w}\t{%2, %0|%0, %2}";
6212     }
6213 }
6214   [(set (attr "type")
6215      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6216         (const_string "incdec")
6217         (const_string "alu")))
6218    (set_attr "mode" "HI")])
6219
6220 (define_insn "*addhi_3"
6221   [(set (reg FLAGS_REG)
6222         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6223                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6224    (clobber (match_scratch:HI 0 "=r"))]
6225   "ix86_match_ccmode (insn, CCZmode)
6226    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6227 {
6228   switch (get_attr_type (insn))
6229     {
6230     case TYPE_INCDEC:
6231       if (operands[2] == const1_rtx)
6232         return "inc{w}\t%0";
6233       else
6234         {
6235           gcc_assert (operands[2] == constm1_rtx);
6236           return "dec{w}\t%0";
6237         }
6238
6239     default:
6240       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6242       if (CONST_INT_P (operands[2])
6243           && (INTVAL (operands[2]) == 128
6244               || (INTVAL (operands[2]) < 0
6245                   && INTVAL (operands[2]) != -128)))
6246         {
6247           operands[2] = GEN_INT (-INTVAL (operands[2]));
6248           return "sub{w}\t{%2, %0|%0, %2}";
6249         }
6250       return "add{w}\t{%2, %0|%0, %2}";
6251     }
6252 }
6253   [(set (attr "type")
6254      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255         (const_string "incdec")
6256         (const_string "alu")))
6257    (set_attr "mode" "HI")])
6258
6259 ; See comments above addsi_4 for details.
6260 (define_insn "*addhi_4"
6261   [(set (reg FLAGS_REG)
6262         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6263                  (match_operand:HI 2 "const_int_operand" "n")))
6264    (clobber (match_scratch:HI 0 "=rm"))]
6265   "ix86_match_ccmode (insn, CCGCmode)
6266    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6267 {
6268   switch (get_attr_type (insn))
6269     {
6270     case TYPE_INCDEC:
6271       if (operands[2] == constm1_rtx)
6272         return "inc{w}\t%0";
6273       else
6274         {
6275           gcc_assert (operands[2] == const1_rtx);
6276           return "dec{w}\t%0";
6277         }
6278
6279     default:
6280       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6281       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6283       if ((INTVAL (operands[2]) == -128
6284            || (INTVAL (operands[2]) > 0
6285                && INTVAL (operands[2]) != 128)))
6286         return "sub{w}\t{%2, %0|%0, %2}";
6287       operands[2] = GEN_INT (-INTVAL (operands[2]));
6288       return "add{w}\t{%2, %0|%0, %2}";
6289     }
6290 }
6291   [(set (attr "type")
6292      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6293         (const_string "incdec")
6294         (const_string "alu")))
6295    (set_attr "mode" "SI")])
6296
6297
6298 (define_insn "*addhi_5"
6299   [(set (reg FLAGS_REG)
6300         (compare
6301           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6302                    (match_operand:HI 2 "general_operand" "rmni"))
6303           (const_int 0)))
6304    (clobber (match_scratch:HI 0 "=r"))]
6305   "ix86_match_ccmode (insn, CCGOCmode)
6306    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6307 {
6308   switch (get_attr_type (insn))
6309     {
6310     case TYPE_INCDEC:
6311       if (operands[2] == const1_rtx)
6312         return "inc{w}\t%0";
6313       else
6314         {
6315           gcc_assert (operands[2] == constm1_rtx);
6316           return "dec{w}\t%0";
6317         }
6318
6319     default:
6320       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6321          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6322       if (CONST_INT_P (operands[2])
6323           && (INTVAL (operands[2]) == 128
6324               || (INTVAL (operands[2]) < 0
6325                   && INTVAL (operands[2]) != -128)))
6326         {
6327           operands[2] = GEN_INT (-INTVAL (operands[2]));
6328           return "sub{w}\t{%2, %0|%0, %2}";
6329         }
6330       return "add{w}\t{%2, %0|%0, %2}";
6331     }
6332 }
6333   [(set (attr "type")
6334      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6335         (const_string "incdec")
6336         (const_string "alu")))
6337    (set_attr "mode" "HI")])
6338
6339 (define_expand "addqi3"
6340   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6341                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6342                             (match_operand:QI 2 "general_operand" "")))
6343               (clobber (reg:CC FLAGS_REG))])]
6344   "TARGET_QIMODE_MATH"
6345   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6346
6347 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6348 (define_insn "*addqi_1_lea"
6349   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6350         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6351                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6352    (clobber (reg:CC FLAGS_REG))]
6353   "!TARGET_PARTIAL_REG_STALL
6354    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6355 {
6356   int widen = (which_alternative == 2);
6357   switch (get_attr_type (insn))
6358     {
6359     case TYPE_LEA:
6360       return "#";
6361     case TYPE_INCDEC:
6362       if (operands[2] == const1_rtx)
6363         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6364       else
6365         {
6366           gcc_assert (operands[2] == constm1_rtx);
6367           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6368         }
6369
6370     default:
6371       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6372          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6373       if (CONST_INT_P (operands[2])
6374           && (INTVAL (operands[2]) == 128
6375               || (INTVAL (operands[2]) < 0
6376                   && INTVAL (operands[2]) != -128)))
6377         {
6378           operands[2] = GEN_INT (-INTVAL (operands[2]));
6379           if (widen)
6380             return "sub{l}\t{%2, %k0|%k0, %2}";
6381           else
6382             return "sub{b}\t{%2, %0|%0, %2}";
6383         }
6384       if (widen)
6385         return "add{l}\t{%k2, %k0|%k0, %k2}";
6386       else
6387         return "add{b}\t{%2, %0|%0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (eq_attr "alternative" "3")
6392         (const_string "lea")
6393         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394            (const_string "incdec")
6395            (const_string "alu"))))
6396    (set_attr "mode" "QI,QI,SI,SI")])
6397
6398 (define_insn "*addqi_1"
6399   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6400         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6401                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6402    (clobber (reg:CC FLAGS_REG))]
6403   "TARGET_PARTIAL_REG_STALL
6404    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6405 {
6406   int widen = (which_alternative == 2);
6407   switch (get_attr_type (insn))
6408     {
6409     case TYPE_INCDEC:
6410       if (operands[2] == const1_rtx)
6411         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6412       else
6413         {
6414           gcc_assert (operands[2] == constm1_rtx);
6415           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6416         }
6417
6418     default:
6419       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6420          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6421       if (CONST_INT_P (operands[2])
6422           && (INTVAL (operands[2]) == 128
6423               || (INTVAL (operands[2]) < 0
6424                   && INTVAL (operands[2]) != -128)))
6425         {
6426           operands[2] = GEN_INT (-INTVAL (operands[2]));
6427           if (widen)
6428             return "sub{l}\t{%2, %k0|%k0, %2}";
6429           else
6430             return "sub{b}\t{%2, %0|%0, %2}";
6431         }
6432       if (widen)
6433         return "add{l}\t{%k2, %k0|%k0, %k2}";
6434       else
6435         return "add{b}\t{%2, %0|%0, %2}";
6436     }
6437 }
6438   [(set (attr "type")
6439      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440         (const_string "incdec")
6441         (const_string "alu")))
6442    (set_attr "mode" "QI,QI,SI")])
6443
6444 (define_insn "*addqi_1_slp"
6445   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6446         (plus:QI (match_dup 0)
6447                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6448    (clobber (reg:CC FLAGS_REG))]
6449   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6450    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6451 {
6452   switch (get_attr_type (insn))
6453     {
6454     case TYPE_INCDEC:
6455       if (operands[1] == const1_rtx)
6456         return "inc{b}\t%0";
6457       else
6458         {
6459           gcc_assert (operands[1] == constm1_rtx);
6460           return "dec{b}\t%0";
6461         }
6462
6463     default:
6464       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6465       if (CONST_INT_P (operands[1])
6466           && INTVAL (operands[1]) < 0)
6467         {
6468           operands[1] = GEN_INT (-INTVAL (operands[1]));
6469           return "sub{b}\t{%1, %0|%0, %1}";
6470         }
6471       return "add{b}\t{%1, %0|%0, %1}";
6472     }
6473 }
6474   [(set (attr "type")
6475      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6476         (const_string "incdec")
6477         (const_string "alu1")))
6478    (set (attr "memory")
6479      (if_then_else (match_operand 1 "memory_operand" "")
6480         (const_string "load")
6481         (const_string "none")))
6482    (set_attr "mode" "QI")])
6483
6484 (define_insn "*addqi_2"
6485   [(set (reg FLAGS_REG)
6486         (compare
6487           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6488                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6489           (const_int 0)))
6490    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6491         (plus:QI (match_dup 1) (match_dup 2)))]
6492   "ix86_match_ccmode (insn, CCGOCmode)
6493    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6494 {
6495   switch (get_attr_type (insn))
6496     {
6497     case TYPE_INCDEC:
6498       if (operands[2] == const1_rtx)
6499         return "inc{b}\t%0";
6500       else
6501         {
6502           gcc_assert (operands[2] == constm1_rtx
6503                       || (CONST_INT_P (operands[2])
6504                           && INTVAL (operands[2]) == 255));
6505           return "dec{b}\t%0";
6506         }
6507
6508     default:
6509       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6510       if (CONST_INT_P (operands[2])
6511           && INTVAL (operands[2]) < 0)
6512         {
6513           operands[2] = GEN_INT (-INTVAL (operands[2]));
6514           return "sub{b}\t{%2, %0|%0, %2}";
6515         }
6516       return "add{b}\t{%2, %0|%0, %2}";
6517     }
6518 }
6519   [(set (attr "type")
6520      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521         (const_string "incdec")
6522         (const_string "alu")))
6523    (set_attr "mode" "QI")])
6524
6525 (define_insn "*addqi_3"
6526   [(set (reg FLAGS_REG)
6527         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6528                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6529    (clobber (match_scratch:QI 0 "=q"))]
6530   "ix86_match_ccmode (insn, CCZmode)
6531    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6532 {
6533   switch (get_attr_type (insn))
6534     {
6535     case TYPE_INCDEC:
6536       if (operands[2] == const1_rtx)
6537         return "inc{b}\t%0";
6538       else
6539         {
6540           gcc_assert (operands[2] == constm1_rtx
6541                       || (CONST_INT_P (operands[2])
6542                           && INTVAL (operands[2]) == 255));
6543           return "dec{b}\t%0";
6544         }
6545
6546     default:
6547       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6548       if (CONST_INT_P (operands[2])
6549           && INTVAL (operands[2]) < 0)
6550         {
6551           operands[2] = GEN_INT (-INTVAL (operands[2]));
6552           return "sub{b}\t{%2, %0|%0, %2}";
6553         }
6554       return "add{b}\t{%2, %0|%0, %2}";
6555     }
6556 }
6557   [(set (attr "type")
6558      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6559         (const_string "incdec")
6560         (const_string "alu")))
6561    (set_attr "mode" "QI")])
6562
6563 ; See comments above addsi_4 for details.
6564 (define_insn "*addqi_4"
6565   [(set (reg FLAGS_REG)
6566         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6567                  (match_operand:QI 2 "const_int_operand" "n")))
6568    (clobber (match_scratch:QI 0 "=qm"))]
6569   "ix86_match_ccmode (insn, CCGCmode)
6570    && (INTVAL (operands[2]) & 0xff) != 0x80"
6571 {
6572   switch (get_attr_type (insn))
6573     {
6574     case TYPE_INCDEC:
6575       if (operands[2] == constm1_rtx
6576           || (CONST_INT_P (operands[2])
6577               && INTVAL (operands[2]) == 255))
6578         return "inc{b}\t%0";
6579       else
6580         {
6581           gcc_assert (operands[2] == const1_rtx);
6582           return "dec{b}\t%0";
6583         }
6584
6585     default:
6586       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587       if (INTVAL (operands[2]) < 0)
6588         {
6589           operands[2] = GEN_INT (-INTVAL (operands[2]));
6590           return "add{b}\t{%2, %0|%0, %2}";
6591         }
6592       return "sub{b}\t{%2, %0|%0, %2}";
6593     }
6594 }
6595   [(set (attr "type")
6596      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6597         (const_string "incdec")
6598         (const_string "alu")))
6599    (set_attr "mode" "QI")])
6600
6601
6602 (define_insn "*addqi_5"
6603   [(set (reg FLAGS_REG)
6604         (compare
6605           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6606                    (match_operand:QI 2 "general_operand" "qmni"))
6607           (const_int 0)))
6608    (clobber (match_scratch:QI 0 "=q"))]
6609   "ix86_match_ccmode (insn, CCGOCmode)
6610    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6611 {
6612   switch (get_attr_type (insn))
6613     {
6614     case TYPE_INCDEC:
6615       if (operands[2] == const1_rtx)
6616         return "inc{b}\t%0";
6617       else
6618         {
6619           gcc_assert (operands[2] == constm1_rtx
6620                       || (CONST_INT_P (operands[2])
6621                           && INTVAL (operands[2]) == 255));
6622           return "dec{b}\t%0";
6623         }
6624
6625     default:
6626       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6627       if (CONST_INT_P (operands[2])
6628           && INTVAL (operands[2]) < 0)
6629         {
6630           operands[2] = GEN_INT (-INTVAL (operands[2]));
6631           return "sub{b}\t{%2, %0|%0, %2}";
6632         }
6633       return "add{b}\t{%2, %0|%0, %2}";
6634     }
6635 }
6636   [(set (attr "type")
6637      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6638         (const_string "incdec")
6639         (const_string "alu")))
6640    (set_attr "mode" "QI")])
6641
6642
6643 (define_insn "addqi_ext_1"
6644   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6645                          (const_int 8)
6646                          (const_int 8))
6647         (plus:SI
6648           (zero_extract:SI
6649             (match_operand 1 "ext_register_operand" "0")
6650             (const_int 8)
6651             (const_int 8))
6652           (match_operand:QI 2 "general_operand" "Qmn")))
6653    (clobber (reg:CC FLAGS_REG))]
6654   "!TARGET_64BIT"
6655 {
6656   switch (get_attr_type (insn))
6657     {
6658     case TYPE_INCDEC:
6659       if (operands[2] == const1_rtx)
6660         return "inc{b}\t%h0";
6661       else
6662         {
6663           gcc_assert (operands[2] == constm1_rtx
6664                       || (CONST_INT_P (operands[2])
6665                           && INTVAL (operands[2]) == 255));
6666           return "dec{b}\t%h0";
6667         }
6668
6669     default:
6670       return "add{b}\t{%2, %h0|%h0, %2}";
6671     }
6672 }
6673   [(set (attr "type")
6674      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6675         (const_string "incdec")
6676         (const_string "alu")))
6677    (set_attr "mode" "QI")])
6678
6679 (define_insn "*addqi_ext_1_rex64"
6680   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6681                          (const_int 8)
6682                          (const_int 8))
6683         (plus:SI
6684           (zero_extract:SI
6685             (match_operand 1 "ext_register_operand" "0")
6686             (const_int 8)
6687             (const_int 8))
6688           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6689    (clobber (reg:CC FLAGS_REG))]
6690   "TARGET_64BIT"
6691 {
6692   switch (get_attr_type (insn))
6693     {
6694     case TYPE_INCDEC:
6695       if (operands[2] == const1_rtx)
6696         return "inc{b}\t%h0";
6697       else
6698         {
6699           gcc_assert (operands[2] == constm1_rtx
6700                       || (CONST_INT_P (operands[2])
6701                           && INTVAL (operands[2]) == 255));
6702           return "dec{b}\t%h0";
6703         }
6704
6705     default:
6706       return "add{b}\t{%2, %h0|%h0, %2}";
6707     }
6708 }
6709   [(set (attr "type")
6710      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6711         (const_string "incdec")
6712         (const_string "alu")))
6713    (set_attr "mode" "QI")])
6714
6715 (define_insn "*addqi_ext_2"
6716   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6717                          (const_int 8)
6718                          (const_int 8))
6719         (plus:SI
6720           (zero_extract:SI
6721             (match_operand 1 "ext_register_operand" "%0")
6722             (const_int 8)
6723             (const_int 8))
6724           (zero_extract:SI
6725             (match_operand 2 "ext_register_operand" "Q")
6726             (const_int 8)
6727             (const_int 8))))
6728    (clobber (reg:CC FLAGS_REG))]
6729   ""
6730   "add{b}\t{%h2, %h0|%h0, %h2}"
6731   [(set_attr "type" "alu")
6732    (set_attr "mode" "QI")])
6733
6734 ;; The patterns that match these are at the end of this file.
6735
6736 (define_expand "addxf3"
6737   [(set (match_operand:XF 0 "register_operand" "")
6738         (plus:XF (match_operand:XF 1 "register_operand" "")
6739                  (match_operand:XF 2 "register_operand" "")))]
6740   "TARGET_80387"
6741   "")
6742
6743 (define_expand "adddf3"
6744   [(set (match_operand:DF 0 "register_operand" "")
6745         (plus:DF (match_operand:DF 1 "register_operand" "")
6746                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6747   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6748   "")
6749
6750 (define_expand "addsf3"
6751   [(set (match_operand:SF 0 "register_operand" "")
6752         (plus:SF (match_operand:SF 1 "register_operand" "")
6753                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6754   "TARGET_80387 || TARGET_SSE_MATH"
6755   "")
6756 \f
6757 ;; Subtract instructions
6758
6759 ;; %%% splits for subditi3
6760
6761 (define_expand "subti3"
6762   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6763                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6764                              (match_operand:TI 2 "x86_64_general_operand" "")))
6765               (clobber (reg:CC FLAGS_REG))])]
6766   "TARGET_64BIT"
6767   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6768
6769 (define_insn "*subti3_1"
6770   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6771         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6772                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6773    (clobber (reg:CC FLAGS_REG))]
6774   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6775   "#")
6776
6777 (define_split
6778   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6779         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6780                   (match_operand:TI 2 "general_operand" "")))
6781    (clobber (reg:CC FLAGS_REG))]
6782   "TARGET_64BIT && reload_completed"
6783   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6784               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6785    (parallel [(set (match_dup 3)
6786                    (minus:DI (match_dup 4)
6787                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6788                                       (match_dup 5))))
6789               (clobber (reg:CC FLAGS_REG))])]
6790   "split_ti (operands+0, 1, operands+0, operands+3);
6791    split_ti (operands+1, 1, operands+1, operands+4);
6792    split_ti (operands+2, 1, operands+2, operands+5);")
6793
6794 ;; %%% splits for subsidi3
6795
6796 (define_expand "subdi3"
6797   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6798                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6799                              (match_operand:DI 2 "x86_64_general_operand" "")))
6800               (clobber (reg:CC FLAGS_REG))])]
6801   ""
6802   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6803
6804 (define_insn "*subdi3_1"
6805   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6806         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6807                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6808    (clobber (reg:CC FLAGS_REG))]
6809   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6810   "#")
6811
6812 (define_split
6813   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6814         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6815                   (match_operand:DI 2 "general_operand" "")))
6816    (clobber (reg:CC FLAGS_REG))]
6817   "!TARGET_64BIT && reload_completed"
6818   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6819               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6820    (parallel [(set (match_dup 3)
6821                    (minus:SI (match_dup 4)
6822                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6823                                       (match_dup 5))))
6824               (clobber (reg:CC FLAGS_REG))])]
6825   "split_di (operands+0, 1, operands+0, operands+3);
6826    split_di (operands+1, 1, operands+1, operands+4);
6827    split_di (operands+2, 1, operands+2, operands+5);")
6828
6829 (define_insn "subdi3_carry_rex64"
6830   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6831           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6832             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6833                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6834    (clobber (reg:CC FLAGS_REG))]
6835   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6836   "sbb{q}\t{%2, %0|%0, %2}"
6837   [(set_attr "type" "alu")
6838    (set_attr "pent_pair" "pu")
6839    (set_attr "mode" "DI")])
6840
6841 (define_insn "*subdi_1_rex64"
6842   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6843         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6844                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6845    (clobber (reg:CC FLAGS_REG))]
6846   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6847   "sub{q}\t{%2, %0|%0, %2}"
6848   [(set_attr "type" "alu")
6849    (set_attr "mode" "DI")])
6850
6851 (define_insn "*subdi_2_rex64"
6852   [(set (reg FLAGS_REG)
6853         (compare
6854           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6855                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6856           (const_int 0)))
6857    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858         (minus:DI (match_dup 1) (match_dup 2)))]
6859   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6860    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6861   "sub{q}\t{%2, %0|%0, %2}"
6862   [(set_attr "type" "alu")
6863    (set_attr "mode" "DI")])
6864
6865 (define_insn "*subdi_3_rex63"
6866   [(set (reg FLAGS_REG)
6867         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6869    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870         (minus:DI (match_dup 1) (match_dup 2)))]
6871   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6872    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6873   "sub{q}\t{%2, %0|%0, %2}"
6874   [(set_attr "type" "alu")
6875    (set_attr "mode" "DI")])
6876
6877 (define_insn "subqi3_carry"
6878   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6881                (match_operand:QI 2 "general_operand" "qi,qm"))))
6882    (clobber (reg:CC FLAGS_REG))]
6883   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6884   "sbb{b}\t{%2, %0|%0, %2}"
6885   [(set_attr "type" "alu")
6886    (set_attr "pent_pair" "pu")
6887    (set_attr "mode" "QI")])
6888
6889 (define_insn "subhi3_carry"
6890   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6891           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6892             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6893                (match_operand:HI 2 "general_operand" "ri,rm"))))
6894    (clobber (reg:CC FLAGS_REG))]
6895   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6896   "sbb{w}\t{%2, %0|%0, %2}"
6897   [(set_attr "type" "alu")
6898    (set_attr "pent_pair" "pu")
6899    (set_attr "mode" "HI")])
6900
6901 (define_insn "subsi3_carry"
6902   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6903           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6904             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6905                (match_operand:SI 2 "general_operand" "ri,rm"))))
6906    (clobber (reg:CC FLAGS_REG))]
6907   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6908   "sbb{l}\t{%2, %0|%0, %2}"
6909   [(set_attr "type" "alu")
6910    (set_attr "pent_pair" "pu")
6911    (set_attr "mode" "SI")])
6912
6913 (define_insn "subsi3_carry_zext"
6914   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6915           (zero_extend:DI
6916             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6917               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6919    (clobber (reg:CC FLAGS_REG))]
6920   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6921   "sbb{l}\t{%2, %k0|%k0, %2}"
6922   [(set_attr "type" "alu")
6923    (set_attr "pent_pair" "pu")
6924    (set_attr "mode" "SI")])
6925
6926 (define_expand "subsi3"
6927   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6928                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6929                              (match_operand:SI 2 "general_operand" "")))
6930               (clobber (reg:CC FLAGS_REG))])]
6931   ""
6932   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6933
6934 (define_insn "*subsi_1"
6935   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6936         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6937                   (match_operand:SI 2 "general_operand" "ri,rm")))
6938    (clobber (reg:CC FLAGS_REG))]
6939   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6940   "sub{l}\t{%2, %0|%0, %2}"
6941   [(set_attr "type" "alu")
6942    (set_attr "mode" "SI")])
6943
6944 (define_insn "*subsi_1_zext"
6945   [(set (match_operand:DI 0 "register_operand" "=r")
6946         (zero_extend:DI
6947           (minus:SI (match_operand:SI 1 "register_operand" "0")
6948                     (match_operand:SI 2 "general_operand" "rim"))))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951   "sub{l}\t{%2, %k0|%k0, %2}"
6952   [(set_attr "type" "alu")
6953    (set_attr "mode" "SI")])
6954
6955 (define_insn "*subsi_2"
6956   [(set (reg FLAGS_REG)
6957         (compare
6958           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6959                     (match_operand:SI 2 "general_operand" "ri,rm"))
6960           (const_int 0)))
6961    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6962         (minus:SI (match_dup 1) (match_dup 2)))]
6963   "ix86_match_ccmode (insn, CCGOCmode)
6964    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6965   "sub{l}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "alu")
6967    (set_attr "mode" "SI")])
6968
6969 (define_insn "*subsi_2_zext"
6970   [(set (reg FLAGS_REG)
6971         (compare
6972           (minus:SI (match_operand:SI 1 "register_operand" "0")
6973                     (match_operand:SI 2 "general_operand" "rim"))
6974           (const_int 0)))
6975    (set (match_operand:DI 0 "register_operand" "=r")
6976         (zero_extend:DI
6977           (minus:SI (match_dup 1)
6978                     (match_dup 2))))]
6979   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6980    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6981   "sub{l}\t{%2, %k0|%k0, %2}"
6982   [(set_attr "type" "alu")
6983    (set_attr "mode" "SI")])
6984
6985 (define_insn "*subsi_3"
6986   [(set (reg FLAGS_REG)
6987         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6988                  (match_operand:SI 2 "general_operand" "ri,rm")))
6989    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6990         (minus:SI (match_dup 1) (match_dup 2)))]
6991   "ix86_match_ccmode (insn, CCmode)
6992    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6993   "sub{l}\t{%2, %0|%0, %2}"
6994   [(set_attr "type" "alu")
6995    (set_attr "mode" "SI")])
6996
6997 (define_insn "*subsi_3_zext"
6998   [(set (reg FLAGS_REG)
6999         (compare (match_operand:SI 1 "register_operand" "0")
7000                  (match_operand:SI 2 "general_operand" "rim")))
7001    (set (match_operand:DI 0 "register_operand" "=r")
7002         (zero_extend:DI
7003           (minus:SI (match_dup 1)
7004                     (match_dup 2))))]
7005   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7006    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7007   "sub{l}\t{%2, %1|%1, %2}"
7008   [(set_attr "type" "alu")
7009    (set_attr "mode" "DI")])
7010
7011 (define_expand "subhi3"
7012   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7013                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7014                              (match_operand:HI 2 "general_operand" "")))
7015               (clobber (reg:CC FLAGS_REG))])]
7016   "TARGET_HIMODE_MATH"
7017   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7018
7019 (define_insn "*subhi_1"
7020   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7021         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7022                   (match_operand:HI 2 "general_operand" "ri,rm")))
7023    (clobber (reg:CC FLAGS_REG))]
7024   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7025   "sub{w}\t{%2, %0|%0, %2}"
7026   [(set_attr "type" "alu")
7027    (set_attr "mode" "HI")])
7028
7029 (define_insn "*subhi_2"
7030   [(set (reg FLAGS_REG)
7031         (compare
7032           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7033                     (match_operand:HI 2 "general_operand" "ri,rm"))
7034           (const_int 0)))
7035    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7036         (minus:HI (match_dup 1) (match_dup 2)))]
7037   "ix86_match_ccmode (insn, CCGOCmode)
7038    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7039   "sub{w}\t{%2, %0|%0, %2}"
7040   [(set_attr "type" "alu")
7041    (set_attr "mode" "HI")])
7042
7043 (define_insn "*subhi_3"
7044   [(set (reg FLAGS_REG)
7045         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046                  (match_operand:HI 2 "general_operand" "ri,rm")))
7047    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048         (minus:HI (match_dup 1) (match_dup 2)))]
7049   "ix86_match_ccmode (insn, CCmode)
7050    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7051   "sub{w}\t{%2, %0|%0, %2}"
7052   [(set_attr "type" "alu")
7053    (set_attr "mode" "HI")])
7054
7055 (define_expand "subqi3"
7056   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058                              (match_operand:QI 2 "general_operand" "")))
7059               (clobber (reg:CC FLAGS_REG))])]
7060   "TARGET_QIMODE_MATH"
7061   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7062
7063 (define_insn "*subqi_1"
7064   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7065         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7066                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7067    (clobber (reg:CC FLAGS_REG))]
7068   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7069   "sub{b}\t{%2, %0|%0, %2}"
7070   [(set_attr "type" "alu")
7071    (set_attr "mode" "QI")])
7072
7073 (define_insn "*subqi_1_slp"
7074   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7075         (minus:QI (match_dup 0)
7076                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7077    (clobber (reg:CC FLAGS_REG))]
7078   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7079    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7080   "sub{b}\t{%1, %0|%0, %1}"
7081   [(set_attr "type" "alu1")
7082    (set_attr "mode" "QI")])
7083
7084 (define_insn "*subqi_2"
7085   [(set (reg FLAGS_REG)
7086         (compare
7087           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7088                     (match_operand:QI 2 "general_operand" "qi,qm"))
7089           (const_int 0)))
7090    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7091         (minus:HI (match_dup 1) (match_dup 2)))]
7092   "ix86_match_ccmode (insn, CCGOCmode)
7093    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7094   "sub{b}\t{%2, %0|%0, %2}"
7095   [(set_attr "type" "alu")
7096    (set_attr "mode" "QI")])
7097
7098 (define_insn "*subqi_3"
7099   [(set (reg FLAGS_REG)
7100         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101                  (match_operand:QI 2 "general_operand" "qi,qm")))
7102    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7103         (minus:HI (match_dup 1) (match_dup 2)))]
7104   "ix86_match_ccmode (insn, CCmode)
7105    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7106   "sub{b}\t{%2, %0|%0, %2}"
7107   [(set_attr "type" "alu")
7108    (set_attr "mode" "QI")])
7109
7110 ;; The patterns that match these are at the end of this file.
7111
7112 (define_expand "subxf3"
7113   [(set (match_operand:XF 0 "register_operand" "")
7114         (minus:XF (match_operand:XF 1 "register_operand" "")
7115                   (match_operand:XF 2 "register_operand" "")))]
7116   "TARGET_80387"
7117   "")
7118
7119 (define_expand "subdf3"
7120   [(set (match_operand:DF 0 "register_operand" "")
7121         (minus:DF (match_operand:DF 1 "register_operand" "")
7122                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7123   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7124   "")
7125
7126 (define_expand "subsf3"
7127   [(set (match_operand:SF 0 "register_operand" "")
7128         (minus:SF (match_operand:SF 1 "register_operand" "")
7129                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7130   "TARGET_80387 || TARGET_SSE_MATH"
7131   "")
7132 \f
7133 ;; Multiply instructions
7134
7135 (define_expand "muldi3"
7136   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137                    (mult:DI (match_operand:DI 1 "register_operand" "")
7138                             (match_operand:DI 2 "x86_64_general_operand" "")))
7139               (clobber (reg:CC FLAGS_REG))])]
7140   "TARGET_64BIT"
7141   "")
7142
7143 ;; On AMDFAM10 
7144 ;; IMUL reg64, reg64, imm8      Direct
7145 ;; IMUL reg64, mem64, imm8      VectorPath
7146 ;; IMUL reg64, reg64, imm32     Direct
7147 ;; IMUL reg64, mem64, imm32     VectorPath 
7148 ;; IMUL reg64, reg64            Direct
7149 ;; IMUL reg64, mem64            Direct
7150
7151 (define_insn "*muldi3_1_rex64"
7152   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7153         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7154                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7155    (clobber (reg:CC FLAGS_REG))]
7156   "TARGET_64BIT
7157    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7158   "@
7159    imul{q}\t{%2, %1, %0|%0, %1, %2}
7160    imul{q}\t{%2, %1, %0|%0, %1, %2}
7161    imul{q}\t{%2, %0|%0, %2}"
7162   [(set_attr "type" "imul")
7163    (set_attr "prefix_0f" "0,0,1")
7164    (set (attr "athlon_decode")
7165         (cond [(eq_attr "cpu" "athlon")
7166                   (const_string "vector")
7167                (eq_attr "alternative" "1")
7168                   (const_string "vector")
7169                (and (eq_attr "alternative" "2")
7170                     (match_operand 1 "memory_operand" ""))
7171                   (const_string "vector")]
7172               (const_string "direct")))
7173    (set (attr "amdfam10_decode")
7174         (cond [(and (eq_attr "alternative" "0,1")
7175                     (match_operand 1 "memory_operand" ""))
7176                   (const_string "vector")]
7177               (const_string "direct")))       
7178    (set_attr "mode" "DI")])
7179
7180 (define_expand "mulsi3"
7181   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182                    (mult:SI (match_operand:SI 1 "register_operand" "")
7183                             (match_operand:SI 2 "general_operand" "")))
7184               (clobber (reg:CC FLAGS_REG))])]
7185   ""
7186   "")
7187
7188 ;; On AMDFAM10 
7189 ;; IMUL reg32, reg32, imm8      Direct
7190 ;; IMUL reg32, mem32, imm8      VectorPath
7191 ;; IMUL reg32, reg32, imm32     Direct
7192 ;; IMUL reg32, mem32, imm32     VectorPath
7193 ;; IMUL reg32, reg32            Direct
7194 ;; IMUL reg32, mem32            Direct
7195
7196 (define_insn "*mulsi3_1"
7197   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7198         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7199                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7200    (clobber (reg:CC FLAGS_REG))]
7201   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7202   "@
7203    imul{l}\t{%2, %1, %0|%0, %1, %2}
7204    imul{l}\t{%2, %1, %0|%0, %1, %2}
7205    imul{l}\t{%2, %0|%0, %2}"
7206   [(set_attr "type" "imul")
7207    (set_attr "prefix_0f" "0,0,1")
7208    (set (attr "athlon_decode")
7209         (cond [(eq_attr "cpu" "athlon")
7210                   (const_string "vector")
7211                (eq_attr "alternative" "1")
7212                   (const_string "vector")
7213                (and (eq_attr "alternative" "2")
7214                     (match_operand 1 "memory_operand" ""))
7215                   (const_string "vector")]
7216               (const_string "direct")))
7217    (set (attr "amdfam10_decode")
7218         (cond [(and (eq_attr "alternative" "0,1")
7219                     (match_operand 1 "memory_operand" ""))
7220                   (const_string "vector")]
7221               (const_string "direct")))       
7222    (set_attr "mode" "SI")])
7223
7224 (define_insn "*mulsi3_1_zext"
7225   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7226         (zero_extend:DI
7227           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7228                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7229    (clobber (reg:CC FLAGS_REG))]
7230   "TARGET_64BIT
7231    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7232   "@
7233    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7234    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7235    imul{l}\t{%2, %k0|%k0, %2}"
7236   [(set_attr "type" "imul")
7237    (set_attr "prefix_0f" "0,0,1")
7238    (set (attr "athlon_decode")
7239         (cond [(eq_attr "cpu" "athlon")
7240                   (const_string "vector")
7241                (eq_attr "alternative" "1")
7242                   (const_string "vector")
7243                (and (eq_attr "alternative" "2")
7244                     (match_operand 1 "memory_operand" ""))
7245                   (const_string "vector")]
7246               (const_string "direct")))
7247    (set (attr "amdfam10_decode")
7248         (cond [(and (eq_attr "alternative" "0,1")
7249                     (match_operand 1 "memory_operand" ""))
7250                   (const_string "vector")]
7251               (const_string "direct")))       
7252    (set_attr "mode" "SI")])
7253
7254 (define_expand "mulhi3"
7255   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7256                    (mult:HI (match_operand:HI 1 "register_operand" "")
7257                             (match_operand:HI 2 "general_operand" "")))
7258               (clobber (reg:CC FLAGS_REG))])]
7259   "TARGET_HIMODE_MATH"
7260   "")
7261
7262 ;; On AMDFAM10
7263 ;; IMUL reg16, reg16, imm8      VectorPath
7264 ;; IMUL reg16, mem16, imm8      VectorPath
7265 ;; IMUL reg16, reg16, imm16     VectorPath
7266 ;; IMUL reg16, mem16, imm16     VectorPath
7267 ;; IMUL reg16, reg16            Direct
7268 ;; IMUL reg16, mem16            Direct
7269 (define_insn "*mulhi3_1"
7270   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7271         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7272                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7273    (clobber (reg:CC FLAGS_REG))]
7274   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7275   "@
7276    imul{w}\t{%2, %1, %0|%0, %1, %2}
7277    imul{w}\t{%2, %1, %0|%0, %1, %2}
7278    imul{w}\t{%2, %0|%0, %2}"
7279   [(set_attr "type" "imul")
7280    (set_attr "prefix_0f" "0,0,1")
7281    (set (attr "athlon_decode")
7282         (cond [(eq_attr "cpu" "athlon")
7283                   (const_string "vector")
7284                (eq_attr "alternative" "1,2")
7285                   (const_string "vector")]
7286               (const_string "direct")))
7287    (set (attr "amdfam10_decode")
7288         (cond [(eq_attr "alternative" "0,1")
7289                   (const_string "vector")]
7290               (const_string "direct")))
7291    (set_attr "mode" "HI")])
7292
7293 (define_expand "mulqi3"
7294   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7296                             (match_operand:QI 2 "register_operand" "")))
7297               (clobber (reg:CC FLAGS_REG))])]
7298   "TARGET_QIMODE_MATH"
7299   "")
7300
7301 ;;On AMDFAM10
7302 ;; MUL reg8     Direct
7303 ;; MUL mem8     Direct
7304
7305 (define_insn "*mulqi3_1"
7306   [(set (match_operand:QI 0 "register_operand" "=a")
7307         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7308                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7309    (clobber (reg:CC FLAGS_REG))]
7310   "TARGET_QIMODE_MATH
7311    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7312   "mul{b}\t%2"
7313   [(set_attr "type" "imul")
7314    (set_attr "length_immediate" "0")
7315    (set (attr "athlon_decode")
7316      (if_then_else (eq_attr "cpu" "athlon")
7317         (const_string "vector")
7318         (const_string "direct")))
7319    (set_attr "amdfam10_decode" "direct")        
7320    (set_attr "mode" "QI")])
7321
7322 (define_expand "umulqihi3"
7323   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7324                    (mult:HI (zero_extend:HI
7325                               (match_operand:QI 1 "nonimmediate_operand" ""))
7326                             (zero_extend:HI
7327                               (match_operand:QI 2 "register_operand" ""))))
7328               (clobber (reg:CC FLAGS_REG))])]
7329   "TARGET_QIMODE_MATH"
7330   "")
7331
7332 (define_insn "*umulqihi3_1"
7333   [(set (match_operand:HI 0 "register_operand" "=a")
7334         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7335                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_QIMODE_MATH
7338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7339   "mul{b}\t%2"
7340   [(set_attr "type" "imul")
7341    (set_attr "length_immediate" "0")
7342    (set (attr "athlon_decode")
7343      (if_then_else (eq_attr "cpu" "athlon")
7344         (const_string "vector")
7345         (const_string "direct")))
7346    (set_attr "amdfam10_decode" "direct")        
7347    (set_attr "mode" "QI")])
7348
7349 (define_expand "mulqihi3"
7350   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7352                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7353               (clobber (reg:CC FLAGS_REG))])]
7354   "TARGET_QIMODE_MATH"
7355   "")
7356
7357 (define_insn "*mulqihi3_insn"
7358   [(set (match_operand:HI 0 "register_operand" "=a")
7359         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7360                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7361    (clobber (reg:CC FLAGS_REG))]
7362   "TARGET_QIMODE_MATH
7363    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7364   "imul{b}\t%2"
7365   [(set_attr "type" "imul")
7366    (set_attr "length_immediate" "0")
7367    (set (attr "athlon_decode")
7368      (if_then_else (eq_attr "cpu" "athlon")
7369         (const_string "vector")
7370         (const_string "direct")))
7371    (set_attr "amdfam10_decode" "direct")        
7372    (set_attr "mode" "QI")])
7373
7374 (define_expand "umulditi3"
7375   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7376                    (mult:TI (zero_extend:TI
7377                               (match_operand:DI 1 "nonimmediate_operand" ""))
7378                             (zero_extend:TI
7379                               (match_operand:DI 2 "register_operand" ""))))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   "TARGET_64BIT"
7382   "")
7383
7384 (define_insn "*umulditi3_insn"
7385   [(set (match_operand:TI 0 "register_operand" "=A")
7386         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7387                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_64BIT
7390    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7391   "mul{q}\t%2"
7392   [(set_attr "type" "imul")
7393    (set_attr "length_immediate" "0")
7394    (set (attr "athlon_decode")
7395      (if_then_else (eq_attr "cpu" "athlon")
7396         (const_string "vector")
7397         (const_string "double")))
7398    (set_attr "amdfam10_decode" "double")        
7399    (set_attr "mode" "DI")])
7400
7401 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7402 (define_expand "umulsidi3"
7403   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7404                    (mult:DI (zero_extend:DI
7405                               (match_operand:SI 1 "nonimmediate_operand" ""))
7406                             (zero_extend:DI
7407                               (match_operand:SI 2 "register_operand" ""))))
7408               (clobber (reg:CC FLAGS_REG))])]
7409   "!TARGET_64BIT"
7410   "")
7411
7412 (define_insn "*umulsidi3_insn"
7413   [(set (match_operand:DI 0 "register_operand" "=A")
7414         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7415                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "!TARGET_64BIT
7418    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419   "mul{l}\t%2"
7420   [(set_attr "type" "imul")
7421    (set_attr "length_immediate" "0")
7422    (set (attr "athlon_decode")
7423      (if_then_else (eq_attr "cpu" "athlon")
7424         (const_string "vector")
7425         (const_string "double")))
7426    (set_attr "amdfam10_decode" "double")        
7427    (set_attr "mode" "SI")])
7428
7429 (define_expand "mulditi3"
7430   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7431                    (mult:TI (sign_extend:TI
7432                               (match_operand:DI 1 "nonimmediate_operand" ""))
7433                             (sign_extend:TI
7434                               (match_operand:DI 2 "register_operand" ""))))
7435               (clobber (reg:CC FLAGS_REG))])]
7436   "TARGET_64BIT"
7437   "")
7438
7439 (define_insn "*mulditi3_insn"
7440   [(set (match_operand:TI 0 "register_operand" "=A")
7441         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7442                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "TARGET_64BIT
7445    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446   "imul{q}\t%2"
7447   [(set_attr "type" "imul")
7448    (set_attr "length_immediate" "0")
7449    (set (attr "athlon_decode")
7450      (if_then_else (eq_attr "cpu" "athlon")
7451         (const_string "vector")
7452         (const_string "double")))
7453    (set_attr "amdfam10_decode" "double")
7454    (set_attr "mode" "DI")])
7455
7456 (define_expand "mulsidi3"
7457   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7458                    (mult:DI (sign_extend:DI
7459                               (match_operand:SI 1 "nonimmediate_operand" ""))
7460                             (sign_extend:DI
7461                               (match_operand:SI 2 "register_operand" ""))))
7462               (clobber (reg:CC FLAGS_REG))])]
7463   "!TARGET_64BIT"
7464   "")
7465
7466 (define_insn "*mulsidi3_insn"
7467   [(set (match_operand:DI 0 "register_operand" "=A")
7468         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7469                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "!TARGET_64BIT
7472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7473   "imul{l}\t%2"
7474   [(set_attr "type" "imul")
7475    (set_attr "length_immediate" "0")
7476    (set (attr "athlon_decode")
7477      (if_then_else (eq_attr "cpu" "athlon")
7478         (const_string "vector")
7479         (const_string "double")))
7480    (set_attr "amdfam10_decode" "double")        
7481    (set_attr "mode" "SI")])
7482
7483 (define_expand "umuldi3_highpart"
7484   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7485                    (truncate:DI
7486                      (lshiftrt:TI
7487                        (mult:TI (zero_extend:TI
7488                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7489                                 (zero_extend:TI
7490                                   (match_operand:DI 2 "register_operand" "")))
7491                        (const_int 64))))
7492               (clobber (match_scratch:DI 3 ""))
7493               (clobber (reg:CC FLAGS_REG))])]
7494   "TARGET_64BIT"
7495   "")
7496
7497 (define_insn "*umuldi3_highpart_rex64"
7498   [(set (match_operand:DI 0 "register_operand" "=d")
7499         (truncate:DI
7500           (lshiftrt:TI
7501             (mult:TI (zero_extend:TI
7502                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7503                      (zero_extend:TI
7504                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7505             (const_int 64))))
7506    (clobber (match_scratch:DI 3 "=1"))
7507    (clobber (reg:CC FLAGS_REG))]
7508   "TARGET_64BIT
7509    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7510   "mul{q}\t%2"
7511   [(set_attr "type" "imul")
7512    (set_attr "length_immediate" "0")
7513    (set (attr "athlon_decode")
7514      (if_then_else (eq_attr "cpu" "athlon")
7515         (const_string "vector")
7516         (const_string "double")))
7517    (set_attr "amdfam10_decode" "double")        
7518    (set_attr "mode" "DI")])
7519
7520 (define_expand "umulsi3_highpart"
7521   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7522                    (truncate:SI
7523                      (lshiftrt:DI
7524                        (mult:DI (zero_extend:DI
7525                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7526                                 (zero_extend:DI
7527                                   (match_operand:SI 2 "register_operand" "")))
7528                        (const_int 32))))
7529               (clobber (match_scratch:SI 3 ""))
7530               (clobber (reg:CC FLAGS_REG))])]
7531   ""
7532   "")
7533
7534 (define_insn "*umulsi3_highpart_insn"
7535   [(set (match_operand:SI 0 "register_operand" "=d")
7536         (truncate:SI
7537           (lshiftrt:DI
7538             (mult:DI (zero_extend:DI
7539                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7540                      (zero_extend:DI
7541                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7542             (const_int 32))))
7543    (clobber (match_scratch:SI 3 "=1"))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7546   "mul{l}\t%2"
7547   [(set_attr "type" "imul")
7548    (set_attr "length_immediate" "0")
7549    (set (attr "athlon_decode")
7550      (if_then_else (eq_attr "cpu" "athlon")
7551         (const_string "vector")
7552         (const_string "double")))
7553    (set_attr "amdfam10_decode" "double")
7554    (set_attr "mode" "SI")])
7555
7556 (define_insn "*umulsi3_highpart_zext"
7557   [(set (match_operand:DI 0 "register_operand" "=d")
7558         (zero_extend:DI (truncate:SI
7559           (lshiftrt:DI
7560             (mult:DI (zero_extend:DI
7561                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7562                      (zero_extend:DI
7563                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7564             (const_int 32)))))
7565    (clobber (match_scratch:SI 3 "=1"))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_64BIT
7568    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7569   "mul{l}\t%2"
7570   [(set_attr "type" "imul")
7571    (set_attr "length_immediate" "0")
7572    (set (attr "athlon_decode")
7573      (if_then_else (eq_attr "cpu" "athlon")
7574         (const_string "vector")
7575         (const_string "double")))
7576    (set_attr "amdfam10_decode" "double")
7577    (set_attr "mode" "SI")])
7578
7579 (define_expand "smuldi3_highpart"
7580   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7581                    (truncate:DI
7582                      (lshiftrt:TI
7583                        (mult:TI (sign_extend:TI
7584                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7585                                 (sign_extend:TI
7586                                   (match_operand:DI 2 "register_operand" "")))
7587                        (const_int 64))))
7588               (clobber (match_scratch:DI 3 ""))
7589               (clobber (reg:CC FLAGS_REG))])]
7590   "TARGET_64BIT"
7591   "")
7592
7593 (define_insn "*smuldi3_highpart_rex64"
7594   [(set (match_operand:DI 0 "register_operand" "=d")
7595         (truncate:DI
7596           (lshiftrt:TI
7597             (mult:TI (sign_extend:TI
7598                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7599                      (sign_extend:TI
7600                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7601             (const_int 64))))
7602    (clobber (match_scratch:DI 3 "=1"))
7603    (clobber (reg:CC FLAGS_REG))]
7604   "TARGET_64BIT
7605    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7606   "imul{q}\t%2"
7607   [(set_attr "type" "imul")
7608    (set (attr "athlon_decode")
7609      (if_then_else (eq_attr "cpu" "athlon")
7610         (const_string "vector")
7611         (const_string "double")))
7612    (set_attr "amdfam10_decode" "double")
7613    (set_attr "mode" "DI")])
7614
7615 (define_expand "smulsi3_highpart"
7616   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7617                    (truncate:SI
7618                      (lshiftrt:DI
7619                        (mult:DI (sign_extend:DI
7620                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7621                                 (sign_extend:DI
7622                                   (match_operand:SI 2 "register_operand" "")))
7623                        (const_int 32))))
7624               (clobber (match_scratch:SI 3 ""))
7625               (clobber (reg:CC FLAGS_REG))])]
7626   ""
7627   "")
7628
7629 (define_insn "*smulsi3_highpart_insn"
7630   [(set (match_operand:SI 0 "register_operand" "=d")
7631         (truncate:SI
7632           (lshiftrt:DI
7633             (mult:DI (sign_extend:DI
7634                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7635                      (sign_extend:DI
7636                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7637             (const_int 32))))
7638    (clobber (match_scratch:SI 3 "=1"))
7639    (clobber (reg:CC FLAGS_REG))]
7640   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7641   "imul{l}\t%2"
7642   [(set_attr "type" "imul")
7643    (set (attr "athlon_decode")
7644      (if_then_else (eq_attr "cpu" "athlon")
7645         (const_string "vector")
7646         (const_string "double")))
7647    (set_attr "amdfam10_decode" "double")
7648    (set_attr "mode" "SI")])
7649
7650 (define_insn "*smulsi3_highpart_zext"
7651   [(set (match_operand:DI 0 "register_operand" "=d")
7652         (zero_extend:DI (truncate:SI
7653           (lshiftrt:DI
7654             (mult:DI (sign_extend:DI
7655                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7656                      (sign_extend:DI
7657                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7658             (const_int 32)))))
7659    (clobber (match_scratch:SI 3 "=1"))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "TARGET_64BIT
7662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663   "imul{l}\t%2"
7664   [(set_attr "type" "imul")
7665    (set (attr "athlon_decode")
7666      (if_then_else (eq_attr "cpu" "athlon")
7667         (const_string "vector")
7668         (const_string "double")))
7669    (set_attr "amdfam10_decode" "double")
7670    (set_attr "mode" "SI")])
7671
7672 ;; The patterns that match these are at the end of this file.
7673
7674 (define_expand "mulxf3"
7675   [(set (match_operand:XF 0 "register_operand" "")
7676         (mult:XF (match_operand:XF 1 "register_operand" "")
7677                  (match_operand:XF 2 "register_operand" "")))]
7678   "TARGET_80387"
7679   "")
7680
7681 (define_expand "muldf3"
7682   [(set (match_operand:DF 0 "register_operand" "")
7683         (mult:DF (match_operand:DF 1 "register_operand" "")
7684                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7685   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7686   "")
7687
7688 (define_expand "mulsf3"
7689   [(set (match_operand:SF 0 "register_operand" "")
7690         (mult:SF (match_operand:SF 1 "register_operand" "")
7691                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7692   "TARGET_80387 || TARGET_SSE_MATH"
7693   "")
7694 \f
7695 ;; Divide instructions
7696
7697 (define_insn "divqi3"
7698   [(set (match_operand:QI 0 "register_operand" "=a")
7699         (div:QI (match_operand:HI 1 "register_operand" "0")
7700                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7701    (clobber (reg:CC FLAGS_REG))]
7702   "TARGET_QIMODE_MATH"
7703   "idiv{b}\t%2"
7704   [(set_attr "type" "idiv")
7705    (set_attr "mode" "QI")])
7706
7707 (define_insn "udivqi3"
7708   [(set (match_operand:QI 0 "register_operand" "=a")
7709         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7710                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7711    (clobber (reg:CC FLAGS_REG))]
7712   "TARGET_QIMODE_MATH"
7713   "div{b}\t%2"
7714   [(set_attr "type" "idiv")
7715    (set_attr "mode" "QI")])
7716
7717 ;; The patterns that match these are at the end of this file.
7718
7719 (define_expand "divxf3"
7720   [(set (match_operand:XF 0 "register_operand" "")
7721         (div:XF (match_operand:XF 1 "register_operand" "")
7722                 (match_operand:XF 2 "register_operand" "")))]
7723   "TARGET_80387"
7724   "")
7725
7726 (define_expand "divdf3"
7727   [(set (match_operand:DF 0 "register_operand" "")
7728         (div:DF (match_operand:DF 1 "register_operand" "")
7729                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7730    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7731    "")
7732
7733 (define_expand "divsf3"
7734   [(set (match_operand:SF 0 "register_operand" "")
7735         (div:SF (match_operand:SF 1 "register_operand" "")
7736                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7737   "TARGET_80387 || TARGET_SSE_MATH"
7738   "")
7739 \f
7740 ;; Remainder instructions.
7741
7742 (define_expand "divmoddi4"
7743   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7744                    (div:DI (match_operand:DI 1 "register_operand" "")
7745                            (match_operand:DI 2 "nonimmediate_operand" "")))
7746               (set (match_operand:DI 3 "register_operand" "")
7747                    (mod:DI (match_dup 1) (match_dup 2)))
7748               (clobber (reg:CC FLAGS_REG))])]
7749   "TARGET_64BIT"
7750   "")
7751
7752 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7753 ;; Penalize eax case slightly because it results in worse scheduling
7754 ;; of code.
7755 (define_insn "*divmoddi4_nocltd_rex64"
7756   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7757         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7758                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7759    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7760         (mod:DI (match_dup 2) (match_dup 3)))
7761    (clobber (reg:CC FLAGS_REG))]
7762   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7763   "#"
7764   [(set_attr "type" "multi")])
7765
7766 (define_insn "*divmoddi4_cltd_rex64"
7767   [(set (match_operand:DI 0 "register_operand" "=a")
7768         (div:DI (match_operand:DI 2 "register_operand" "a")
7769                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7770    (set (match_operand:DI 1 "register_operand" "=&d")
7771         (mod:DI (match_dup 2) (match_dup 3)))
7772    (clobber (reg:CC FLAGS_REG))]
7773   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7774   "#"
7775   [(set_attr "type" "multi")])
7776
7777 (define_insn "*divmoddi_noext_rex64"
7778   [(set (match_operand:DI 0 "register_operand" "=a")
7779         (div:DI (match_operand:DI 1 "register_operand" "0")
7780                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7781    (set (match_operand:DI 3 "register_operand" "=d")
7782         (mod:DI (match_dup 1) (match_dup 2)))
7783    (use (match_operand:DI 4 "register_operand" "3"))
7784    (clobber (reg:CC FLAGS_REG))]
7785   "TARGET_64BIT"
7786   "idiv{q}\t%2"
7787   [(set_attr "type" "idiv")
7788    (set_attr "mode" "DI")])
7789
7790 (define_split
7791   [(set (match_operand:DI 0 "register_operand" "")
7792         (div:DI (match_operand:DI 1 "register_operand" "")
7793                 (match_operand:DI 2 "nonimmediate_operand" "")))
7794    (set (match_operand:DI 3 "register_operand" "")
7795         (mod:DI (match_dup 1) (match_dup 2)))
7796    (clobber (reg:CC FLAGS_REG))]
7797   "TARGET_64BIT && reload_completed"
7798   [(parallel [(set (match_dup 3)
7799                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7800               (clobber (reg:CC FLAGS_REG))])
7801    (parallel [(set (match_dup 0)
7802                    (div:DI (reg:DI 0) (match_dup 2)))
7803               (set (match_dup 3)
7804                    (mod:DI (reg:DI 0) (match_dup 2)))
7805               (use (match_dup 3))
7806               (clobber (reg:CC FLAGS_REG))])]
7807 {
7808   /* Avoid use of cltd in favor of a mov+shift.  */
7809   if (!TARGET_USE_CLTD && !optimize_size)
7810     {
7811       if (true_regnum (operands[1]))
7812         emit_move_insn (operands[0], operands[1]);
7813       else
7814         emit_move_insn (operands[3], operands[1]);
7815       operands[4] = operands[3];
7816     }
7817   else
7818     {
7819       gcc_assert (!true_regnum (operands[1]));
7820       operands[4] = operands[1];
7821     }
7822 })
7823
7824
7825 (define_expand "divmodsi4"
7826   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7827                    (div:SI (match_operand:SI 1 "register_operand" "")
7828                            (match_operand:SI 2 "nonimmediate_operand" "")))
7829               (set (match_operand:SI 3 "register_operand" "")
7830                    (mod:SI (match_dup 1) (match_dup 2)))
7831               (clobber (reg:CC FLAGS_REG))])]
7832   ""
7833   "")
7834
7835 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7836 ;; Penalize eax case slightly because it results in worse scheduling
7837 ;; of code.
7838 (define_insn "*divmodsi4_nocltd"
7839   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7840         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7841                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7842    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7843         (mod:SI (match_dup 2) (match_dup 3)))
7844    (clobber (reg:CC FLAGS_REG))]
7845   "!optimize_size && !TARGET_USE_CLTD"
7846   "#"
7847   [(set_attr "type" "multi")])
7848
7849 (define_insn "*divmodsi4_cltd"
7850   [(set (match_operand:SI 0 "register_operand" "=a")
7851         (div:SI (match_operand:SI 2 "register_operand" "a")
7852                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7853    (set (match_operand:SI 1 "register_operand" "=&d")
7854         (mod:SI (match_dup 2) (match_dup 3)))
7855    (clobber (reg:CC FLAGS_REG))]
7856   "optimize_size || TARGET_USE_CLTD"
7857   "#"
7858   [(set_attr "type" "multi")])
7859
7860 (define_insn "*divmodsi_noext"
7861   [(set (match_operand:SI 0 "register_operand" "=a")
7862         (div:SI (match_operand:SI 1 "register_operand" "0")
7863                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7864    (set (match_operand:SI 3 "register_operand" "=d")
7865         (mod:SI (match_dup 1) (match_dup 2)))
7866    (use (match_operand:SI 4 "register_operand" "3"))
7867    (clobber (reg:CC FLAGS_REG))]
7868   ""
7869   "idiv{l}\t%2"
7870   [(set_attr "type" "idiv")
7871    (set_attr "mode" "SI")])
7872
7873 (define_split
7874   [(set (match_operand:SI 0 "register_operand" "")
7875         (div:SI (match_operand:SI 1 "register_operand" "")
7876                 (match_operand:SI 2 "nonimmediate_operand" "")))
7877    (set (match_operand:SI 3 "register_operand" "")
7878         (mod:SI (match_dup 1) (match_dup 2)))
7879    (clobber (reg:CC FLAGS_REG))]
7880   "reload_completed"
7881   [(parallel [(set (match_dup 3)
7882                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7883               (clobber (reg:CC FLAGS_REG))])
7884    (parallel [(set (match_dup 0)
7885                    (div:SI (reg:SI 0) (match_dup 2)))
7886               (set (match_dup 3)
7887                    (mod:SI (reg:SI 0) (match_dup 2)))
7888               (use (match_dup 3))
7889               (clobber (reg:CC FLAGS_REG))])]
7890 {
7891   /* Avoid use of cltd in favor of a mov+shift.  */
7892   if (!TARGET_USE_CLTD && !optimize_size)
7893     {
7894       if (true_regnum (operands[1]))
7895         emit_move_insn (operands[0], operands[1]);
7896       else
7897         emit_move_insn (operands[3], operands[1]);
7898       operands[4] = operands[3];
7899     }
7900   else
7901     {
7902       gcc_assert (!true_regnum (operands[1]));
7903       operands[4] = operands[1];
7904     }
7905 })
7906 ;; %%% Split me.
7907 (define_insn "divmodhi4"
7908   [(set (match_operand:HI 0 "register_operand" "=a")
7909         (div:HI (match_operand:HI 1 "register_operand" "0")
7910                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7911    (set (match_operand:HI 3 "register_operand" "=&d")
7912         (mod:HI (match_dup 1) (match_dup 2)))
7913    (clobber (reg:CC FLAGS_REG))]
7914   "TARGET_HIMODE_MATH"
7915   "cwtd\;idiv{w}\t%2"
7916   [(set_attr "type" "multi")
7917    (set_attr "length_immediate" "0")
7918    (set_attr "mode" "SI")])
7919
7920 (define_insn "udivmoddi4"
7921   [(set (match_operand:DI 0 "register_operand" "=a")
7922         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7923                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7924    (set (match_operand:DI 3 "register_operand" "=&d")
7925         (umod:DI (match_dup 1) (match_dup 2)))
7926    (clobber (reg:CC FLAGS_REG))]
7927   "TARGET_64BIT"
7928   "xor{q}\t%3, %3\;div{q}\t%2"
7929   [(set_attr "type" "multi")
7930    (set_attr "length_immediate" "0")
7931    (set_attr "mode" "DI")])
7932
7933 (define_insn "*udivmoddi4_noext"
7934   [(set (match_operand:DI 0 "register_operand" "=a")
7935         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937    (set (match_operand:DI 3 "register_operand" "=d")
7938         (umod:DI (match_dup 1) (match_dup 2)))
7939    (use (match_dup 3))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "TARGET_64BIT"
7942   "div{q}\t%2"
7943   [(set_attr "type" "idiv")
7944    (set_attr "mode" "DI")])
7945
7946 (define_split
7947   [(set (match_operand:DI 0 "register_operand" "")
7948         (udiv:DI (match_operand:DI 1 "register_operand" "")
7949                  (match_operand:DI 2 "nonimmediate_operand" "")))
7950    (set (match_operand:DI 3 "register_operand" "")
7951         (umod:DI (match_dup 1) (match_dup 2)))
7952    (clobber (reg:CC FLAGS_REG))]
7953   "TARGET_64BIT && reload_completed"
7954   [(set (match_dup 3) (const_int 0))
7955    (parallel [(set (match_dup 0)
7956                    (udiv:DI (match_dup 1) (match_dup 2)))
7957               (set (match_dup 3)
7958                    (umod:DI (match_dup 1) (match_dup 2)))
7959               (use (match_dup 3))
7960               (clobber (reg:CC FLAGS_REG))])]
7961   "")
7962
7963 (define_insn "udivmodsi4"
7964   [(set (match_operand:SI 0 "register_operand" "=a")
7965         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7966                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7967    (set (match_operand:SI 3 "register_operand" "=&d")
7968         (umod:SI (match_dup 1) (match_dup 2)))
7969    (clobber (reg:CC FLAGS_REG))]
7970   ""
7971   "xor{l}\t%3, %3\;div{l}\t%2"
7972   [(set_attr "type" "multi")
7973    (set_attr "length_immediate" "0")
7974    (set_attr "mode" "SI")])
7975
7976 (define_insn "*udivmodsi4_noext"
7977   [(set (match_operand:SI 0 "register_operand" "=a")
7978         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980    (set (match_operand:SI 3 "register_operand" "=d")
7981         (umod:SI (match_dup 1) (match_dup 2)))
7982    (use (match_dup 3))
7983    (clobber (reg:CC FLAGS_REG))]
7984   ""
7985   "div{l}\t%2"
7986   [(set_attr "type" "idiv")
7987    (set_attr "mode" "SI")])
7988
7989 (define_split
7990   [(set (match_operand:SI 0 "register_operand" "")
7991         (udiv:SI (match_operand:SI 1 "register_operand" "")
7992                  (match_operand:SI 2 "nonimmediate_operand" "")))
7993    (set (match_operand:SI 3 "register_operand" "")
7994         (umod:SI (match_dup 1) (match_dup 2)))
7995    (clobber (reg:CC FLAGS_REG))]
7996   "reload_completed"
7997   [(set (match_dup 3) (const_int 0))
7998    (parallel [(set (match_dup 0)
7999                    (udiv:SI (match_dup 1) (match_dup 2)))
8000               (set (match_dup 3)
8001                    (umod:SI (match_dup 1) (match_dup 2)))
8002               (use (match_dup 3))
8003               (clobber (reg:CC FLAGS_REG))])]
8004   "")
8005
8006 (define_expand "udivmodhi4"
8007   [(set (match_dup 4) (const_int 0))
8008    (parallel [(set (match_operand:HI 0 "register_operand" "")
8009                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8010                             (match_operand:HI 2 "nonimmediate_operand" "")))
8011               (set (match_operand:HI 3 "register_operand" "")
8012                    (umod:HI (match_dup 1) (match_dup 2)))
8013               (use (match_dup 4))
8014               (clobber (reg:CC FLAGS_REG))])]
8015   "TARGET_HIMODE_MATH"
8016   "operands[4] = gen_reg_rtx (HImode);")
8017
8018 (define_insn "*udivmodhi_noext"
8019   [(set (match_operand:HI 0 "register_operand" "=a")
8020         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8021                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8022    (set (match_operand:HI 3 "register_operand" "=d")
8023         (umod:HI (match_dup 1) (match_dup 2)))
8024    (use (match_operand:HI 4 "register_operand" "3"))
8025    (clobber (reg:CC FLAGS_REG))]
8026   ""
8027   "div{w}\t%2"
8028   [(set_attr "type" "idiv")
8029    (set_attr "mode" "HI")])
8030
8031 ;; We cannot use div/idiv for double division, because it causes
8032 ;; "division by zero" on the overflow and that's not what we expect
8033 ;; from truncate.  Because true (non truncating) double division is
8034 ;; never generated, we can't create this insn anyway.
8035 ;
8036 ;(define_insn ""
8037 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8038 ;       (truncate:SI
8039 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8040 ;                  (zero_extend:DI
8041 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8042 ;   (set (match_operand:SI 3 "register_operand" "=d")
8043 ;       (truncate:SI
8044 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8045 ;   (clobber (reg:CC FLAGS_REG))]
8046 ;  ""
8047 ;  "div{l}\t{%2, %0|%0, %2}"
8048 ;  [(set_attr "type" "idiv")])
8049 \f
8050 ;;- Logical AND instructions
8051
8052 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8053 ;; Note that this excludes ah.
8054
8055 (define_insn "*testdi_1_rex64"
8056   [(set (reg FLAGS_REG)
8057         (compare
8058           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8059                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8060           (const_int 0)))]
8061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8063   "@
8064    test{l}\t{%k1, %k0|%k0, %k1}
8065    test{l}\t{%k1, %k0|%k0, %k1}
8066    test{q}\t{%1, %0|%0, %1}
8067    test{q}\t{%1, %0|%0, %1}
8068    test{q}\t{%1, %0|%0, %1}"
8069   [(set_attr "type" "test")
8070    (set_attr "modrm" "0,1,0,1,1")
8071    (set_attr "mode" "SI,SI,DI,DI,DI")
8072    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8073
8074 (define_insn "testsi_1"
8075   [(set (reg FLAGS_REG)
8076         (compare
8077           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8078                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8079           (const_int 0)))]
8080   "ix86_match_ccmode (insn, CCNOmode)
8081    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8082   "test{l}\t{%1, %0|%0, %1}"
8083   [(set_attr "type" "test")
8084    (set_attr "modrm" "0,1,1")
8085    (set_attr "mode" "SI")
8086    (set_attr "pent_pair" "uv,np,uv")])
8087
8088 (define_expand "testsi_ccno_1"
8089   [(set (reg:CCNO FLAGS_REG)
8090         (compare:CCNO
8091           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8092                   (match_operand:SI 1 "nonmemory_operand" ""))
8093           (const_int 0)))]
8094   ""
8095   "")
8096
8097 (define_insn "*testhi_1"
8098   [(set (reg FLAGS_REG)
8099         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8100                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8101                  (const_int 0)))]
8102   "ix86_match_ccmode (insn, CCNOmode)
8103    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8104   "test{w}\t{%1, %0|%0, %1}"
8105   [(set_attr "type" "test")
8106    (set_attr "modrm" "0,1,1")
8107    (set_attr "mode" "HI")
8108    (set_attr "pent_pair" "uv,np,uv")])
8109
8110 (define_expand "testqi_ccz_1"
8111   [(set (reg:CCZ FLAGS_REG)
8112         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8113                              (match_operand:QI 1 "nonmemory_operand" ""))
8114                  (const_int 0)))]
8115   ""
8116   "")
8117
8118 (define_insn "*testqi_1_maybe_si"
8119   [(set (reg FLAGS_REG)
8120         (compare
8121           (and:QI
8122             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8123             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8124           (const_int 0)))]
8125    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8126     && ix86_match_ccmode (insn,
8127                          CONST_INT_P (operands[1])
8128                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8129 {
8130   if (which_alternative == 3)
8131     {
8132       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8133         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8134       return "test{l}\t{%1, %k0|%k0, %1}";
8135     }
8136   return "test{b}\t{%1, %0|%0, %1}";
8137 }
8138   [(set_attr "type" "test")
8139    (set_attr "modrm" "0,1,1,1")
8140    (set_attr "mode" "QI,QI,QI,SI")
8141    (set_attr "pent_pair" "uv,np,uv,np")])
8142
8143 (define_insn "*testqi_1"
8144   [(set (reg FLAGS_REG)
8145         (compare
8146           (and:QI
8147             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8148             (match_operand:QI 1 "general_operand" "n,n,qn"))
8149           (const_int 0)))]
8150   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8151    && ix86_match_ccmode (insn, CCNOmode)"
8152   "test{b}\t{%1, %0|%0, %1}"
8153   [(set_attr "type" "test")
8154    (set_attr "modrm" "0,1,1")
8155    (set_attr "mode" "QI")
8156    (set_attr "pent_pair" "uv,np,uv")])
8157
8158 (define_expand "testqi_ext_ccno_0"
8159   [(set (reg:CCNO FLAGS_REG)
8160         (compare:CCNO
8161           (and:SI
8162             (zero_extract:SI
8163               (match_operand 0 "ext_register_operand" "")
8164               (const_int 8)
8165               (const_int 8))
8166             (match_operand 1 "const_int_operand" ""))
8167           (const_int 0)))]
8168   ""
8169   "")
8170
8171 (define_insn "*testqi_ext_0"
8172   [(set (reg FLAGS_REG)
8173         (compare
8174           (and:SI
8175             (zero_extract:SI
8176               (match_operand 0 "ext_register_operand" "Q")
8177               (const_int 8)
8178               (const_int 8))
8179             (match_operand 1 "const_int_operand" "n"))
8180           (const_int 0)))]
8181   "ix86_match_ccmode (insn, CCNOmode)"
8182   "test{b}\t{%1, %h0|%h0, %1}"
8183   [(set_attr "type" "test")
8184    (set_attr "mode" "QI")
8185    (set_attr "length_immediate" "1")
8186    (set_attr "pent_pair" "np")])
8187
8188 (define_insn "*testqi_ext_1"
8189   [(set (reg FLAGS_REG)
8190         (compare
8191           (and:SI
8192             (zero_extract:SI
8193               (match_operand 0 "ext_register_operand" "Q")
8194               (const_int 8)
8195               (const_int 8))
8196             (zero_extend:SI
8197               (match_operand:QI 1 "general_operand" "Qm")))
8198           (const_int 0)))]
8199   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8201   "test{b}\t{%1, %h0|%h0, %1}"
8202   [(set_attr "type" "test")
8203    (set_attr "mode" "QI")])
8204
8205 (define_insn "*testqi_ext_1_rex64"
8206   [(set (reg FLAGS_REG)
8207         (compare
8208           (and:SI
8209             (zero_extract:SI
8210               (match_operand 0 "ext_register_operand" "Q")
8211               (const_int 8)
8212               (const_int 8))
8213             (zero_extend:SI
8214               (match_operand:QI 1 "register_operand" "Q")))
8215           (const_int 0)))]
8216   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8217   "test{b}\t{%1, %h0|%h0, %1}"
8218   [(set_attr "type" "test")
8219    (set_attr "mode" "QI")])
8220
8221 (define_insn "*testqi_ext_2"
8222   [(set (reg FLAGS_REG)
8223         (compare
8224           (and:SI
8225             (zero_extract:SI
8226               (match_operand 0 "ext_register_operand" "Q")
8227               (const_int 8)
8228               (const_int 8))
8229             (zero_extract:SI
8230               (match_operand 1 "ext_register_operand" "Q")
8231               (const_int 8)
8232               (const_int 8)))
8233           (const_int 0)))]
8234   "ix86_match_ccmode (insn, CCNOmode)"
8235   "test{b}\t{%h1, %h0|%h0, %h1}"
8236   [(set_attr "type" "test")
8237    (set_attr "mode" "QI")])
8238
8239 ;; Combine likes to form bit extractions for some tests.  Humor it.
8240 (define_insn "*testqi_ext_3"
8241   [(set (reg FLAGS_REG)
8242         (compare (zero_extract:SI
8243                    (match_operand 0 "nonimmediate_operand" "rm")
8244                    (match_operand:SI 1 "const_int_operand" "")
8245                    (match_operand:SI 2 "const_int_operand" ""))
8246                  (const_int 0)))]
8247   "ix86_match_ccmode (insn, CCNOmode)
8248    && INTVAL (operands[1]) > 0
8249    && INTVAL (operands[2]) >= 0
8250    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8251    && (GET_MODE (operands[0]) == SImode
8252        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8253        || GET_MODE (operands[0]) == HImode
8254        || GET_MODE (operands[0]) == QImode)"
8255   "#")
8256
8257 (define_insn "*testqi_ext_3_rex64"
8258   [(set (reg FLAGS_REG)
8259         (compare (zero_extract:DI
8260                    (match_operand 0 "nonimmediate_operand" "rm")
8261                    (match_operand:DI 1 "const_int_operand" "")
8262                    (match_operand:DI 2 "const_int_operand" ""))
8263                  (const_int 0)))]
8264   "TARGET_64BIT
8265    && ix86_match_ccmode (insn, CCNOmode)
8266    && INTVAL (operands[1]) > 0
8267    && INTVAL (operands[2]) >= 0
8268    /* Ensure that resulting mask is zero or sign extended operand.  */
8269    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8270        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8271            && INTVAL (operands[1]) > 32))
8272    && (GET_MODE (operands[0]) == SImode
8273        || GET_MODE (operands[0]) == DImode
8274        || GET_MODE (operands[0]) == HImode
8275        || GET_MODE (operands[0]) == QImode)"
8276   "#")
8277
8278 (define_split
8279   [(set (match_operand 0 "flags_reg_operand" "")
8280         (match_operator 1 "compare_operator"
8281           [(zero_extract
8282              (match_operand 2 "nonimmediate_operand" "")
8283              (match_operand 3 "const_int_operand" "")
8284              (match_operand 4 "const_int_operand" ""))
8285            (const_int 0)]))]
8286   "ix86_match_ccmode (insn, CCNOmode)"
8287   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8288 {
8289   rtx val = operands[2];
8290   HOST_WIDE_INT len = INTVAL (operands[3]);
8291   HOST_WIDE_INT pos = INTVAL (operands[4]);
8292   HOST_WIDE_INT mask;
8293   enum machine_mode mode, submode;
8294
8295   mode = GET_MODE (val);
8296   if (MEM_P (val))
8297     {
8298       /* ??? Combine likes to put non-volatile mem extractions in QImode
8299          no matter the size of the test.  So find a mode that works.  */
8300       if (! MEM_VOLATILE_P (val))
8301         {
8302           mode = smallest_mode_for_size (pos + len, MODE_INT);
8303           val = adjust_address (val, mode, 0);
8304         }
8305     }
8306   else if (GET_CODE (val) == SUBREG
8307            && (submode = GET_MODE (SUBREG_REG (val)),
8308                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8309            && pos + len <= GET_MODE_BITSIZE (submode))
8310     {
8311       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8312       mode = submode;
8313       val = SUBREG_REG (val);
8314     }
8315   else if (mode == HImode && pos + len <= 8)
8316     {
8317       /* Small HImode tests can be converted to QImode.  */
8318       mode = QImode;
8319       val = gen_lowpart (QImode, val);
8320     }
8321
8322   if (len == HOST_BITS_PER_WIDE_INT)
8323     mask = -1;
8324   else
8325     mask = ((HOST_WIDE_INT)1 << len) - 1;
8326   mask <<= pos;
8327
8328   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8329 })
8330
8331 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8332 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8333 ;; this is relatively important trick.
8334 ;; Do the conversion only post-reload to avoid limiting of the register class
8335 ;; to QI regs.
8336 (define_split
8337   [(set (match_operand 0 "flags_reg_operand" "")
8338         (match_operator 1 "compare_operator"
8339           [(and (match_operand 2 "register_operand" "")
8340                 (match_operand 3 "const_int_operand" ""))
8341            (const_int 0)]))]
8342    "reload_completed
8343     && QI_REG_P (operands[2])
8344     && GET_MODE (operands[2]) != QImode
8345     && ((ix86_match_ccmode (insn, CCZmode)
8346          && !(INTVAL (operands[3]) & ~(255 << 8)))
8347         || (ix86_match_ccmode (insn, CCNOmode)
8348             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8349   [(set (match_dup 0)
8350         (match_op_dup 1
8351           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8352                    (match_dup 3))
8353            (const_int 0)]))]
8354   "operands[2] = gen_lowpart (SImode, operands[2]);
8355    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8356
8357 (define_split
8358   [(set (match_operand 0 "flags_reg_operand" "")
8359         (match_operator 1 "compare_operator"
8360           [(and (match_operand 2 "nonimmediate_operand" "")
8361                 (match_operand 3 "const_int_operand" ""))
8362            (const_int 0)]))]
8363    "reload_completed
8364     && GET_MODE (operands[2]) != QImode
8365     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8366     && ((ix86_match_ccmode (insn, CCZmode)
8367          && !(INTVAL (operands[3]) & ~255))
8368         || (ix86_match_ccmode (insn, CCNOmode)
8369             && !(INTVAL (operands[3]) & ~127)))"
8370   [(set (match_dup 0)
8371         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8372                          (const_int 0)]))]
8373   "operands[2] = gen_lowpart (QImode, operands[2]);
8374    operands[3] = gen_lowpart (QImode, operands[3]);")
8375
8376
8377 ;; %%% This used to optimize known byte-wide and operations to memory,
8378 ;; and sometimes to QImode registers.  If this is considered useful,
8379 ;; it should be done with splitters.
8380
8381 (define_expand "anddi3"
8382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8383         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8384                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8385    (clobber (reg:CC FLAGS_REG))]
8386   "TARGET_64BIT"
8387   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8388
8389 (define_insn "*anddi_1_rex64"
8390   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8391         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8392                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8395 {
8396   switch (get_attr_type (insn))
8397     {
8398     case TYPE_IMOVX:
8399       {
8400         enum machine_mode mode;
8401
8402         gcc_assert (CONST_INT_P (operands[2]));
8403         if (INTVAL (operands[2]) == 0xff)
8404           mode = QImode;
8405         else
8406           {
8407             gcc_assert (INTVAL (operands[2]) == 0xffff);
8408             mode = HImode;
8409           }
8410
8411         operands[1] = gen_lowpart (mode, operands[1]);
8412         if (mode == QImode)
8413           return "movz{bq|x}\t{%1,%0|%0, %1}";
8414         else
8415           return "movz{wq|x}\t{%1,%0|%0, %1}";
8416       }
8417
8418     default:
8419       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8420       if (get_attr_mode (insn) == MODE_SI)
8421         return "and{l}\t{%k2, %k0|%k0, %k2}";
8422       else
8423         return "and{q}\t{%2, %0|%0, %2}";
8424     }
8425 }
8426   [(set_attr "type" "alu,alu,alu,imovx")
8427    (set_attr "length_immediate" "*,*,*,0")
8428    (set_attr "mode" "SI,DI,DI,DI")])
8429
8430 (define_insn "*anddi_2"
8431   [(set (reg FLAGS_REG)
8432         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8433                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8434                  (const_int 0)))
8435    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8436         (and:DI (match_dup 1) (match_dup 2)))]
8437   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8438    && ix86_binary_operator_ok (AND, DImode, operands)"
8439   "@
8440    and{l}\t{%k2, %k0|%k0, %k2}
8441    and{q}\t{%2, %0|%0, %2}
8442    and{q}\t{%2, %0|%0, %2}"
8443   [(set_attr "type" "alu")
8444    (set_attr "mode" "SI,DI,DI")])
8445
8446 (define_expand "andsi3"
8447   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8448         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8449                 (match_operand:SI 2 "general_operand" "")))
8450    (clobber (reg:CC FLAGS_REG))]
8451   ""
8452   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8453
8454 (define_insn "*andsi_1"
8455   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8456         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8457                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8458    (clobber (reg:CC FLAGS_REG))]
8459   "ix86_binary_operator_ok (AND, SImode, operands)"
8460 {
8461   switch (get_attr_type (insn))
8462     {
8463     case TYPE_IMOVX:
8464       {
8465         enum machine_mode mode;
8466
8467         gcc_assert (CONST_INT_P (operands[2]));
8468         if (INTVAL (operands[2]) == 0xff)
8469           mode = QImode;
8470         else
8471           {
8472             gcc_assert (INTVAL (operands[2]) == 0xffff);
8473             mode = HImode;
8474           }
8475
8476         operands[1] = gen_lowpart (mode, operands[1]);
8477         if (mode == QImode)
8478           return "movz{bl|x}\t{%1,%0|%0, %1}";
8479         else
8480           return "movz{wl|x}\t{%1,%0|%0, %1}";
8481       }
8482
8483     default:
8484       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8485       return "and{l}\t{%2, %0|%0, %2}";
8486     }
8487 }
8488   [(set_attr "type" "alu,alu,imovx")
8489    (set_attr "length_immediate" "*,*,0")
8490    (set_attr "mode" "SI")])
8491
8492 (define_split
8493   [(set (match_operand 0 "register_operand" "")
8494         (and (match_dup 0)
8495              (const_int -65536)))
8496    (clobber (reg:CC FLAGS_REG))]
8497   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8498   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8499   "operands[1] = gen_lowpart (HImode, operands[0]);")
8500
8501 (define_split
8502   [(set (match_operand 0 "ext_register_operand" "")
8503         (and (match_dup 0)
8504              (const_int -256)))
8505    (clobber (reg:CC FLAGS_REG))]
8506   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8507   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8508   "operands[1] = gen_lowpart (QImode, operands[0]);")
8509
8510 (define_split
8511   [(set (match_operand 0 "ext_register_operand" "")
8512         (and (match_dup 0)
8513              (const_int -65281)))
8514    (clobber (reg:CC FLAGS_REG))]
8515   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8516   [(parallel [(set (zero_extract:SI (match_dup 0)
8517                                     (const_int 8)
8518                                     (const_int 8))
8519                    (xor:SI
8520                      (zero_extract:SI (match_dup 0)
8521                                       (const_int 8)
8522                                       (const_int 8))
8523                      (zero_extract:SI (match_dup 0)
8524                                       (const_int 8)
8525                                       (const_int 8))))
8526               (clobber (reg:CC FLAGS_REG))])]
8527   "operands[0] = gen_lowpart (SImode, operands[0]);")
8528
8529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8530 (define_insn "*andsi_1_zext"
8531   [(set (match_operand:DI 0 "register_operand" "=r")
8532         (zero_extend:DI
8533           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8534                   (match_operand:SI 2 "general_operand" "rim"))))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8537   "and{l}\t{%2, %k0|%k0, %2}"
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "SI")])
8540
8541 (define_insn "*andsi_2"
8542   [(set (reg FLAGS_REG)
8543         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8544                          (match_operand:SI 2 "general_operand" "rim,ri"))
8545                  (const_int 0)))
8546    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8547         (and:SI (match_dup 1) (match_dup 2)))]
8548   "ix86_match_ccmode (insn, CCNOmode)
8549    && ix86_binary_operator_ok (AND, SImode, operands)"
8550   "and{l}\t{%2, %0|%0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "SI")])
8553
8554 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8555 (define_insn "*andsi_2_zext"
8556   [(set (reg FLAGS_REG)
8557         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8558                          (match_operand:SI 2 "general_operand" "rim"))
8559                  (const_int 0)))
8560    (set (match_operand:DI 0 "register_operand" "=r")
8561         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8562   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563    && ix86_binary_operator_ok (AND, SImode, operands)"
8564   "and{l}\t{%2, %k0|%k0, %2}"
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "SI")])
8567
8568 (define_expand "andhi3"
8569   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8570         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8571                 (match_operand:HI 2 "general_operand" "")))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "TARGET_HIMODE_MATH"
8574   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8575
8576 (define_insn "*andhi_1"
8577   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8578         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8579                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "ix86_binary_operator_ok (AND, HImode, operands)"
8582 {
8583   switch (get_attr_type (insn))
8584     {
8585     case TYPE_IMOVX:
8586       gcc_assert (CONST_INT_P (operands[2]));
8587       gcc_assert (INTVAL (operands[2]) == 0xff);
8588       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8589
8590     default:
8591       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8592
8593       return "and{w}\t{%2, %0|%0, %2}";
8594     }
8595 }
8596   [(set_attr "type" "alu,alu,imovx")
8597    (set_attr "length_immediate" "*,*,0")
8598    (set_attr "mode" "HI,HI,SI")])
8599
8600 (define_insn "*andhi_2"
8601   [(set (reg FLAGS_REG)
8602         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8603                          (match_operand:HI 2 "general_operand" "rim,ri"))
8604                  (const_int 0)))
8605    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8606         (and:HI (match_dup 1) (match_dup 2)))]
8607   "ix86_match_ccmode (insn, CCNOmode)
8608    && ix86_binary_operator_ok (AND, HImode, operands)"
8609   "and{w}\t{%2, %0|%0, %2}"
8610   [(set_attr "type" "alu")
8611    (set_attr "mode" "HI")])
8612
8613 (define_expand "andqi3"
8614   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8615         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8616                 (match_operand:QI 2 "general_operand" "")))
8617    (clobber (reg:CC FLAGS_REG))]
8618   "TARGET_QIMODE_MATH"
8619   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8620
8621 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8622 (define_insn "*andqi_1"
8623   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8624         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8625                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "ix86_binary_operator_ok (AND, QImode, operands)"
8628   "@
8629    and{b}\t{%2, %0|%0, %2}
8630    and{b}\t{%2, %0|%0, %2}
8631    and{l}\t{%k2, %k0|%k0, %k2}"
8632   [(set_attr "type" "alu")
8633    (set_attr "mode" "QI,QI,SI")])
8634
8635 (define_insn "*andqi_1_slp"
8636   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8637         (and:QI (match_dup 0)
8638                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8641    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8642   "and{b}\t{%1, %0|%0, %1}"
8643   [(set_attr "type" "alu1")
8644    (set_attr "mode" "QI")])
8645
8646 (define_insn "*andqi_2_maybe_si"
8647   [(set (reg FLAGS_REG)
8648         (compare (and:QI
8649                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8651                  (const_int 0)))
8652    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653         (and:QI (match_dup 1) (match_dup 2)))]
8654   "ix86_binary_operator_ok (AND, QImode, operands)
8655    && ix86_match_ccmode (insn,
8656                          CONST_INT_P (operands[2])
8657                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8658 {
8659   if (which_alternative == 2)
8660     {
8661       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663       return "and{l}\t{%2, %k0|%k0, %2}";
8664     }
8665   return "and{b}\t{%2, %0|%0, %2}";
8666 }
8667   [(set_attr "type" "alu")
8668    (set_attr "mode" "QI,QI,SI")])
8669
8670 (define_insn "*andqi_2"
8671   [(set (reg FLAGS_REG)
8672         (compare (and:QI
8673                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8674                    (match_operand:QI 2 "general_operand" "qim,qi"))
8675                  (const_int 0)))
8676    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8677         (and:QI (match_dup 1) (match_dup 2)))]
8678   "ix86_match_ccmode (insn, CCNOmode)
8679    && ix86_binary_operator_ok (AND, QImode, operands)"
8680   "and{b}\t{%2, %0|%0, %2}"
8681   [(set_attr "type" "alu")
8682    (set_attr "mode" "QI")])
8683
8684 (define_insn "*andqi_2_slp"
8685   [(set (reg FLAGS_REG)
8686         (compare (and:QI
8687                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8688                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8689                  (const_int 0)))
8690    (set (strict_low_part (match_dup 0))
8691         (and:QI (match_dup 0) (match_dup 1)))]
8692   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8693    && ix86_match_ccmode (insn, CCNOmode)
8694    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8695   "and{b}\t{%1, %0|%0, %1}"
8696   [(set_attr "type" "alu1")
8697    (set_attr "mode" "QI")])
8698
8699 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8700 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8701 ;; for a QImode operand, which of course failed.
8702
8703 (define_insn "andqi_ext_0"
8704   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8705                          (const_int 8)
8706                          (const_int 8))
8707         (and:SI
8708           (zero_extract:SI
8709             (match_operand 1 "ext_register_operand" "0")
8710             (const_int 8)
8711             (const_int 8))
8712           (match_operand 2 "const_int_operand" "n")))
8713    (clobber (reg:CC FLAGS_REG))]
8714   ""
8715   "and{b}\t{%2, %h0|%h0, %2}"
8716   [(set_attr "type" "alu")
8717    (set_attr "length_immediate" "1")
8718    (set_attr "mode" "QI")])
8719
8720 ;; Generated by peephole translating test to and.  This shows up
8721 ;; often in fp comparisons.
8722
8723 (define_insn "*andqi_ext_0_cc"
8724   [(set (reg FLAGS_REG)
8725         (compare
8726           (and:SI
8727             (zero_extract:SI
8728               (match_operand 1 "ext_register_operand" "0")
8729               (const_int 8)
8730               (const_int 8))
8731             (match_operand 2 "const_int_operand" "n"))
8732           (const_int 0)))
8733    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8734                          (const_int 8)
8735                          (const_int 8))
8736         (and:SI
8737           (zero_extract:SI
8738             (match_dup 1)
8739             (const_int 8)
8740             (const_int 8))
8741           (match_dup 2)))]
8742   "ix86_match_ccmode (insn, CCNOmode)"
8743   "and{b}\t{%2, %h0|%h0, %2}"
8744   [(set_attr "type" "alu")
8745    (set_attr "length_immediate" "1")
8746    (set_attr "mode" "QI")])
8747
8748 (define_insn "*andqi_ext_1"
8749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8750                          (const_int 8)
8751                          (const_int 8))
8752         (and:SI
8753           (zero_extract:SI
8754             (match_operand 1 "ext_register_operand" "0")
8755             (const_int 8)
8756             (const_int 8))
8757           (zero_extend:SI
8758             (match_operand:QI 2 "general_operand" "Qm"))))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "!TARGET_64BIT"
8761   "and{b}\t{%2, %h0|%h0, %2}"
8762   [(set_attr "type" "alu")
8763    (set_attr "length_immediate" "0")
8764    (set_attr "mode" "QI")])
8765
8766 (define_insn "*andqi_ext_1_rex64"
8767   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8768                          (const_int 8)
8769                          (const_int 8))
8770         (and:SI
8771           (zero_extract:SI
8772             (match_operand 1 "ext_register_operand" "0")
8773             (const_int 8)
8774             (const_int 8))
8775           (zero_extend:SI
8776             (match_operand 2 "ext_register_operand" "Q"))))
8777    (clobber (reg:CC FLAGS_REG))]
8778   "TARGET_64BIT"
8779   "and{b}\t{%2, %h0|%h0, %2}"
8780   [(set_attr "type" "alu")
8781    (set_attr "length_immediate" "0")
8782    (set_attr "mode" "QI")])
8783
8784 (define_insn "*andqi_ext_2"
8785   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786                          (const_int 8)
8787                          (const_int 8))
8788         (and:SI
8789           (zero_extract:SI
8790             (match_operand 1 "ext_register_operand" "%0")
8791             (const_int 8)
8792             (const_int 8))
8793           (zero_extract:SI
8794             (match_operand 2 "ext_register_operand" "Q")
8795             (const_int 8)
8796             (const_int 8))))
8797    (clobber (reg:CC FLAGS_REG))]
8798   ""
8799   "and{b}\t{%h2, %h0|%h0, %h2}"
8800   [(set_attr "type" "alu")
8801    (set_attr "length_immediate" "0")
8802    (set_attr "mode" "QI")])
8803
8804 ;; Convert wide AND instructions with immediate operand to shorter QImode
8805 ;; equivalents when possible.
8806 ;; Don't do the splitting with memory operands, since it introduces risk
8807 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8808 ;; for size, but that can (should?) be handled by generic code instead.
8809 (define_split
8810   [(set (match_operand 0 "register_operand" "")
8811         (and (match_operand 1 "register_operand" "")
8812              (match_operand 2 "const_int_operand" "")))
8813    (clobber (reg:CC FLAGS_REG))]
8814    "reload_completed
8815     && QI_REG_P (operands[0])
8816     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8817     && !(~INTVAL (operands[2]) & ~(255 << 8))
8818     && GET_MODE (operands[0]) != QImode"
8819   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8820                    (and:SI (zero_extract:SI (match_dup 1)
8821                                             (const_int 8) (const_int 8))
8822                            (match_dup 2)))
8823               (clobber (reg:CC FLAGS_REG))])]
8824   "operands[0] = gen_lowpart (SImode, operands[0]);
8825    operands[1] = gen_lowpart (SImode, operands[1]);
8826    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8827
8828 ;; Since AND can be encoded with sign extended immediate, this is only
8829 ;; profitable when 7th bit is not set.
8830 (define_split
8831   [(set (match_operand 0 "register_operand" "")
8832         (and (match_operand 1 "general_operand" "")
8833              (match_operand 2 "const_int_operand" "")))
8834    (clobber (reg:CC FLAGS_REG))]
8835    "reload_completed
8836     && ANY_QI_REG_P (operands[0])
8837     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8838     && !(~INTVAL (operands[2]) & ~255)
8839     && !(INTVAL (operands[2]) & 128)
8840     && GET_MODE (operands[0]) != QImode"
8841   [(parallel [(set (strict_low_part (match_dup 0))
8842                    (and:QI (match_dup 1)
8843                            (match_dup 2)))
8844               (clobber (reg:CC FLAGS_REG))])]
8845   "operands[0] = gen_lowpart (QImode, operands[0]);
8846    operands[1] = gen_lowpart (QImode, operands[1]);
8847    operands[2] = gen_lowpart (QImode, operands[2]);")
8848 \f
8849 ;; Logical inclusive OR instructions
8850
8851 ;; %%% This used to optimize known byte-wide and operations to memory.
8852 ;; If this is considered useful, it should be done with splitters.
8853
8854 (define_expand "iordi3"
8855   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8856         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8857                 (match_operand:DI 2 "x86_64_general_operand" "")))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "TARGET_64BIT"
8860   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8861
8862 (define_insn "*iordi_1_rex64"
8863   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8864         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "TARGET_64BIT
8868    && ix86_binary_operator_ok (IOR, DImode, operands)"
8869   "or{q}\t{%2, %0|%0, %2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "mode" "DI")])
8872
8873 (define_insn "*iordi_2_rex64"
8874   [(set (reg FLAGS_REG)
8875         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8877                  (const_int 0)))
8878    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879         (ior:DI (match_dup 1) (match_dup 2)))]
8880   "TARGET_64BIT
8881    && ix86_match_ccmode (insn, CCNOmode)
8882    && ix86_binary_operator_ok (IOR, DImode, operands)"
8883   "or{q}\t{%2, %0|%0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "DI")])
8886
8887 (define_insn "*iordi_3_rex64"
8888   [(set (reg FLAGS_REG)
8889         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8891                  (const_int 0)))
8892    (clobber (match_scratch:DI 0 "=r"))]
8893   "TARGET_64BIT
8894    && ix86_match_ccmode (insn, CCNOmode)
8895    && ix86_binary_operator_ok (IOR, DImode, operands)"
8896   "or{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8899
8900
8901 (define_expand "iorsi3"
8902   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904                 (match_operand:SI 2 "general_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   ""
8907   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8908
8909 (define_insn "*iorsi_1"
8910   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "ix86_binary_operator_ok (IOR, SImode, operands)"
8915   "or{l}\t{%2, %0|%0, %2}"
8916   [(set_attr "type" "alu")
8917    (set_attr "mode" "SI")])
8918
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 (define_insn "*iorsi_1_zext"
8921   [(set (match_operand:DI 0 "register_operand" "=rm")
8922         (zero_extend:DI
8923           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924                   (match_operand:SI 2 "general_operand" "rim"))))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8927   "or{l}\t{%2, %k0|%k0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "SI")])
8930
8931 (define_insn "*iorsi_1_zext_imm"
8932   [(set (match_operand:DI 0 "register_operand" "=rm")
8933         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   "TARGET_64BIT"
8937   "or{l}\t{%2, %k0|%k0, %2}"
8938   [(set_attr "type" "alu")
8939    (set_attr "mode" "SI")])
8940
8941 (define_insn "*iorsi_2"
8942   [(set (reg FLAGS_REG)
8943         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944                          (match_operand:SI 2 "general_operand" "rim,ri"))
8945                  (const_int 0)))
8946    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947         (ior:SI (match_dup 1) (match_dup 2)))]
8948   "ix86_match_ccmode (insn, CCNOmode)
8949    && ix86_binary_operator_ok (IOR, SImode, operands)"
8950   "or{l}\t{%2, %0|%0, %2}"
8951   [(set_attr "type" "alu")
8952    (set_attr "mode" "SI")])
8953
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*iorsi_2_zext"
8957   [(set (reg FLAGS_REG)
8958         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959                          (match_operand:SI 2 "general_operand" "rim"))
8960                  (const_int 0)))
8961    (set (match_operand:DI 0 "register_operand" "=r")
8962         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8963   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (IOR, SImode, operands)"
8965   "or{l}\t{%2, %k0|%k0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "SI")])
8968
8969 (define_insn "*iorsi_2_zext_imm"
8970   [(set (reg FLAGS_REG)
8971         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8973                  (const_int 0)))
8974    (set (match_operand:DI 0 "register_operand" "=r")
8975         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977    && ix86_binary_operator_ok (IOR, SImode, operands)"
8978   "or{l}\t{%2, %k0|%k0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "SI")])
8981
8982 (define_insn "*iorsi_3"
8983   [(set (reg FLAGS_REG)
8984         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985                          (match_operand:SI 2 "general_operand" "rim"))
8986                  (const_int 0)))
8987    (clobber (match_scratch:SI 0 "=r"))]
8988   "ix86_match_ccmode (insn, CCNOmode)
8989    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8990   "or{l}\t{%2, %0|%0, %2}"
8991   [(set_attr "type" "alu")
8992    (set_attr "mode" "SI")])
8993
8994 (define_expand "iorhi3"
8995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997                 (match_operand:HI 2 "general_operand" "")))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "TARGET_HIMODE_MATH"
9000   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9001
9002 (define_insn "*iorhi_1"
9003   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006    (clobber (reg:CC FLAGS_REG))]
9007   "ix86_binary_operator_ok (IOR, HImode, operands)"
9008   "or{w}\t{%2, %0|%0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "HI")])
9011
9012 (define_insn "*iorhi_2"
9013   [(set (reg FLAGS_REG)
9014         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015                          (match_operand:HI 2 "general_operand" "rim,ri"))
9016                  (const_int 0)))
9017    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018         (ior:HI (match_dup 1) (match_dup 2)))]
9019   "ix86_match_ccmode (insn, CCNOmode)
9020    && ix86_binary_operator_ok (IOR, HImode, operands)"
9021   "or{w}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "HI")])
9024
9025 (define_insn "*iorhi_3"
9026   [(set (reg FLAGS_REG)
9027         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028                          (match_operand:HI 2 "general_operand" "rim"))
9029                  (const_int 0)))
9030    (clobber (match_scratch:HI 0 "=r"))]
9031   "ix86_match_ccmode (insn, CCNOmode)
9032    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9033   "or{w}\t{%2, %0|%0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "mode" "HI")])
9036
9037 (define_expand "iorqi3"
9038   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040                 (match_operand:QI 2 "general_operand" "")))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "TARGET_QIMODE_MATH"
9043   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9044
9045 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9046 (define_insn "*iorqi_1"
9047   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050    (clobber (reg:CC FLAGS_REG))]
9051   "ix86_binary_operator_ok (IOR, QImode, operands)"
9052   "@
9053    or{b}\t{%2, %0|%0, %2}
9054    or{b}\t{%2, %0|%0, %2}
9055    or{l}\t{%k2, %k0|%k0, %k2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "QI,QI,SI")])
9058
9059 (define_insn "*iorqi_1_slp"
9060   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9061         (ior:QI (match_dup 0)
9062                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9066   "or{b}\t{%1, %0|%0, %1}"
9067   [(set_attr "type" "alu1")
9068    (set_attr "mode" "QI")])
9069
9070 (define_insn "*iorqi_2"
9071   [(set (reg FLAGS_REG)
9072         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9073                          (match_operand:QI 2 "general_operand" "qim,qi"))
9074                  (const_int 0)))
9075    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9076         (ior:QI (match_dup 1) (match_dup 2)))]
9077   "ix86_match_ccmode (insn, CCNOmode)
9078    && ix86_binary_operator_ok (IOR, QImode, operands)"
9079   "or{b}\t{%2, %0|%0, %2}"
9080   [(set_attr "type" "alu")
9081    (set_attr "mode" "QI")])
9082
9083 (define_insn "*iorqi_2_slp"
9084   [(set (reg FLAGS_REG)
9085         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9086                          (match_operand:QI 1 "general_operand" "qim,qi"))
9087                  (const_int 0)))
9088    (set (strict_low_part (match_dup 0))
9089         (ior:QI (match_dup 0) (match_dup 1)))]
9090   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9091    && ix86_match_ccmode (insn, CCNOmode)
9092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093   "or{b}\t{%1, %0|%0, %1}"
9094   [(set_attr "type" "alu1")
9095    (set_attr "mode" "QI")])
9096
9097 (define_insn "*iorqi_3"
9098   [(set (reg FLAGS_REG)
9099         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9100                          (match_operand:QI 2 "general_operand" "qim"))
9101                  (const_int 0)))
9102    (clobber (match_scratch:QI 0 "=q"))]
9103   "ix86_match_ccmode (insn, CCNOmode)
9104    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9105   "or{b}\t{%2, %0|%0, %2}"
9106   [(set_attr "type" "alu")
9107    (set_attr "mode" "QI")])
9108
9109 (define_insn "iorqi_ext_0"
9110   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111                          (const_int 8)
9112                          (const_int 8))
9113         (ior:SI
9114           (zero_extract:SI
9115             (match_operand 1 "ext_register_operand" "0")
9116             (const_int 8)
9117             (const_int 8))
9118           (match_operand 2 "const_int_operand" "n")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121   "or{b}\t{%2, %h0|%h0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "length_immediate" "1")
9124    (set_attr "mode" "QI")])
9125
9126 (define_insn "*iorqi_ext_1"
9127   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128                          (const_int 8)
9129                          (const_int 8))
9130         (ior:SI
9131           (zero_extract:SI
9132             (match_operand 1 "ext_register_operand" "0")
9133             (const_int 8)
9134             (const_int 8))
9135           (zero_extend:SI
9136             (match_operand:QI 2 "general_operand" "Qm"))))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "!TARGET_64BIT
9139    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140   "or{b}\t{%2, %h0|%h0, %2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "length_immediate" "0")
9143    (set_attr "mode" "QI")])
9144
9145 (define_insn "*iorqi_ext_1_rex64"
9146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9147                          (const_int 8)
9148                          (const_int 8))
9149         (ior:SI
9150           (zero_extract:SI
9151             (match_operand 1 "ext_register_operand" "0")
9152             (const_int 8)
9153             (const_int 8))
9154           (zero_extend:SI
9155             (match_operand 2 "ext_register_operand" "Q"))))
9156    (clobber (reg:CC FLAGS_REG))]
9157   "TARGET_64BIT
9158    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159   "or{b}\t{%2, %h0|%h0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "length_immediate" "0")
9162    (set_attr "mode" "QI")])
9163
9164 (define_insn "*iorqi_ext_2"
9165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9166                          (const_int 8)
9167                          (const_int 8))
9168         (ior:SI
9169           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9170                            (const_int 8)
9171                            (const_int 8))
9172           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9173                            (const_int 8)
9174                            (const_int 8))))
9175    (clobber (reg:CC FLAGS_REG))]
9176   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177   "ior{b}\t{%h2, %h0|%h0, %h2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "length_immediate" "0")
9180    (set_attr "mode" "QI")])
9181
9182 (define_split
9183   [(set (match_operand 0 "register_operand" "")
9184         (ior (match_operand 1 "register_operand" "")
9185              (match_operand 2 "const_int_operand" "")))
9186    (clobber (reg:CC FLAGS_REG))]
9187    "reload_completed
9188     && QI_REG_P (operands[0])
9189     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9190     && !(INTVAL (operands[2]) & ~(255 << 8))
9191     && GET_MODE (operands[0]) != QImode"
9192   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9193                    (ior:SI (zero_extract:SI (match_dup 1)
9194                                             (const_int 8) (const_int 8))
9195                            (match_dup 2)))
9196               (clobber (reg:CC FLAGS_REG))])]
9197   "operands[0] = gen_lowpart (SImode, operands[0]);
9198    operands[1] = gen_lowpart (SImode, operands[1]);
9199    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9200
9201 ;; Since OR can be encoded with sign extended immediate, this is only
9202 ;; profitable when 7th bit is set.
9203 (define_split
9204   [(set (match_operand 0 "register_operand" "")
9205         (ior (match_operand 1 "general_operand" "")
9206              (match_operand 2 "const_int_operand" "")))
9207    (clobber (reg:CC FLAGS_REG))]
9208    "reload_completed
9209     && ANY_QI_REG_P (operands[0])
9210     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9211     && !(INTVAL (operands[2]) & ~255)
9212     && (INTVAL (operands[2]) & 128)
9213     && GET_MODE (operands[0]) != QImode"
9214   [(parallel [(set (strict_low_part (match_dup 0))
9215                    (ior:QI (match_dup 1)
9216                            (match_dup 2)))
9217               (clobber (reg:CC FLAGS_REG))])]
9218   "operands[0] = gen_lowpart (QImode, operands[0]);
9219    operands[1] = gen_lowpart (QImode, operands[1]);
9220    operands[2] = gen_lowpart (QImode, operands[2]);")
9221 \f
9222 ;; Logical XOR instructions
9223
9224 ;; %%% This used to optimize known byte-wide and operations to memory.
9225 ;; If this is considered useful, it should be done with splitters.
9226
9227 (define_expand "xordi3"
9228   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9230                 (match_operand:DI 2 "x86_64_general_operand" "")))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "TARGET_64BIT"
9233   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9234
9235 (define_insn "*xordi_1_rex64"
9236   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9237         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "TARGET_64BIT
9241    && ix86_binary_operator_ok (XOR, DImode, operands)"
9242   "@
9243    xor{q}\t{%2, %0|%0, %2}
9244    xor{q}\t{%2, %0|%0, %2}"
9245   [(set_attr "type" "alu")
9246    (set_attr "mode" "DI,DI")])
9247
9248 (define_insn "*xordi_2_rex64"
9249   [(set (reg FLAGS_REG)
9250         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9252                  (const_int 0)))
9253    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9254         (xor:DI (match_dup 1) (match_dup 2)))]
9255   "TARGET_64BIT
9256    && ix86_match_ccmode (insn, CCNOmode)
9257    && ix86_binary_operator_ok (XOR, DImode, operands)"
9258   "@
9259    xor{q}\t{%2, %0|%0, %2}
9260    xor{q}\t{%2, %0|%0, %2}"
9261   [(set_attr "type" "alu")
9262    (set_attr "mode" "DI,DI")])
9263
9264 (define_insn "*xordi_3_rex64"
9265   [(set (reg FLAGS_REG)
9266         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9267                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9268                  (const_int 0)))
9269    (clobber (match_scratch:DI 0 "=r"))]
9270   "TARGET_64BIT
9271    && ix86_match_ccmode (insn, CCNOmode)
9272    && ix86_binary_operator_ok (XOR, DImode, operands)"
9273   "xor{q}\t{%2, %0|%0, %2}"
9274   [(set_attr "type" "alu")
9275    (set_attr "mode" "DI")])
9276
9277 (define_expand "xorsi3"
9278   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9279         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9280                 (match_operand:SI 2 "general_operand" "")))
9281    (clobber (reg:CC FLAGS_REG))]
9282   ""
9283   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9284
9285 (define_insn "*xorsi_1"
9286   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9287         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9288                 (match_operand:SI 2 "general_operand" "ri,rm")))
9289    (clobber (reg:CC FLAGS_REG))]
9290   "ix86_binary_operator_ok (XOR, SImode, operands)"
9291   "xor{l}\t{%2, %0|%0, %2}"
9292   [(set_attr "type" "alu")
9293    (set_attr "mode" "SI")])
9294
9295 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9296 ;; Add speccase for immediates
9297 (define_insn "*xorsi_1_zext"
9298   [(set (match_operand:DI 0 "register_operand" "=r")
9299         (zero_extend:DI
9300           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9301                   (match_operand:SI 2 "general_operand" "rim"))))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9304   "xor{l}\t{%2, %k0|%k0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "mode" "SI")])
9307
9308 (define_insn "*xorsi_1_zext_imm"
9309   [(set (match_operand:DI 0 "register_operand" "=r")
9310         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9311                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9312    (clobber (reg:CC FLAGS_REG))]
9313   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9314   "xor{l}\t{%2, %k0|%k0, %2}"
9315   [(set_attr "type" "alu")
9316    (set_attr "mode" "SI")])
9317
9318 (define_insn "*xorsi_2"
9319   [(set (reg FLAGS_REG)
9320         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9321                          (match_operand:SI 2 "general_operand" "rim,ri"))
9322                  (const_int 0)))
9323    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9324         (xor:SI (match_dup 1) (match_dup 2)))]
9325   "ix86_match_ccmode (insn, CCNOmode)
9326    && ix86_binary_operator_ok (XOR, SImode, operands)"
9327   "xor{l}\t{%2, %0|%0, %2}"
9328   [(set_attr "type" "alu")
9329    (set_attr "mode" "SI")])
9330
9331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9332 ;; ??? Special case for immediate operand is missing - it is tricky.
9333 (define_insn "*xorsi_2_zext"
9334   [(set (reg FLAGS_REG)
9335         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9336                          (match_operand:SI 2 "general_operand" "rim"))
9337                  (const_int 0)))
9338    (set (match_operand:DI 0 "register_operand" "=r")
9339         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9340   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9341    && ix86_binary_operator_ok (XOR, SImode, operands)"
9342   "xor{l}\t{%2, %k0|%k0, %2}"
9343   [(set_attr "type" "alu")
9344    (set_attr "mode" "SI")])
9345
9346 (define_insn "*xorsi_2_zext_imm"
9347   [(set (reg FLAGS_REG)
9348         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9350                  (const_int 0)))
9351    (set (match_operand:DI 0 "register_operand" "=r")
9352         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9353   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354    && ix86_binary_operator_ok (XOR, SImode, operands)"
9355   "xor{l}\t{%2, %k0|%k0, %2}"
9356   [(set_attr "type" "alu")
9357    (set_attr "mode" "SI")])
9358
9359 (define_insn "*xorsi_3"
9360   [(set (reg FLAGS_REG)
9361         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362                          (match_operand:SI 2 "general_operand" "rim"))
9363                  (const_int 0)))
9364    (clobber (match_scratch:SI 0 "=r"))]
9365   "ix86_match_ccmode (insn, CCNOmode)
9366    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9367   "xor{l}\t{%2, %0|%0, %2}"
9368   [(set_attr "type" "alu")
9369    (set_attr "mode" "SI")])
9370
9371 (define_expand "xorhi3"
9372   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9373         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9374                 (match_operand:HI 2 "general_operand" "")))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "TARGET_HIMODE_MATH"
9377   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9378
9379 (define_insn "*xorhi_1"
9380   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9381         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9382                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9383    (clobber (reg:CC FLAGS_REG))]
9384   "ix86_binary_operator_ok (XOR, HImode, operands)"
9385   "xor{w}\t{%2, %0|%0, %2}"
9386   [(set_attr "type" "alu")
9387    (set_attr "mode" "HI")])
9388
9389 (define_insn "*xorhi_2"
9390   [(set (reg FLAGS_REG)
9391         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9392                          (match_operand:HI 2 "general_operand" "rim,ri"))
9393                  (const_int 0)))
9394    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9395         (xor:HI (match_dup 1) (match_dup 2)))]
9396   "ix86_match_ccmode (insn, CCNOmode)
9397    && ix86_binary_operator_ok (XOR, HImode, operands)"
9398   "xor{w}\t{%2, %0|%0, %2}"
9399   [(set_attr "type" "alu")
9400    (set_attr "mode" "HI")])
9401
9402 (define_insn "*xorhi_3"
9403   [(set (reg FLAGS_REG)
9404         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9405                          (match_operand:HI 2 "general_operand" "rim"))
9406                  (const_int 0)))
9407    (clobber (match_scratch:HI 0 "=r"))]
9408   "ix86_match_ccmode (insn, CCNOmode)
9409    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410   "xor{w}\t{%2, %0|%0, %2}"
9411   [(set_attr "type" "alu")
9412    (set_attr "mode" "HI")])
9413
9414 (define_expand "xorqi3"
9415   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9416         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9417                 (match_operand:QI 2 "general_operand" "")))
9418    (clobber (reg:CC FLAGS_REG))]
9419   "TARGET_QIMODE_MATH"
9420   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9421
9422 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9423 (define_insn "*xorqi_1"
9424   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9425         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9426                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "ix86_binary_operator_ok (XOR, QImode, operands)"
9429   "@
9430    xor{b}\t{%2, %0|%0, %2}
9431    xor{b}\t{%2, %0|%0, %2}
9432    xor{l}\t{%k2, %k0|%k0, %k2}"
9433   [(set_attr "type" "alu")
9434    (set_attr "mode" "QI,QI,SI")])
9435
9436 (define_insn "*xorqi_1_slp"
9437   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9438         (xor:QI (match_dup 0)
9439                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9443   "xor{b}\t{%1, %0|%0, %1}"
9444   [(set_attr "type" "alu1")
9445    (set_attr "mode" "QI")])
9446
9447 (define_insn "xorqi_ext_0"
9448   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9449                          (const_int 8)
9450                          (const_int 8))
9451         (xor:SI
9452           (zero_extract:SI
9453             (match_operand 1 "ext_register_operand" "0")
9454             (const_int 8)
9455             (const_int 8))
9456           (match_operand 2 "const_int_operand" "n")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9459   "xor{b}\t{%2, %h0|%h0, %2}"
9460   [(set_attr "type" "alu")
9461    (set_attr "length_immediate" "1")
9462    (set_attr "mode" "QI")])
9463
9464 (define_insn "*xorqi_ext_1"
9465   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466                          (const_int 8)
9467                          (const_int 8))
9468         (xor:SI
9469           (zero_extract:SI
9470             (match_operand 1 "ext_register_operand" "0")
9471             (const_int 8)
9472             (const_int 8))
9473           (zero_extend:SI
9474             (match_operand:QI 2 "general_operand" "Qm"))))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "!TARGET_64BIT
9477    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9478   "xor{b}\t{%2, %h0|%h0, %2}"
9479   [(set_attr "type" "alu")
9480    (set_attr "length_immediate" "0")
9481    (set_attr "mode" "QI")])
9482
9483 (define_insn "*xorqi_ext_1_rex64"
9484   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9485                          (const_int 8)
9486                          (const_int 8))
9487         (xor:SI
9488           (zero_extract:SI
9489             (match_operand 1 "ext_register_operand" "0")
9490             (const_int 8)
9491             (const_int 8))
9492           (zero_extend:SI
9493             (match_operand 2 "ext_register_operand" "Q"))))
9494    (clobber (reg:CC FLAGS_REG))]
9495   "TARGET_64BIT
9496    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9497   "xor{b}\t{%2, %h0|%h0, %2}"
9498   [(set_attr "type" "alu")
9499    (set_attr "length_immediate" "0")
9500    (set_attr "mode" "QI")])
9501
9502 (define_insn "*xorqi_ext_2"
9503   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9504                          (const_int 8)
9505                          (const_int 8))
9506         (xor:SI
9507           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9508                            (const_int 8)
9509                            (const_int 8))
9510           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9511                            (const_int 8)
9512                            (const_int 8))))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515   "xor{b}\t{%h2, %h0|%h0, %h2}"
9516   [(set_attr "type" "alu")
9517    (set_attr "length_immediate" "0")
9518    (set_attr "mode" "QI")])
9519
9520 (define_insn "*xorqi_cc_1"
9521   [(set (reg FLAGS_REG)
9522         (compare
9523           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9524                   (match_operand:QI 2 "general_operand" "qim,qi"))
9525           (const_int 0)))
9526    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9527         (xor:QI (match_dup 1) (match_dup 2)))]
9528   "ix86_match_ccmode (insn, CCNOmode)
9529    && ix86_binary_operator_ok (XOR, QImode, operands)"
9530   "xor{b}\t{%2, %0|%0, %2}"
9531   [(set_attr "type" "alu")
9532    (set_attr "mode" "QI")])
9533
9534 (define_insn "*xorqi_2_slp"
9535   [(set (reg FLAGS_REG)
9536         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9537                          (match_operand:QI 1 "general_operand" "qim,qi"))
9538                  (const_int 0)))
9539    (set (strict_low_part (match_dup 0))
9540         (xor:QI (match_dup 0) (match_dup 1)))]
9541   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9542    && ix86_match_ccmode (insn, CCNOmode)
9543    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9544   "xor{b}\t{%1, %0|%0, %1}"
9545   [(set_attr "type" "alu1")
9546    (set_attr "mode" "QI")])
9547
9548 (define_insn "*xorqi_cc_2"
9549   [(set (reg FLAGS_REG)
9550         (compare
9551           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9552                   (match_operand:QI 2 "general_operand" "qim"))
9553           (const_int 0)))
9554    (clobber (match_scratch:QI 0 "=q"))]
9555   "ix86_match_ccmode (insn, CCNOmode)
9556    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9557   "xor{b}\t{%2, %0|%0, %2}"
9558   [(set_attr "type" "alu")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_cc_ext_1"
9562   [(set (reg FLAGS_REG)
9563         (compare
9564           (xor:SI
9565             (zero_extract:SI
9566               (match_operand 1 "ext_register_operand" "0")
9567               (const_int 8)
9568               (const_int 8))
9569             (match_operand:QI 2 "general_operand" "qmn"))
9570           (const_int 0)))
9571    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9572                          (const_int 8)
9573                          (const_int 8))
9574         (xor:SI
9575           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9576           (match_dup 2)))]
9577   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9578   "xor{b}\t{%2, %h0|%h0, %2}"
9579   [(set_attr "type" "alu")
9580    (set_attr "mode" "QI")])
9581
9582 (define_insn "*xorqi_cc_ext_1_rex64"
9583   [(set (reg FLAGS_REG)
9584         (compare
9585           (xor:SI
9586             (zero_extract:SI
9587               (match_operand 1 "ext_register_operand" "0")
9588               (const_int 8)
9589               (const_int 8))
9590             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9591           (const_int 0)))
9592    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9593                          (const_int 8)
9594                          (const_int 8))
9595         (xor:SI
9596           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9597           (match_dup 2)))]
9598   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9599   "xor{b}\t{%2, %h0|%h0, %2}"
9600   [(set_attr "type" "alu")
9601    (set_attr "mode" "QI")])
9602
9603 (define_expand "xorqi_cc_ext_1"
9604   [(parallel [
9605      (set (reg:CCNO FLAGS_REG)
9606           (compare:CCNO
9607             (xor:SI
9608               (zero_extract:SI
9609                 (match_operand 1 "ext_register_operand" "")
9610                 (const_int 8)
9611                 (const_int 8))
9612               (match_operand:QI 2 "general_operand" ""))
9613             (const_int 0)))
9614      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9615                            (const_int 8)
9616                            (const_int 8))
9617           (xor:SI
9618             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9619             (match_dup 2)))])]
9620   ""
9621   "")
9622
9623 (define_split
9624   [(set (match_operand 0 "register_operand" "")
9625         (xor (match_operand 1 "register_operand" "")
9626              (match_operand 2 "const_int_operand" "")))
9627    (clobber (reg:CC FLAGS_REG))]
9628    "reload_completed
9629     && QI_REG_P (operands[0])
9630     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9631     && !(INTVAL (operands[2]) & ~(255 << 8))
9632     && GET_MODE (operands[0]) != QImode"
9633   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9634                    (xor:SI (zero_extract:SI (match_dup 1)
9635                                             (const_int 8) (const_int 8))
9636                            (match_dup 2)))
9637               (clobber (reg:CC FLAGS_REG))])]
9638   "operands[0] = gen_lowpart (SImode, operands[0]);
9639    operands[1] = gen_lowpart (SImode, operands[1]);
9640    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9641
9642 ;; Since XOR can be encoded with sign extended immediate, this is only
9643 ;; profitable when 7th bit is set.
9644 (define_split
9645   [(set (match_operand 0 "register_operand" "")
9646         (xor (match_operand 1 "general_operand" "")
9647              (match_operand 2 "const_int_operand" "")))
9648    (clobber (reg:CC FLAGS_REG))]
9649    "reload_completed
9650     && ANY_QI_REG_P (operands[0])
9651     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9652     && !(INTVAL (operands[2]) & ~255)
9653     && (INTVAL (operands[2]) & 128)
9654     && GET_MODE (operands[0]) != QImode"
9655   [(parallel [(set (strict_low_part (match_dup 0))
9656                    (xor:QI (match_dup 1)
9657                            (match_dup 2)))
9658               (clobber (reg:CC FLAGS_REG))])]
9659   "operands[0] = gen_lowpart (QImode, operands[0]);
9660    operands[1] = gen_lowpart (QImode, operands[1]);
9661    operands[2] = gen_lowpart (QImode, operands[2]);")
9662 \f
9663 ;; Negation instructions
9664
9665 (define_expand "negti2"
9666   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9667                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9668               (clobber (reg:CC FLAGS_REG))])]
9669   "TARGET_64BIT"
9670   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9671
9672 (define_insn "*negti2_1"
9673   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9674         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "TARGET_64BIT
9677    && ix86_unary_operator_ok (NEG, TImode, operands)"
9678   "#")
9679
9680 (define_split
9681   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9682         (neg:TI (match_operand:TI 1 "general_operand" "")))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "TARGET_64BIT && reload_completed"
9685   [(parallel
9686     [(set (reg:CCZ FLAGS_REG)
9687           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9688      (set (match_dup 0) (neg:DI (match_dup 2)))])
9689    (parallel
9690     [(set (match_dup 1)
9691           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9692                             (match_dup 3))
9693                    (const_int 0)))
9694      (clobber (reg:CC FLAGS_REG))])
9695    (parallel
9696     [(set (match_dup 1)
9697           (neg:DI (match_dup 1)))
9698      (clobber (reg:CC FLAGS_REG))])]
9699   "split_ti (operands+1, 1, operands+2, operands+3);
9700    split_ti (operands+0, 1, operands+0, operands+1);")
9701
9702 (define_expand "negdi2"
9703   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9704                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9705               (clobber (reg:CC FLAGS_REG))])]
9706   ""
9707   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9708
9709 (define_insn "*negdi2_1"
9710   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9711         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9712    (clobber (reg:CC FLAGS_REG))]
9713   "!TARGET_64BIT
9714    && ix86_unary_operator_ok (NEG, DImode, operands)"
9715   "#")
9716
9717 (define_split
9718   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9719         (neg:DI (match_operand:DI 1 "general_operand" "")))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "!TARGET_64BIT && reload_completed"
9722   [(parallel
9723     [(set (reg:CCZ FLAGS_REG)
9724           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9725      (set (match_dup 0) (neg:SI (match_dup 2)))])
9726    (parallel
9727     [(set (match_dup 1)
9728           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9729                             (match_dup 3))
9730                    (const_int 0)))
9731      (clobber (reg:CC FLAGS_REG))])
9732    (parallel
9733     [(set (match_dup 1)
9734           (neg:SI (match_dup 1)))
9735      (clobber (reg:CC FLAGS_REG))])]
9736   "split_di (operands+1, 1, operands+2, operands+3);
9737    split_di (operands+0, 1, operands+0, operands+1);")
9738
9739 (define_insn "*negdi2_1_rex64"
9740   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9741         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9742    (clobber (reg:CC FLAGS_REG))]
9743   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9744   "neg{q}\t%0"
9745   [(set_attr "type" "negnot")
9746    (set_attr "mode" "DI")])
9747
9748 ;; The problem with neg is that it does not perform (compare x 0),
9749 ;; it really performs (compare 0 x), which leaves us with the zero
9750 ;; flag being the only useful item.
9751
9752 (define_insn "*negdi2_cmpz_rex64"
9753   [(set (reg:CCZ FLAGS_REG)
9754         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9755                      (const_int 0)))
9756    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9757         (neg:DI (match_dup 1)))]
9758   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9759   "neg{q}\t%0"
9760   [(set_attr "type" "negnot")
9761    (set_attr "mode" "DI")])
9762
9763
9764 (define_expand "negsi2"
9765   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9766                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9767               (clobber (reg:CC FLAGS_REG))])]
9768   ""
9769   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9770
9771 (define_insn "*negsi2_1"
9772   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9773         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9774    (clobber (reg:CC FLAGS_REG))]
9775   "ix86_unary_operator_ok (NEG, SImode, operands)"
9776   "neg{l}\t%0"
9777   [(set_attr "type" "negnot")
9778    (set_attr "mode" "SI")])
9779
9780 ;; Combine is quite creative about this pattern.
9781 (define_insn "*negsi2_1_zext"
9782   [(set (match_operand:DI 0 "register_operand" "=r")
9783         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9784                                         (const_int 32)))
9785                      (const_int 32)))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9788   "neg{l}\t%k0"
9789   [(set_attr "type" "negnot")
9790    (set_attr "mode" "SI")])
9791
9792 ;; The problem with neg is that it does not perform (compare x 0),
9793 ;; it really performs (compare 0 x), which leaves us with the zero
9794 ;; flag being the only useful item.
9795
9796 (define_insn "*negsi2_cmpz"
9797   [(set (reg:CCZ FLAGS_REG)
9798         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9799                      (const_int 0)))
9800    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9801         (neg:SI (match_dup 1)))]
9802   "ix86_unary_operator_ok (NEG, SImode, operands)"
9803   "neg{l}\t%0"
9804   [(set_attr "type" "negnot")
9805    (set_attr "mode" "SI")])
9806
9807 (define_insn "*negsi2_cmpz_zext"
9808   [(set (reg:CCZ FLAGS_REG)
9809         (compare:CCZ (lshiftrt:DI
9810                        (neg:DI (ashift:DI
9811                                  (match_operand:DI 1 "register_operand" "0")
9812                                  (const_int 32)))
9813                        (const_int 32))
9814                      (const_int 0)))
9815    (set (match_operand:DI 0 "register_operand" "=r")
9816         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9817                                         (const_int 32)))
9818                      (const_int 32)))]
9819   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9820   "neg{l}\t%k0"
9821   [(set_attr "type" "negnot")
9822    (set_attr "mode" "SI")])
9823
9824 (define_expand "neghi2"
9825   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9826                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9827               (clobber (reg:CC FLAGS_REG))])]
9828   "TARGET_HIMODE_MATH"
9829   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9830
9831 (define_insn "*neghi2_1"
9832   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9833         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "ix86_unary_operator_ok (NEG, HImode, operands)"
9836   "neg{w}\t%0"
9837   [(set_attr "type" "negnot")
9838    (set_attr "mode" "HI")])
9839
9840 (define_insn "*neghi2_cmpz"
9841   [(set (reg:CCZ FLAGS_REG)
9842         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9843                      (const_int 0)))
9844    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9845         (neg:HI (match_dup 1)))]
9846   "ix86_unary_operator_ok (NEG, HImode, operands)"
9847   "neg{w}\t%0"
9848   [(set_attr "type" "negnot")
9849    (set_attr "mode" "HI")])
9850
9851 (define_expand "negqi2"
9852   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9853                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9854               (clobber (reg:CC FLAGS_REG))])]
9855   "TARGET_QIMODE_MATH"
9856   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9857
9858 (define_insn "*negqi2_1"
9859   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9860         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "ix86_unary_operator_ok (NEG, QImode, operands)"
9863   "neg{b}\t%0"
9864   [(set_attr "type" "negnot")
9865    (set_attr "mode" "QI")])
9866
9867 (define_insn "*negqi2_cmpz"
9868   [(set (reg:CCZ FLAGS_REG)
9869         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9870                      (const_int 0)))
9871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9872         (neg:QI (match_dup 1)))]
9873   "ix86_unary_operator_ok (NEG, QImode, operands)"
9874   "neg{b}\t%0"
9875   [(set_attr "type" "negnot")
9876    (set_attr "mode" "QI")])
9877
9878 ;; Changing of sign for FP values is doable using integer unit too.
9879
9880 (define_expand "negsf2"
9881   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9882         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9883   "TARGET_80387 || TARGET_SSE_MATH"
9884   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9885
9886 (define_expand "abssf2"
9887   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9888         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9889   "TARGET_80387 || TARGET_SSE_MATH"
9890   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9891
9892 (define_insn "*absnegsf2_mixed"
9893   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9894         (match_operator:SF 3 "absneg_operator"
9895           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9896    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9897    (clobber (reg:CC FLAGS_REG))]
9898   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9899    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9900   "#")
9901
9902 (define_insn "*absnegsf2_sse"
9903   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9904         (match_operator:SF 3 "absneg_operator"
9905           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9906    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "TARGET_SSE_MATH
9909    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9910   "#")
9911
9912 (define_insn "*absnegsf2_i387"
9913   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9914         (match_operator:SF 3 "absneg_operator"
9915           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9916    (use (match_operand 2 "" ""))
9917    (clobber (reg:CC FLAGS_REG))]
9918   "TARGET_80387 && !TARGET_SSE_MATH
9919    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9920   "#")
9921
9922 (define_expand "copysignsf3"
9923   [(match_operand:SF 0 "register_operand" "")
9924    (match_operand:SF 1 "nonmemory_operand" "")
9925    (match_operand:SF 2 "register_operand" "")]
9926   "TARGET_SSE_MATH"
9927 {
9928   ix86_expand_copysign (operands);
9929   DONE;
9930 })
9931
9932 (define_insn_and_split "copysignsf3_const"
9933   [(set (match_operand:SF 0 "register_operand"          "=x")
9934         (unspec:SF
9935           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9936            (match_operand:SF 2 "register_operand"       "0")
9937            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9938           UNSPEC_COPYSIGN))]
9939   "TARGET_SSE_MATH"
9940   "#"
9941   "&& reload_completed"
9942   [(const_int 0)]
9943 {
9944   ix86_split_copysign_const (operands);
9945   DONE;
9946 })
9947
9948 (define_insn "copysignsf3_var"
9949   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9950         (unspec:SF
9951           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9952            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9953            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9954            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9955           UNSPEC_COPYSIGN))
9956    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9957   "TARGET_SSE_MATH"
9958   "#")
9959
9960 (define_split
9961   [(set (match_operand:SF 0 "register_operand" "")
9962         (unspec:SF
9963           [(match_operand:SF 2 "register_operand" "")
9964            (match_operand:SF 3 "register_operand" "")
9965            (match_operand:V4SF 4 "" "")
9966            (match_operand:V4SF 5 "" "")]
9967           UNSPEC_COPYSIGN))
9968    (clobber (match_scratch:V4SF 1 ""))]
9969   "TARGET_SSE_MATH && reload_completed"
9970   [(const_int 0)]
9971 {
9972   ix86_split_copysign_var (operands);
9973   DONE;
9974 })
9975
9976 (define_expand "negdf2"
9977   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9978         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9979   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9980   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9981
9982 (define_expand "absdf2"
9983   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9984         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9985   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9986   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9987
9988 (define_insn "*absnegdf2_mixed"
9989   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9990         (match_operator:DF 3 "absneg_operator"
9991           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9992    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9993    (clobber (reg:CC FLAGS_REG))]
9994   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9995    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9996   "#")
9997
9998 (define_insn "*absnegdf2_sse"
9999   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10000         (match_operator:DF 3 "absneg_operator"
10001           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10002    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10003    (clobber (reg:CC FLAGS_REG))]
10004   "TARGET_SSE2 && TARGET_SSE_MATH
10005    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10006   "#")
10007
10008 (define_insn "*absnegdf2_i387"
10009   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10010         (match_operator:DF 3 "absneg_operator"
10011           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10012    (use (match_operand 2 "" ""))
10013    (clobber (reg:CC FLAGS_REG))]
10014   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10015    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10016   "#")
10017
10018 (define_expand "copysigndf3"
10019   [(match_operand:DF 0 "register_operand" "")
10020    (match_operand:DF 1 "nonmemory_operand" "")
10021    (match_operand:DF 2 "register_operand" "")]
10022   "TARGET_SSE2 && TARGET_SSE_MATH"
10023 {
10024   ix86_expand_copysign (operands);
10025   DONE;
10026 })
10027
10028 (define_insn_and_split "copysigndf3_const"
10029   [(set (match_operand:DF 0 "register_operand"          "=x")
10030         (unspec:DF
10031           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
10032            (match_operand:DF 2 "register_operand"       "0")
10033            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10034           UNSPEC_COPYSIGN))]
10035   "TARGET_SSE2 && TARGET_SSE_MATH"
10036   "#"
10037   "&& reload_completed"
10038   [(const_int 0)]
10039 {
10040   ix86_split_copysign_const (operands);
10041   DONE;
10042 })
10043
10044 (define_insn "copysigndf3_var"
10045   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
10046         (unspec:DF
10047           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
10048            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
10049            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10050            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10051           UNSPEC_COPYSIGN))
10052    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
10053   "TARGET_SSE2 && TARGET_SSE_MATH"
10054   "#")
10055
10056 (define_split
10057   [(set (match_operand:DF 0 "register_operand" "")
10058         (unspec:DF
10059           [(match_operand:DF 2 "register_operand" "")
10060            (match_operand:DF 3 "register_operand" "")
10061            (match_operand:V2DF 4 "" "")
10062            (match_operand:V2DF 5 "" "")]
10063           UNSPEC_COPYSIGN))
10064    (clobber (match_scratch:V2DF 1 ""))]
10065   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10066   [(const_int 0)]
10067 {
10068   ix86_split_copysign_var (operands);
10069   DONE;
10070 })
10071
10072 (define_expand "negxf2"
10073   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10074         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10075   "TARGET_80387"
10076   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10077
10078 (define_expand "absxf2"
10079   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10080         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10081   "TARGET_80387"
10082   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10083
10084 (define_insn "*absnegxf2_i387"
10085   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10086         (match_operator:XF 3 "absneg_operator"
10087           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10088    (use (match_operand 2 "" ""))
10089    (clobber (reg:CC FLAGS_REG))]
10090   "TARGET_80387
10091    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10092   "#")
10093
10094 ;; Splitters for fp abs and neg.
10095
10096 (define_split
10097   [(set (match_operand 0 "fp_register_operand" "")
10098         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10099    (use (match_operand 2 "" ""))
10100    (clobber (reg:CC FLAGS_REG))]
10101   "reload_completed"
10102   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10103
10104 (define_split
10105   [(set (match_operand 0 "register_operand" "")
10106         (match_operator 3 "absneg_operator"
10107           [(match_operand 1 "register_operand" "")]))
10108    (use (match_operand 2 "nonimmediate_operand" ""))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "reload_completed && SSE_REG_P (operands[0])"
10111   [(set (match_dup 0) (match_dup 3))]
10112 {
10113   enum machine_mode mode = GET_MODE (operands[0]);
10114   enum machine_mode vmode = GET_MODE (operands[2]);
10115   rtx tmp;
10116
10117   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10118   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10119   if (operands_match_p (operands[0], operands[2]))
10120     {
10121       tmp = operands[1];
10122       operands[1] = operands[2];
10123       operands[2] = tmp;
10124     }
10125   if (GET_CODE (operands[3]) == ABS)
10126     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10127   else
10128     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10129   operands[3] = tmp;
10130 })
10131
10132 (define_split
10133   [(set (match_operand:SF 0 "register_operand" "")
10134         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10135    (use (match_operand:V4SF 2 "" ""))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "reload_completed"
10138   [(parallel [(set (match_dup 0) (match_dup 1))
10139               (clobber (reg:CC FLAGS_REG))])]
10140 {
10141   rtx tmp;
10142   operands[0] = gen_lowpart (SImode, operands[0]);
10143   if (GET_CODE (operands[1]) == ABS)
10144     {
10145       tmp = gen_int_mode (0x7fffffff, SImode);
10146       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10147     }
10148   else
10149     {
10150       tmp = gen_int_mode (0x80000000, SImode);
10151       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10152     }
10153   operands[1] = tmp;
10154 })
10155
10156 (define_split
10157   [(set (match_operand:DF 0 "register_operand" "")
10158         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10159    (use (match_operand 2 "" ""))
10160    (clobber (reg:CC FLAGS_REG))]
10161   "reload_completed"
10162   [(parallel [(set (match_dup 0) (match_dup 1))
10163               (clobber (reg:CC FLAGS_REG))])]
10164 {
10165   rtx tmp;
10166   if (TARGET_64BIT)
10167     {
10168       tmp = gen_lowpart (DImode, operands[0]);
10169       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10170       operands[0] = tmp;
10171
10172       if (GET_CODE (operands[1]) == ABS)
10173         tmp = const0_rtx;
10174       else
10175         tmp = gen_rtx_NOT (DImode, tmp);
10176     }
10177   else
10178     {
10179       operands[0] = gen_highpart (SImode, operands[0]);
10180       if (GET_CODE (operands[1]) == ABS)
10181         {
10182           tmp = gen_int_mode (0x7fffffff, SImode);
10183           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10184         }
10185       else
10186         {
10187           tmp = gen_int_mode (0x80000000, SImode);
10188           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10189         }
10190     }
10191   operands[1] = tmp;
10192 })
10193
10194 (define_split
10195   [(set (match_operand:XF 0 "register_operand" "")
10196         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10197    (use (match_operand 2 "" ""))
10198    (clobber (reg:CC FLAGS_REG))]
10199   "reload_completed"
10200   [(parallel [(set (match_dup 0) (match_dup 1))
10201               (clobber (reg:CC FLAGS_REG))])]
10202 {
10203   rtx tmp;
10204   operands[0] = gen_rtx_REG (SImode,
10205                              true_regnum (operands[0])
10206                              + (TARGET_64BIT ? 1 : 2));
10207   if (GET_CODE (operands[1]) == ABS)
10208     {
10209       tmp = GEN_INT (0x7fff);
10210       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10211     }
10212   else
10213     {
10214       tmp = GEN_INT (0x8000);
10215       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10216     }
10217   operands[1] = tmp;
10218 })
10219
10220 (define_split
10221   [(set (match_operand 0 "memory_operand" "")
10222         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10223    (use (match_operand 2 "" ""))
10224    (clobber (reg:CC FLAGS_REG))]
10225   "reload_completed"
10226   [(parallel [(set (match_dup 0) (match_dup 1))
10227               (clobber (reg:CC FLAGS_REG))])]
10228 {
10229   enum machine_mode mode = GET_MODE (operands[0]);
10230   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10231   rtx tmp;
10232
10233   operands[0] = adjust_address (operands[0], QImode, size - 1);
10234   if (GET_CODE (operands[1]) == ABS)
10235     {
10236       tmp = gen_int_mode (0x7f, QImode);
10237       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10238     }
10239   else
10240     {
10241       tmp = gen_int_mode (0x80, QImode);
10242       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10243     }
10244   operands[1] = tmp;
10245 })
10246
10247 ;; Conditionalize these after reload. If they match before reload, we
10248 ;; lose the clobber and ability to use integer instructions.
10249
10250 (define_insn "*negsf2_1"
10251   [(set (match_operand:SF 0 "register_operand" "=f")
10252         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10253   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10254   "fchs"
10255   [(set_attr "type" "fsgn")
10256    (set_attr "mode" "SF")])
10257
10258 (define_insn "*negdf2_1"
10259   [(set (match_operand:DF 0 "register_operand" "=f")
10260         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10261   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10262   "fchs"
10263   [(set_attr "type" "fsgn")
10264    (set_attr "mode" "DF")])
10265
10266 (define_insn "*negxf2_1"
10267   [(set (match_operand:XF 0 "register_operand" "=f")
10268         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10269   "TARGET_80387"
10270   "fchs"
10271   [(set_attr "type" "fsgn")
10272    (set_attr "mode" "XF")])
10273
10274 (define_insn "*abssf2_1"
10275   [(set (match_operand:SF 0 "register_operand" "=f")
10276         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10277   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10278   "fabs"
10279   [(set_attr "type" "fsgn")
10280    (set_attr "mode" "SF")])
10281
10282 (define_insn "*absdf2_1"
10283   [(set (match_operand:DF 0 "register_operand" "=f")
10284         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10285   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10286   "fabs"
10287   [(set_attr "type" "fsgn")
10288    (set_attr "mode" "DF")])
10289
10290 (define_insn "*absxf2_1"
10291   [(set (match_operand:XF 0 "register_operand" "=f")
10292         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10293   "TARGET_80387"
10294   "fabs"
10295   [(set_attr "type" "fsgn")
10296    (set_attr "mode" "DF")])
10297
10298 (define_insn "*negextendsfdf2"
10299   [(set (match_operand:DF 0 "register_operand" "=f")
10300         (neg:DF (float_extend:DF
10301                   (match_operand:SF 1 "register_operand" "0"))))]
10302   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10303   "fchs"
10304   [(set_attr "type" "fsgn")
10305    (set_attr "mode" "DF")])
10306
10307 (define_insn "*negextenddfxf2"
10308   [(set (match_operand:XF 0 "register_operand" "=f")
10309         (neg:XF (float_extend:XF
10310                   (match_operand:DF 1 "register_operand" "0"))))]
10311   "TARGET_80387"
10312   "fchs"
10313   [(set_attr "type" "fsgn")
10314    (set_attr "mode" "XF")])
10315
10316 (define_insn "*negextendsfxf2"
10317   [(set (match_operand:XF 0 "register_operand" "=f")
10318         (neg:XF (float_extend:XF
10319                   (match_operand:SF 1 "register_operand" "0"))))]
10320   "TARGET_80387"
10321   "fchs"
10322   [(set_attr "type" "fsgn")
10323    (set_attr "mode" "XF")])
10324
10325 (define_insn "*absextendsfdf2"
10326   [(set (match_operand:DF 0 "register_operand" "=f")
10327         (abs:DF (float_extend:DF
10328                   (match_operand:SF 1 "register_operand" "0"))))]
10329   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10330   "fabs"
10331   [(set_attr "type" "fsgn")
10332    (set_attr "mode" "DF")])
10333
10334 (define_insn "*absextenddfxf2"
10335   [(set (match_operand:XF 0 "register_operand" "=f")
10336         (abs:XF (float_extend:XF
10337           (match_operand:DF 1 "register_operand" "0"))))]
10338   "TARGET_80387"
10339   "fabs"
10340   [(set_attr "type" "fsgn")
10341    (set_attr "mode" "XF")])
10342
10343 (define_insn "*absextendsfxf2"
10344   [(set (match_operand:XF 0 "register_operand" "=f")
10345         (abs:XF (float_extend:XF
10346           (match_operand:SF 1 "register_operand" "0"))))]
10347   "TARGET_80387"
10348   "fabs"
10349   [(set_attr "type" "fsgn")
10350    (set_attr "mode" "XF")])
10351 \f
10352 ;; One complement instructions
10353
10354 (define_expand "one_cmpldi2"
10355   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10356         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10357   "TARGET_64BIT"
10358   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10359
10360 (define_insn "*one_cmpldi2_1_rex64"
10361   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10363   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10364   "not{q}\t%0"
10365   [(set_attr "type" "negnot")
10366    (set_attr "mode" "DI")])
10367
10368 (define_insn "*one_cmpldi2_2_rex64"
10369   [(set (reg FLAGS_REG)
10370         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10371                  (const_int 0)))
10372    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10373         (not:DI (match_dup 1)))]
10374   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10375    && ix86_unary_operator_ok (NOT, DImode, operands)"
10376   "#"
10377   [(set_attr "type" "alu1")
10378    (set_attr "mode" "DI")])
10379
10380 (define_split
10381   [(set (match_operand 0 "flags_reg_operand" "")
10382         (match_operator 2 "compare_operator"
10383           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10384            (const_int 0)]))
10385    (set (match_operand:DI 1 "nonimmediate_operand" "")
10386         (not:DI (match_dup 3)))]
10387   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10388   [(parallel [(set (match_dup 0)
10389                    (match_op_dup 2
10390                      [(xor:DI (match_dup 3) (const_int -1))
10391                       (const_int 0)]))
10392               (set (match_dup 1)
10393                    (xor:DI (match_dup 3) (const_int -1)))])]
10394   "")
10395
10396 (define_expand "one_cmplsi2"
10397   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10398         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10399   ""
10400   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10401
10402 (define_insn "*one_cmplsi2_1"
10403   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10404         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10405   "ix86_unary_operator_ok (NOT, SImode, operands)"
10406   "not{l}\t%0"
10407   [(set_attr "type" "negnot")
10408    (set_attr "mode" "SI")])
10409
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_1_zext"
10412   [(set (match_operand:DI 0 "register_operand" "=r")
10413         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10414   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10415   "not{l}\t%k0"
10416   [(set_attr "type" "negnot")
10417    (set_attr "mode" "SI")])
10418
10419 (define_insn "*one_cmplsi2_2"
10420   [(set (reg FLAGS_REG)
10421         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10422                  (const_int 0)))
10423    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424         (not:SI (match_dup 1)))]
10425   "ix86_match_ccmode (insn, CCNOmode)
10426    && ix86_unary_operator_ok (NOT, SImode, operands)"
10427   "#"
10428   [(set_attr "type" "alu1")
10429    (set_attr "mode" "SI")])
10430
10431 (define_split
10432   [(set (match_operand 0 "flags_reg_operand" "")
10433         (match_operator 2 "compare_operator"
10434           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10435            (const_int 0)]))
10436    (set (match_operand:SI 1 "nonimmediate_operand" "")
10437         (not:SI (match_dup 3)))]
10438   "ix86_match_ccmode (insn, CCNOmode)"
10439   [(parallel [(set (match_dup 0)
10440                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10441                                     (const_int 0)]))
10442               (set (match_dup 1)
10443                    (xor:SI (match_dup 3) (const_int -1)))])]
10444   "")
10445
10446 ;; ??? Currently never generated - xor is used instead.
10447 (define_insn "*one_cmplsi2_2_zext"
10448   [(set (reg FLAGS_REG)
10449         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10450                  (const_int 0)))
10451    (set (match_operand:DI 0 "register_operand" "=r")
10452         (zero_extend:DI (not:SI (match_dup 1))))]
10453   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10454    && ix86_unary_operator_ok (NOT, SImode, operands)"
10455   "#"
10456   [(set_attr "type" "alu1")
10457    (set_attr "mode" "SI")])
10458
10459 (define_split
10460   [(set (match_operand 0 "flags_reg_operand" "")
10461         (match_operator 2 "compare_operator"
10462           [(not:SI (match_operand:SI 3 "register_operand" ""))
10463            (const_int 0)]))
10464    (set (match_operand:DI 1 "register_operand" "")
10465         (zero_extend:DI (not:SI (match_dup 3))))]
10466   "ix86_match_ccmode (insn, CCNOmode)"
10467   [(parallel [(set (match_dup 0)
10468                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10469                                     (const_int 0)]))
10470               (set (match_dup 1)
10471                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10472   "")
10473
10474 (define_expand "one_cmplhi2"
10475   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10476         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10477   "TARGET_HIMODE_MATH"
10478   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10479
10480 (define_insn "*one_cmplhi2_1"
10481   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10483   "ix86_unary_operator_ok (NOT, HImode, operands)"
10484   "not{w}\t%0"
10485   [(set_attr "type" "negnot")
10486    (set_attr "mode" "HI")])
10487
10488 (define_insn "*one_cmplhi2_2"
10489   [(set (reg FLAGS_REG)
10490         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10491                  (const_int 0)))
10492    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10493         (not:HI (match_dup 1)))]
10494   "ix86_match_ccmode (insn, CCNOmode)
10495    && ix86_unary_operator_ok (NEG, HImode, operands)"
10496   "#"
10497   [(set_attr "type" "alu1")
10498    (set_attr "mode" "HI")])
10499
10500 (define_split
10501   [(set (match_operand 0 "flags_reg_operand" "")
10502         (match_operator 2 "compare_operator"
10503           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10504            (const_int 0)]))
10505    (set (match_operand:HI 1 "nonimmediate_operand" "")
10506         (not:HI (match_dup 3)))]
10507   "ix86_match_ccmode (insn, CCNOmode)"
10508   [(parallel [(set (match_dup 0)
10509                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10510                                     (const_int 0)]))
10511               (set (match_dup 1)
10512                    (xor:HI (match_dup 3) (const_int -1)))])]
10513   "")
10514
10515 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10516 (define_expand "one_cmplqi2"
10517   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519   "TARGET_QIMODE_MATH"
10520   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10521
10522 (define_insn "*one_cmplqi2_1"
10523   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525   "ix86_unary_operator_ok (NOT, QImode, operands)"
10526   "@
10527    not{b}\t%0
10528    not{l}\t%k0"
10529   [(set_attr "type" "negnot")
10530    (set_attr "mode" "QI,SI")])
10531
10532 (define_insn "*one_cmplqi2_2"
10533   [(set (reg FLAGS_REG)
10534         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10535                  (const_int 0)))
10536    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537         (not:QI (match_dup 1)))]
10538   "ix86_match_ccmode (insn, CCNOmode)
10539    && ix86_unary_operator_ok (NOT, QImode, operands)"
10540   "#"
10541   [(set_attr "type" "alu1")
10542    (set_attr "mode" "QI")])
10543
10544 (define_split
10545   [(set (match_operand 0 "flags_reg_operand" "")
10546         (match_operator 2 "compare_operator"
10547           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10548            (const_int 0)]))
10549    (set (match_operand:QI 1 "nonimmediate_operand" "")
10550         (not:QI (match_dup 3)))]
10551   "ix86_match_ccmode (insn, CCNOmode)"
10552   [(parallel [(set (match_dup 0)
10553                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10554                                     (const_int 0)]))
10555               (set (match_dup 1)
10556                    (xor:QI (match_dup 3) (const_int -1)))])]
10557   "")
10558 \f
10559 ;; Arithmetic shift instructions
10560
10561 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10562 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10563 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10564 ;; from the assembler input.
10565 ;;
10566 ;; This instruction shifts the target reg/mem as usual, but instead of
10567 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10568 ;; is a left shift double, bits are taken from the high order bits of
10569 ;; reg, else if the insn is a shift right double, bits are taken from the
10570 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10571 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10572 ;;
10573 ;; Since sh[lr]d does not change the `reg' operand, that is done
10574 ;; separately, making all shifts emit pairs of shift double and normal
10575 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10576 ;; support a 63 bit shift, each shift where the count is in a reg expands
10577 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10578 ;;
10579 ;; If the shift count is a constant, we need never emit more than one
10580 ;; shift pair, instead using moves and sign extension for counts greater
10581 ;; than 31.
10582
10583 (define_expand "ashlti3"
10584   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10585                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10586                               (match_operand:QI 2 "nonmemory_operand" "")))
10587               (clobber (reg:CC FLAGS_REG))])]
10588   "TARGET_64BIT"
10589 {
10590   if (! immediate_operand (operands[2], QImode))
10591     {
10592       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10593       DONE;
10594     }
10595   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10596   DONE;
10597 })
10598
10599 (define_insn "ashlti3_1"
10600   [(set (match_operand:TI 0 "register_operand" "=r")
10601         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10602                    (match_operand:QI 2 "register_operand" "c")))
10603    (clobber (match_scratch:DI 3 "=&r"))
10604    (clobber (reg:CC FLAGS_REG))]
10605   "TARGET_64BIT"
10606   "#"
10607   [(set_attr "type" "multi")])
10608
10609 (define_insn "*ashlti3_2"
10610   [(set (match_operand:TI 0 "register_operand" "=r")
10611         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10612                    (match_operand:QI 2 "immediate_operand" "O")))
10613    (clobber (reg:CC FLAGS_REG))]
10614   "TARGET_64BIT"
10615   "#"
10616   [(set_attr "type" "multi")])
10617
10618 (define_split
10619   [(set (match_operand:TI 0 "register_operand" "")
10620         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10621                    (match_operand:QI 2 "register_operand" "")))
10622    (clobber (match_scratch:DI 3 ""))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "TARGET_64BIT && reload_completed"
10625   [(const_int 0)]
10626   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10627
10628 (define_split
10629   [(set (match_operand:TI 0 "register_operand" "")
10630         (ashift:TI (match_operand:TI 1 "register_operand" "")
10631                    (match_operand:QI 2 "immediate_operand" "")))
10632    (clobber (reg:CC FLAGS_REG))]
10633   "TARGET_64BIT && reload_completed"
10634   [(const_int 0)]
10635   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10636
10637 (define_insn "x86_64_shld"
10638   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10639         (ior:DI (ashift:DI (match_dup 0)
10640                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10641                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10642                   (minus:QI (const_int 64) (match_dup 2)))))
10643    (clobber (reg:CC FLAGS_REG))]
10644   "TARGET_64BIT"
10645   "@
10646    shld{q}\t{%2, %1, %0|%0, %1, %2}
10647    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10648   [(set_attr "type" "ishift")
10649    (set_attr "prefix_0f" "1")
10650    (set_attr "mode" "DI")
10651    (set_attr "athlon_decode" "vector")
10652    (set_attr "amdfam10_decode" "vector")])   
10653
10654 (define_expand "x86_64_shift_adj"
10655   [(set (reg:CCZ FLAGS_REG)
10656         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10657                              (const_int 64))
10658                      (const_int 0)))
10659    (set (match_operand:DI 0 "register_operand" "")
10660         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10661                          (match_operand:DI 1 "register_operand" "")
10662                          (match_dup 0)))
10663    (set (match_dup 1)
10664         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10665                          (match_operand:DI 3 "register_operand" "r")
10666                          (match_dup 1)))]
10667   "TARGET_64BIT"
10668   "")
10669
10670 (define_expand "ashldi3"
10671   [(set (match_operand:DI 0 "shiftdi_operand" "")
10672         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10673                    (match_operand:QI 2 "nonmemory_operand" "")))]
10674   ""
10675   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10676
10677 (define_insn "*ashldi3_1_rex64"
10678   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10679         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10680                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10681    (clobber (reg:CC FLAGS_REG))]
10682   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10683 {
10684   switch (get_attr_type (insn))
10685     {
10686     case TYPE_ALU:
10687       gcc_assert (operands[2] == const1_rtx);
10688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10689       return "add{q}\t{%0, %0|%0, %0}";
10690
10691     case TYPE_LEA:
10692       gcc_assert (CONST_INT_P (operands[2]));
10693       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10694       operands[1] = gen_rtx_MULT (DImode, operands[1],
10695                                   GEN_INT (1 << INTVAL (operands[2])));
10696       return "lea{q}\t{%a1, %0|%0, %a1}";
10697
10698     default:
10699       if (REG_P (operands[2]))
10700         return "sal{q}\t{%b2, %0|%0, %b2}";
10701       else if (operands[2] == const1_rtx
10702                && (TARGET_SHIFT1 || optimize_size))
10703         return "sal{q}\t%0";
10704       else
10705         return "sal{q}\t{%2, %0|%0, %2}";
10706     }
10707 }
10708   [(set (attr "type")
10709      (cond [(eq_attr "alternative" "1")
10710               (const_string "lea")
10711             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10712                           (const_int 0))
10713                       (match_operand 0 "register_operand" ""))
10714                  (match_operand 2 "const1_operand" ""))
10715               (const_string "alu")
10716            ]
10717            (const_string "ishift")))
10718    (set_attr "mode" "DI")])
10719
10720 ;; Convert lea to the lea pattern to avoid flags dependency.
10721 (define_split
10722   [(set (match_operand:DI 0 "register_operand" "")
10723         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10724                    (match_operand:QI 2 "immediate_operand" "")))
10725    (clobber (reg:CC FLAGS_REG))]
10726   "TARGET_64BIT && reload_completed
10727    && true_regnum (operands[0]) != true_regnum (operands[1])"
10728   [(set (match_dup 0)
10729         (mult:DI (match_dup 1)
10730                  (match_dup 2)))]
10731   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10732
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags.  We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashldi3_cmp_rex64"
10737   [(set (reg FLAGS_REG)
10738         (compare
10739           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10740                      (match_operand:QI 2 "immediate_operand" "e"))
10741           (const_int 0)))
10742    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10743         (ashift:DI (match_dup 1) (match_dup 2)))]
10744   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10745    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10746    && (optimize_size
10747        || !TARGET_PARTIAL_FLAG_REG_STALL
10748        || (operands[2] == const1_rtx
10749            && (TARGET_SHIFT1
10750                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10751 {
10752   switch (get_attr_type (insn))
10753     {
10754     case TYPE_ALU:
10755       gcc_assert (operands[2] == const1_rtx);
10756       return "add{q}\t{%0, %0|%0, %0}";
10757
10758     default:
10759       if (REG_P (operands[2]))
10760         return "sal{q}\t{%b2, %0|%0, %b2}";
10761       else if (operands[2] == const1_rtx
10762                && (TARGET_SHIFT1 || optimize_size))
10763         return "sal{q}\t%0";
10764       else
10765         return "sal{q}\t{%2, %0|%0, %2}";
10766     }
10767 }
10768   [(set (attr "type")
10769      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10770                           (const_int 0))
10771                       (match_operand 0 "register_operand" ""))
10772                  (match_operand 2 "const1_operand" ""))
10773               (const_string "alu")
10774            ]
10775            (const_string "ishift")))
10776    (set_attr "mode" "DI")])
10777
10778 (define_insn "*ashldi3_cconly_rex64"
10779   [(set (reg FLAGS_REG)
10780         (compare
10781           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782                      (match_operand:QI 2 "immediate_operand" "e"))
10783           (const_int 0)))
10784    (clobber (match_scratch:DI 0 "=r"))]
10785   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10786    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10787    && (optimize_size
10788        || !TARGET_PARTIAL_FLAG_REG_STALL
10789        || (operands[2] == const1_rtx
10790            && (TARGET_SHIFT1
10791                || TARGET_DOUBLE_WITH_ADD)))"
10792 {
10793   switch (get_attr_type (insn))
10794     {
10795     case TYPE_ALU:
10796       gcc_assert (operands[2] == const1_rtx);
10797       return "add{q}\t{%0, %0|%0, %0}";
10798
10799     default:
10800       if (REG_P (operands[2]))
10801         return "sal{q}\t{%b2, %0|%0, %b2}";
10802       else if (operands[2] == const1_rtx
10803                && (TARGET_SHIFT1 || optimize_size))
10804         return "sal{q}\t%0";
10805       else
10806         return "sal{q}\t{%2, %0|%0, %2}";
10807     }
10808 }
10809   [(set (attr "type")
10810      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10811                           (const_int 0))
10812                       (match_operand 0 "register_operand" ""))
10813                  (match_operand 2 "const1_operand" ""))
10814               (const_string "alu")
10815            ]
10816            (const_string "ishift")))
10817    (set_attr "mode" "DI")])
10818
10819 (define_insn "*ashldi3_1"
10820   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10821         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10822                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10823    (clobber (reg:CC FLAGS_REG))]
10824   "!TARGET_64BIT"
10825   "#"
10826   [(set_attr "type" "multi")])
10827
10828 ;; By default we don't ask for a scratch register, because when DImode
10829 ;; values are manipulated, registers are already at a premium.  But if
10830 ;; we have one handy, we won't turn it away.
10831 (define_peephole2
10832   [(match_scratch:SI 3 "r")
10833    (parallel [(set (match_operand:DI 0 "register_operand" "")
10834                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10835                               (match_operand:QI 2 "nonmemory_operand" "")))
10836               (clobber (reg:CC FLAGS_REG))])
10837    (match_dup 3)]
10838   "!TARGET_64BIT && TARGET_CMOVE"
10839   [(const_int 0)]
10840   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10841
10842 (define_split
10843   [(set (match_operand:DI 0 "register_operand" "")
10844         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10845                    (match_operand:QI 2 "nonmemory_operand" "")))
10846    (clobber (reg:CC FLAGS_REG))]
10847   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10848                      ? flow2_completed : reload_completed)"
10849   [(const_int 0)]
10850   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10851
10852 (define_insn "x86_shld_1"
10853   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10854         (ior:SI (ashift:SI (match_dup 0)
10855                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10856                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10857                   (minus:QI (const_int 32) (match_dup 2)))))
10858    (clobber (reg:CC FLAGS_REG))]
10859   ""
10860   "@
10861    shld{l}\t{%2, %1, %0|%0, %1, %2}
10862    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10863   [(set_attr "type" "ishift")
10864    (set_attr "prefix_0f" "1")
10865    (set_attr "mode" "SI")
10866    (set_attr "pent_pair" "np")
10867    (set_attr "athlon_decode" "vector")
10868    (set_attr "amdfam10_decode" "vector")])   
10869
10870 (define_expand "x86_shift_adj_1"
10871   [(set (reg:CCZ FLAGS_REG)
10872         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10873                              (const_int 32))
10874                      (const_int 0)))
10875    (set (match_operand:SI 0 "register_operand" "")
10876         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10877                          (match_operand:SI 1 "register_operand" "")
10878                          (match_dup 0)))
10879    (set (match_dup 1)
10880         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10881                          (match_operand:SI 3 "register_operand" "r")
10882                          (match_dup 1)))]
10883   "TARGET_CMOVE"
10884   "")
10885
10886 (define_expand "x86_shift_adj_2"
10887   [(use (match_operand:SI 0 "register_operand" ""))
10888    (use (match_operand:SI 1 "register_operand" ""))
10889    (use (match_operand:QI 2 "register_operand" ""))]
10890   ""
10891 {
10892   rtx label = gen_label_rtx ();
10893   rtx tmp;
10894
10895   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10896
10897   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10898   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10899   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10900                               gen_rtx_LABEL_REF (VOIDmode, label),
10901                               pc_rtx);
10902   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10903   JUMP_LABEL (tmp) = label;
10904
10905   emit_move_insn (operands[0], operands[1]);
10906   ix86_expand_clear (operands[1]);
10907
10908   emit_label (label);
10909   LABEL_NUSES (label) = 1;
10910
10911   DONE;
10912 })
10913
10914 (define_expand "ashlsi3"
10915   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10916         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10917                    (match_operand:QI 2 "nonmemory_operand" "")))
10918    (clobber (reg:CC FLAGS_REG))]
10919   ""
10920   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10921
10922 (define_insn "*ashlsi3_1"
10923   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10924         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10925                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10926    (clobber (reg:CC FLAGS_REG))]
10927   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10928 {
10929   switch (get_attr_type (insn))
10930     {
10931     case TYPE_ALU:
10932       gcc_assert (operands[2] == const1_rtx);
10933       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10934       return "add{l}\t{%0, %0|%0, %0}";
10935
10936     case TYPE_LEA:
10937       return "#";
10938
10939     default:
10940       if (REG_P (operands[2]))
10941         return "sal{l}\t{%b2, %0|%0, %b2}";
10942       else if (operands[2] == const1_rtx
10943                && (TARGET_SHIFT1 || optimize_size))
10944         return "sal{l}\t%0";
10945       else
10946         return "sal{l}\t{%2, %0|%0, %2}";
10947     }
10948 }
10949   [(set (attr "type")
10950      (cond [(eq_attr "alternative" "1")
10951               (const_string "lea")
10952             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10953                           (const_int 0))
10954                       (match_operand 0 "register_operand" ""))
10955                  (match_operand 2 "const1_operand" ""))
10956               (const_string "alu")
10957            ]
10958            (const_string "ishift")))
10959    (set_attr "mode" "SI")])
10960
10961 ;; Convert lea to the lea pattern to avoid flags dependency.
10962 (define_split
10963   [(set (match_operand 0 "register_operand" "")
10964         (ashift (match_operand 1 "index_register_operand" "")
10965                 (match_operand:QI 2 "const_int_operand" "")))
10966    (clobber (reg:CC FLAGS_REG))]
10967   "reload_completed
10968    && true_regnum (operands[0]) != true_regnum (operands[1])
10969    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10970   [(const_int 0)]
10971 {
10972   rtx pat;
10973   enum machine_mode mode = GET_MODE (operands[0]);
10974
10975   if (GET_MODE_SIZE (mode) < 4)
10976     operands[0] = gen_lowpart (SImode, operands[0]);
10977   if (mode != Pmode)
10978     operands[1] = gen_lowpart (Pmode, operands[1]);
10979   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10980
10981   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10982   if (Pmode != SImode)
10983     pat = gen_rtx_SUBREG (SImode, pat, 0);
10984   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10985   DONE;
10986 })
10987
10988 ;; Rare case of shifting RSP is handled by generating move and shift
10989 (define_split
10990   [(set (match_operand 0 "register_operand" "")
10991         (ashift (match_operand 1 "register_operand" "")
10992                 (match_operand:QI 2 "const_int_operand" "")))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "reload_completed
10995    && true_regnum (operands[0]) != true_regnum (operands[1])"
10996   [(const_int 0)]
10997 {
10998   rtx pat, clob;
10999   emit_move_insn (operands[0], operands[1]);
11000   pat = gen_rtx_SET (VOIDmode, operands[0],
11001                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11002                                      operands[0], operands[2]));
11003   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11004   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11005   DONE;
11006 })
11007
11008 (define_insn "*ashlsi3_1_zext"
11009   [(set (match_operand:DI 0 "register_operand" "=r,r")
11010         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11011                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11014 {
11015   switch (get_attr_type (insn))
11016     {
11017     case TYPE_ALU:
11018       gcc_assert (operands[2] == const1_rtx);
11019       return "add{l}\t{%k0, %k0|%k0, %k0}";
11020
11021     case TYPE_LEA:
11022       return "#";
11023
11024     default:
11025       if (REG_P (operands[2]))
11026         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11027       else if (operands[2] == const1_rtx
11028                && (TARGET_SHIFT1 || optimize_size))
11029         return "sal{l}\t%k0";
11030       else
11031         return "sal{l}\t{%2, %k0|%k0, %2}";
11032     }
11033 }
11034   [(set (attr "type")
11035      (cond [(eq_attr "alternative" "1")
11036               (const_string "lea")
11037             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11038                      (const_int 0))
11039                  (match_operand 2 "const1_operand" ""))
11040               (const_string "alu")
11041            ]
11042            (const_string "ishift")))
11043    (set_attr "mode" "SI")])
11044
11045 ;; Convert lea to the lea pattern to avoid flags dependency.
11046 (define_split
11047   [(set (match_operand:DI 0 "register_operand" "")
11048         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11049                                 (match_operand:QI 2 "const_int_operand" ""))))
11050    (clobber (reg:CC FLAGS_REG))]
11051   "TARGET_64BIT && reload_completed
11052    && true_regnum (operands[0]) != true_regnum (operands[1])"
11053   [(set (match_dup 0) (zero_extend:DI
11054                         (subreg:SI (mult:SI (match_dup 1)
11055                                             (match_dup 2)) 0)))]
11056 {
11057   operands[1] = gen_lowpart (Pmode, operands[1]);
11058   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11059 })
11060
11061 ;; This pattern can't accept a variable shift count, since shifts by
11062 ;; zero don't affect the flags.  We assume that shifts by constant
11063 ;; zero are optimized away.
11064 (define_insn "*ashlsi3_cmp"
11065   [(set (reg FLAGS_REG)
11066         (compare
11067           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11069           (const_int 0)))
11070    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11071         (ashift:SI (match_dup 1) (match_dup 2)))]
11072   "ix86_match_ccmode (insn, CCGOCmode)
11073    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11074    && (optimize_size
11075        || !TARGET_PARTIAL_FLAG_REG_STALL
11076        || (operands[2] == const1_rtx
11077            && (TARGET_SHIFT1
11078                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11079 {
11080   switch (get_attr_type (insn))
11081     {
11082     case TYPE_ALU:
11083       gcc_assert (operands[2] == const1_rtx);
11084       return "add{l}\t{%0, %0|%0, %0}";
11085
11086     default:
11087       if (REG_P (operands[2]))
11088         return "sal{l}\t{%b2, %0|%0, %b2}";
11089       else if (operands[2] == const1_rtx
11090                && (TARGET_SHIFT1 || optimize_size))
11091         return "sal{l}\t%0";
11092       else
11093         return "sal{l}\t{%2, %0|%0, %2}";
11094     }
11095 }
11096   [(set (attr "type")
11097      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11098                           (const_int 0))
11099                       (match_operand 0 "register_operand" ""))
11100                  (match_operand 2 "const1_operand" ""))
11101               (const_string "alu")
11102            ]
11103            (const_string "ishift")))
11104    (set_attr "mode" "SI")])
11105
11106 (define_insn "*ashlsi3_cconly"
11107   [(set (reg FLAGS_REG)
11108         (compare
11109           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11110                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11111           (const_int 0)))
11112    (clobber (match_scratch:SI 0 "=r"))]
11113   "ix86_match_ccmode (insn, CCGOCmode)
11114    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11115    && (optimize_size
11116        || !TARGET_PARTIAL_FLAG_REG_STALL
11117        || (operands[2] == const1_rtx
11118            && (TARGET_SHIFT1
11119                || TARGET_DOUBLE_WITH_ADD)))"
11120 {
11121   switch (get_attr_type (insn))
11122     {
11123     case TYPE_ALU:
11124       gcc_assert (operands[2] == const1_rtx);
11125       return "add{l}\t{%0, %0|%0, %0}";
11126
11127     default:
11128       if (REG_P (operands[2]))
11129         return "sal{l}\t{%b2, %0|%0, %b2}";
11130       else if (operands[2] == const1_rtx
11131                && (TARGET_SHIFT1 || optimize_size))
11132         return "sal{l}\t%0";
11133       else
11134         return "sal{l}\t{%2, %0|%0, %2}";
11135     }
11136 }
11137   [(set (attr "type")
11138      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11139                           (const_int 0))
11140                       (match_operand 0 "register_operand" ""))
11141                  (match_operand 2 "const1_operand" ""))
11142               (const_string "alu")
11143            ]
11144            (const_string "ishift")))
11145    (set_attr "mode" "SI")])
11146
11147 (define_insn "*ashlsi3_cmp_zext"
11148   [(set (reg FLAGS_REG)
11149         (compare
11150           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11151                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11152           (const_int 0)))
11153    (set (match_operand:DI 0 "register_operand" "=r")
11154         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11157    && (optimize_size
11158        || !TARGET_PARTIAL_FLAG_REG_STALL
11159        || (operands[2] == const1_rtx
11160            && (TARGET_SHIFT1
11161                || TARGET_DOUBLE_WITH_ADD)))"
11162 {
11163   switch (get_attr_type (insn))
11164     {
11165     case TYPE_ALU:
11166       gcc_assert (operands[2] == const1_rtx);
11167       return "add{l}\t{%k0, %k0|%k0, %k0}";
11168
11169     default:
11170       if (REG_P (operands[2]))
11171         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11172       else if (operands[2] == const1_rtx
11173                && (TARGET_SHIFT1 || optimize_size))
11174         return "sal{l}\t%k0";
11175       else
11176         return "sal{l}\t{%2, %k0|%k0, %2}";
11177     }
11178 }
11179   [(set (attr "type")
11180      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11181                      (const_int 0))
11182                  (match_operand 2 "const1_operand" ""))
11183               (const_string "alu")
11184            ]
11185            (const_string "ishift")))
11186    (set_attr "mode" "SI")])
11187
11188 (define_expand "ashlhi3"
11189   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11190         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11191                    (match_operand:QI 2 "nonmemory_operand" "")))
11192    (clobber (reg:CC FLAGS_REG))]
11193   "TARGET_HIMODE_MATH"
11194   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11195
11196 (define_insn "*ashlhi3_1_lea"
11197   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11198         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11199                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11200    (clobber (reg:CC FLAGS_REG))]
11201   "!TARGET_PARTIAL_REG_STALL
11202    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11203 {
11204   switch (get_attr_type (insn))
11205     {
11206     case TYPE_LEA:
11207       return "#";
11208     case TYPE_ALU:
11209       gcc_assert (operands[2] == const1_rtx);
11210       return "add{w}\t{%0, %0|%0, %0}";
11211
11212     default:
11213       if (REG_P (operands[2]))
11214         return "sal{w}\t{%b2, %0|%0, %b2}";
11215       else if (operands[2] == const1_rtx
11216                && (TARGET_SHIFT1 || optimize_size))
11217         return "sal{w}\t%0";
11218       else
11219         return "sal{w}\t{%2, %0|%0, %2}";
11220     }
11221 }
11222   [(set (attr "type")
11223      (cond [(eq_attr "alternative" "1")
11224               (const_string "lea")
11225             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11226                           (const_int 0))
11227                       (match_operand 0 "register_operand" ""))
11228                  (match_operand 2 "const1_operand" ""))
11229               (const_string "alu")
11230            ]
11231            (const_string "ishift")))
11232    (set_attr "mode" "HI,SI")])
11233
11234 (define_insn "*ashlhi3_1"
11235   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11237                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "TARGET_PARTIAL_REG_STALL
11240    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11241 {
11242   switch (get_attr_type (insn))
11243     {
11244     case TYPE_ALU:
11245       gcc_assert (operands[2] == const1_rtx);
11246       return "add{w}\t{%0, %0|%0, %0}";
11247
11248     default:
11249       if (REG_P (operands[2]))
11250         return "sal{w}\t{%b2, %0|%0, %b2}";
11251       else if (operands[2] == const1_rtx
11252                && (TARGET_SHIFT1 || optimize_size))
11253         return "sal{w}\t%0";
11254       else
11255         return "sal{w}\t{%2, %0|%0, %2}";
11256     }
11257 }
11258   [(set (attr "type")
11259      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11260                           (const_int 0))
11261                       (match_operand 0 "register_operand" ""))
11262                  (match_operand 2 "const1_operand" ""))
11263               (const_string "alu")
11264            ]
11265            (const_string "ishift")))
11266    (set_attr "mode" "HI")])
11267
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags.  We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashlhi3_cmp"
11272   [(set (reg FLAGS_REG)
11273         (compare
11274           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11275                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276           (const_int 0)))
11277    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11278         (ashift:HI (match_dup 1) (match_dup 2)))]
11279   "ix86_match_ccmode (insn, CCGOCmode)
11280    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11281    && (optimize_size
11282        || !TARGET_PARTIAL_FLAG_REG_STALL
11283        || (operands[2] == const1_rtx
11284            && (TARGET_SHIFT1
11285                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11286 {
11287   switch (get_attr_type (insn))
11288     {
11289     case TYPE_ALU:
11290       gcc_assert (operands[2] == const1_rtx);
11291       return "add{w}\t{%0, %0|%0, %0}";
11292
11293     default:
11294       if (REG_P (operands[2]))
11295         return "sal{w}\t{%b2, %0|%0, %b2}";
11296       else if (operands[2] == const1_rtx
11297                && (TARGET_SHIFT1 || optimize_size))
11298         return "sal{w}\t%0";
11299       else
11300         return "sal{w}\t{%2, %0|%0, %2}";
11301     }
11302 }
11303   [(set (attr "type")
11304      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11305                           (const_int 0))
11306                       (match_operand 0 "register_operand" ""))
11307                  (match_operand 2 "const1_operand" ""))
11308               (const_string "alu")
11309            ]
11310            (const_string "ishift")))
11311    (set_attr "mode" "HI")])
11312
11313 (define_insn "*ashlhi3_cconly"
11314   [(set (reg FLAGS_REG)
11315         (compare
11316           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11317                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11318           (const_int 0)))
11319    (clobber (match_scratch:HI 0 "=r"))]
11320   "ix86_match_ccmode (insn, CCGOCmode)
11321    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11322    && (optimize_size
11323        || !TARGET_PARTIAL_FLAG_REG_STALL
11324        || (operands[2] == const1_rtx
11325            && (TARGET_SHIFT1
11326                || TARGET_DOUBLE_WITH_ADD)))"
11327 {
11328   switch (get_attr_type (insn))
11329     {
11330     case TYPE_ALU:
11331       gcc_assert (operands[2] == const1_rtx);
11332       return "add{w}\t{%0, %0|%0, %0}";
11333
11334     default:
11335       if (REG_P (operands[2]))
11336         return "sal{w}\t{%b2, %0|%0, %b2}";
11337       else if (operands[2] == const1_rtx
11338                && (TARGET_SHIFT1 || optimize_size))
11339         return "sal{w}\t%0";
11340       else
11341         return "sal{w}\t{%2, %0|%0, %2}";
11342     }
11343 }
11344   [(set (attr "type")
11345      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11346                           (const_int 0))
11347                       (match_operand 0 "register_operand" ""))
11348                  (match_operand 2 "const1_operand" ""))
11349               (const_string "alu")
11350            ]
11351            (const_string "ishift")))
11352    (set_attr "mode" "HI")])
11353
11354 (define_expand "ashlqi3"
11355   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11356         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11357                    (match_operand:QI 2 "nonmemory_operand" "")))
11358    (clobber (reg:CC FLAGS_REG))]
11359   "TARGET_QIMODE_MATH"
11360   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11361
11362 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11363
11364 (define_insn "*ashlqi3_1_lea"
11365   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11366         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11367                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11368    (clobber (reg:CC FLAGS_REG))]
11369   "!TARGET_PARTIAL_REG_STALL
11370    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11371 {
11372   switch (get_attr_type (insn))
11373     {
11374     case TYPE_LEA:
11375       return "#";
11376     case TYPE_ALU:
11377       gcc_assert (operands[2] == const1_rtx);
11378       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11379         return "add{l}\t{%k0, %k0|%k0, %k0}";
11380       else
11381         return "add{b}\t{%0, %0|%0, %0}";
11382
11383     default:
11384       if (REG_P (operands[2]))
11385         {
11386           if (get_attr_mode (insn) == MODE_SI)
11387             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11388           else
11389             return "sal{b}\t{%b2, %0|%0, %b2}";
11390         }
11391       else if (operands[2] == const1_rtx
11392                && (TARGET_SHIFT1 || optimize_size))
11393         {
11394           if (get_attr_mode (insn) == MODE_SI)
11395             return "sal{l}\t%0";
11396           else
11397             return "sal{b}\t%0";
11398         }
11399       else
11400         {
11401           if (get_attr_mode (insn) == MODE_SI)
11402             return "sal{l}\t{%2, %k0|%k0, %2}";
11403           else
11404             return "sal{b}\t{%2, %0|%0, %2}";
11405         }
11406     }
11407 }
11408   [(set (attr "type")
11409      (cond [(eq_attr "alternative" "2")
11410               (const_string "lea")
11411             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11412                           (const_int 0))
11413                       (match_operand 0 "register_operand" ""))
11414                  (match_operand 2 "const1_operand" ""))
11415               (const_string "alu")
11416            ]
11417            (const_string "ishift")))
11418    (set_attr "mode" "QI,SI,SI")])
11419
11420 (define_insn "*ashlqi3_1"
11421   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11422         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11423                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "TARGET_PARTIAL_REG_STALL
11426    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11427 {
11428   switch (get_attr_type (insn))
11429     {
11430     case TYPE_ALU:
11431       gcc_assert (operands[2] == const1_rtx);
11432       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11433         return "add{l}\t{%k0, %k0|%k0, %k0}";
11434       else
11435         return "add{b}\t{%0, %0|%0, %0}";
11436
11437     default:
11438       if (REG_P (operands[2]))
11439         {
11440           if (get_attr_mode (insn) == MODE_SI)
11441             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11442           else
11443             return "sal{b}\t{%b2, %0|%0, %b2}";
11444         }
11445       else if (operands[2] == const1_rtx
11446                && (TARGET_SHIFT1 || optimize_size))
11447         {
11448           if (get_attr_mode (insn) == MODE_SI)
11449             return "sal{l}\t%0";
11450           else
11451             return "sal{b}\t%0";
11452         }
11453       else
11454         {
11455           if (get_attr_mode (insn) == MODE_SI)
11456             return "sal{l}\t{%2, %k0|%k0, %2}";
11457           else
11458             return "sal{b}\t{%2, %0|%0, %2}";
11459         }
11460     }
11461 }
11462   [(set (attr "type")
11463      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11464                           (const_int 0))
11465                       (match_operand 0 "register_operand" ""))
11466                  (match_operand 2 "const1_operand" ""))
11467               (const_string "alu")
11468            ]
11469            (const_string "ishift")))
11470    (set_attr "mode" "QI,SI")])
11471
11472 ;; This pattern can't accept a variable shift count, since shifts by
11473 ;; zero don't affect the flags.  We assume that shifts by constant
11474 ;; zero are optimized away.
11475 (define_insn "*ashlqi3_cmp"
11476   [(set (reg FLAGS_REG)
11477         (compare
11478           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11479                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11480           (const_int 0)))
11481    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11482         (ashift:QI (match_dup 1) (match_dup 2)))]
11483   "ix86_match_ccmode (insn, CCGOCmode)
11484    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11485    && (optimize_size
11486        || !TARGET_PARTIAL_FLAG_REG_STALL
11487        || (operands[2] == const1_rtx
11488            && (TARGET_SHIFT1
11489                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11490 {
11491   switch (get_attr_type (insn))
11492     {
11493     case TYPE_ALU:
11494       gcc_assert (operands[2] == const1_rtx);
11495       return "add{b}\t{%0, %0|%0, %0}";
11496
11497     default:
11498       if (REG_P (operands[2]))
11499         return "sal{b}\t{%b2, %0|%0, %b2}";
11500       else if (operands[2] == const1_rtx
11501                && (TARGET_SHIFT1 || optimize_size))
11502         return "sal{b}\t%0";
11503       else
11504         return "sal{b}\t{%2, %0|%0, %2}";
11505     }
11506 }
11507   [(set (attr "type")
11508      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11509                           (const_int 0))
11510                       (match_operand 0 "register_operand" ""))
11511                  (match_operand 2 "const1_operand" ""))
11512               (const_string "alu")
11513            ]
11514            (const_string "ishift")))
11515    (set_attr "mode" "QI")])
11516
11517 (define_insn "*ashlqi3_cconly"
11518   [(set (reg FLAGS_REG)
11519         (compare
11520           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11521                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11522           (const_int 0)))
11523    (clobber (match_scratch:QI 0 "=q"))]
11524   "ix86_match_ccmode (insn, CCGOCmode)
11525    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11526    && (optimize_size
11527        || !TARGET_PARTIAL_FLAG_REG_STALL
11528        || (operands[2] == const1_rtx
11529            && (TARGET_SHIFT1
11530                || TARGET_DOUBLE_WITH_ADD)))"
11531 {
11532   switch (get_attr_type (insn))
11533     {
11534     case TYPE_ALU:
11535       gcc_assert (operands[2] == const1_rtx);
11536       return "add{b}\t{%0, %0|%0, %0}";
11537
11538     default:
11539       if (REG_P (operands[2]))
11540         return "sal{b}\t{%b2, %0|%0, %b2}";
11541       else if (operands[2] == const1_rtx
11542                && (TARGET_SHIFT1 || optimize_size))
11543         return "sal{b}\t%0";
11544       else
11545         return "sal{b}\t{%2, %0|%0, %2}";
11546     }
11547 }
11548   [(set (attr "type")
11549      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11550                           (const_int 0))
11551                       (match_operand 0 "register_operand" ""))
11552                  (match_operand 2 "const1_operand" ""))
11553               (const_string "alu")
11554            ]
11555            (const_string "ishift")))
11556    (set_attr "mode" "QI")])
11557
11558 ;; See comment above `ashldi3' about how this works.
11559
11560 (define_expand "ashrti3"
11561   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11562                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11563                                 (match_operand:QI 2 "nonmemory_operand" "")))
11564               (clobber (reg:CC FLAGS_REG))])]
11565   "TARGET_64BIT"
11566 {
11567   if (! immediate_operand (operands[2], QImode))
11568     {
11569       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11570       DONE;
11571     }
11572   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11573   DONE;
11574 })
11575
11576 (define_insn "ashrti3_1"
11577   [(set (match_operand:TI 0 "register_operand" "=r")
11578         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11579                      (match_operand:QI 2 "register_operand" "c")))
11580    (clobber (match_scratch:DI 3 "=&r"))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "TARGET_64BIT"
11583   "#"
11584   [(set_attr "type" "multi")])
11585
11586 (define_insn "*ashrti3_2"
11587   [(set (match_operand:TI 0 "register_operand" "=r")
11588         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11589                      (match_operand:QI 2 "immediate_operand" "O")))
11590    (clobber (reg:CC FLAGS_REG))]
11591   "TARGET_64BIT"
11592   "#"
11593   [(set_attr "type" "multi")])
11594
11595 (define_split
11596   [(set (match_operand:TI 0 "register_operand" "")
11597         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11598                      (match_operand:QI 2 "register_operand" "")))
11599    (clobber (match_scratch:DI 3 ""))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_64BIT && reload_completed"
11602   [(const_int 0)]
11603   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11604
11605 (define_split
11606   [(set (match_operand:TI 0 "register_operand" "")
11607         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11608                      (match_operand:QI 2 "immediate_operand" "")))
11609    (clobber (reg:CC FLAGS_REG))]
11610   "TARGET_64BIT && reload_completed"
11611   [(const_int 0)]
11612   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11613
11614 (define_insn "x86_64_shrd"
11615   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11616         (ior:DI (ashiftrt:DI (match_dup 0)
11617                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11618                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11619                   (minus:QI (const_int 64) (match_dup 2)))))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_64BIT"
11622   "@
11623    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11624    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11625   [(set_attr "type" "ishift")
11626    (set_attr "prefix_0f" "1")
11627    (set_attr "mode" "DI")
11628    (set_attr "athlon_decode" "vector")
11629    (set_attr "amdfam10_decode" "vector")])   
11630
11631 (define_expand "ashrdi3"
11632   [(set (match_operand:DI 0 "shiftdi_operand" "")
11633         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11634                      (match_operand:QI 2 "nonmemory_operand" "")))]
11635   ""
11636   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11637
11638 (define_insn "*ashrdi3_63_rex64"
11639   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11640         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11641                      (match_operand:DI 2 "const_int_operand" "i,i")))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "TARGET_64BIT && INTVAL (operands[2]) == 63
11644    && (TARGET_USE_CLTD || optimize_size)
11645    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11646   "@
11647    {cqto|cqo}
11648    sar{q}\t{%2, %0|%0, %2}"
11649   [(set_attr "type" "imovx,ishift")
11650    (set_attr "prefix_0f" "0,*")
11651    (set_attr "length_immediate" "0,*")
11652    (set_attr "modrm" "0,1")
11653    (set_attr "mode" "DI")])
11654
11655 (define_insn "*ashrdi3_1_one_bit_rex64"
11656   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11657         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11658                      (match_operand:QI 2 "const1_operand" "")))
11659    (clobber (reg:CC FLAGS_REG))]
11660   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11661    && (TARGET_SHIFT1 || optimize_size)"
11662   "sar{q}\t%0"
11663   [(set_attr "type" "ishift")
11664    (set (attr "length")
11665      (if_then_else (match_operand:DI 0 "register_operand" "")
11666         (const_string "2")
11667         (const_string "*")))])
11668
11669 (define_insn "*ashrdi3_1_rex64"
11670   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11671         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11672                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11673    (clobber (reg:CC FLAGS_REG))]
11674   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11675   "@
11676    sar{q}\t{%2, %0|%0, %2}
11677    sar{q}\t{%b2, %0|%0, %b2}"
11678   [(set_attr "type" "ishift")
11679    (set_attr "mode" "DI")])
11680
11681 ;; This pattern can't accept a variable shift count, since shifts by
11682 ;; zero don't affect the flags.  We assume that shifts by constant
11683 ;; zero are optimized away.
11684 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11685   [(set (reg FLAGS_REG)
11686         (compare
11687           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688                        (match_operand:QI 2 "const1_operand" ""))
11689           (const_int 0)))
11690    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11691         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11692   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11693    && (TARGET_SHIFT1 || optimize_size)
11694    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11695   "sar{q}\t%0"
11696   [(set_attr "type" "ishift")
11697    (set (attr "length")
11698      (if_then_else (match_operand:DI 0 "register_operand" "")
11699         (const_string "2")
11700         (const_string "*")))])
11701
11702 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11703   [(set (reg FLAGS_REG)
11704         (compare
11705           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706                        (match_operand:QI 2 "const1_operand" ""))
11707           (const_int 0)))
11708    (clobber (match_scratch:DI 0 "=r"))]
11709   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11710    && (TARGET_SHIFT1 || optimize_size)
11711    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11712   "sar{q}\t%0"
11713   [(set_attr "type" "ishift")
11714    (set_attr "length" "2")])
11715
11716 ;; This pattern can't accept a variable shift count, since shifts by
11717 ;; zero don't affect the flags.  We assume that shifts by constant
11718 ;; zero are optimized away.
11719 (define_insn "*ashrdi3_cmp_rex64"
11720   [(set (reg FLAGS_REG)
11721         (compare
11722           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11723                        (match_operand:QI 2 "const_int_operand" "n"))
11724           (const_int 0)))
11725    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11726         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11727   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11728    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11729    && (optimize_size
11730        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11731   "sar{q}\t{%2, %0|%0, %2}"
11732   [(set_attr "type" "ishift")
11733    (set_attr "mode" "DI")])
11734
11735 (define_insn "*ashrdi3_cconly_rex64"
11736   [(set (reg FLAGS_REG)
11737         (compare
11738           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11739                        (match_operand:QI 2 "const_int_operand" "n"))
11740           (const_int 0)))
11741    (clobber (match_scratch:DI 0 "=r"))]
11742   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11744    && (optimize_size
11745        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746   "sar{q}\t{%2, %0|%0, %2}"
11747   [(set_attr "type" "ishift")
11748    (set_attr "mode" "DI")])
11749
11750 (define_insn "*ashrdi3_1"
11751   [(set (match_operand:DI 0 "register_operand" "=r")
11752         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11753                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   "!TARGET_64BIT"
11756   "#"
11757   [(set_attr "type" "multi")])
11758
11759 ;; By default we don't ask for a scratch register, because when DImode
11760 ;; values are manipulated, registers are already at a premium.  But if
11761 ;; we have one handy, we won't turn it away.
11762 (define_peephole2
11763   [(match_scratch:SI 3 "r")
11764    (parallel [(set (match_operand:DI 0 "register_operand" "")
11765                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11766                                 (match_operand:QI 2 "nonmemory_operand" "")))
11767               (clobber (reg:CC FLAGS_REG))])
11768    (match_dup 3)]
11769   "!TARGET_64BIT && TARGET_CMOVE"
11770   [(const_int 0)]
11771   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11772
11773 (define_split
11774   [(set (match_operand:DI 0 "register_operand" "")
11775         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11776                      (match_operand:QI 2 "nonmemory_operand" "")))
11777    (clobber (reg:CC FLAGS_REG))]
11778   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11779                      ? flow2_completed : reload_completed)"
11780   [(const_int 0)]
11781   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11782
11783 (define_insn "x86_shrd_1"
11784   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11785         (ior:SI (ashiftrt:SI (match_dup 0)
11786                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11787                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11788                   (minus:QI (const_int 32) (match_dup 2)))))
11789    (clobber (reg:CC FLAGS_REG))]
11790   ""
11791   "@
11792    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11793    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11794   [(set_attr "type" "ishift")
11795    (set_attr "prefix_0f" "1")
11796    (set_attr "pent_pair" "np")
11797    (set_attr "mode" "SI")])
11798
11799 (define_expand "x86_shift_adj_3"
11800   [(use (match_operand:SI 0 "register_operand" ""))
11801    (use (match_operand:SI 1 "register_operand" ""))
11802    (use (match_operand:QI 2 "register_operand" ""))]
11803   ""
11804 {
11805   rtx label = gen_label_rtx ();
11806   rtx tmp;
11807
11808   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11809
11810   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11811   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11812   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11813                               gen_rtx_LABEL_REF (VOIDmode, label),
11814                               pc_rtx);
11815   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11816   JUMP_LABEL (tmp) = label;
11817
11818   emit_move_insn (operands[0], operands[1]);
11819   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11820
11821   emit_label (label);
11822   LABEL_NUSES (label) = 1;
11823
11824   DONE;
11825 })
11826
11827 (define_insn "ashrsi3_31"
11828   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11829         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11830                      (match_operand:SI 2 "const_int_operand" "i,i")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11833    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11834   "@
11835    {cltd|cdq}
11836    sar{l}\t{%2, %0|%0, %2}"
11837   [(set_attr "type" "imovx,ishift")
11838    (set_attr "prefix_0f" "0,*")
11839    (set_attr "length_immediate" "0,*")
11840    (set_attr "modrm" "0,1")
11841    (set_attr "mode" "SI")])
11842
11843 (define_insn "*ashrsi3_31_zext"
11844   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11845         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11846                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11849    && INTVAL (operands[2]) == 31
11850    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11851   "@
11852    {cltd|cdq}
11853    sar{l}\t{%2, %k0|%k0, %2}"
11854   [(set_attr "type" "imovx,ishift")
11855    (set_attr "prefix_0f" "0,*")
11856    (set_attr "length_immediate" "0,*")
11857    (set_attr "modrm" "0,1")
11858    (set_attr "mode" "SI")])
11859
11860 (define_expand "ashrsi3"
11861   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11862         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11863                      (match_operand:QI 2 "nonmemory_operand" "")))
11864    (clobber (reg:CC FLAGS_REG))]
11865   ""
11866   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11867
11868 (define_insn "*ashrsi3_1_one_bit"
11869   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11871                      (match_operand:QI 2 "const1_operand" "")))
11872    (clobber (reg:CC FLAGS_REG))]
11873   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11874    && (TARGET_SHIFT1 || optimize_size)"
11875   "sar{l}\t%0"
11876   [(set_attr "type" "ishift")
11877    (set (attr "length")
11878      (if_then_else (match_operand:SI 0 "register_operand" "")
11879         (const_string "2")
11880         (const_string "*")))])
11881
11882 (define_insn "*ashrsi3_1_one_bit_zext"
11883   [(set (match_operand:DI 0 "register_operand" "=r")
11884         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11885                                      (match_operand:QI 2 "const1_operand" ""))))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11888    && (TARGET_SHIFT1 || optimize_size)"
11889   "sar{l}\t%k0"
11890   [(set_attr "type" "ishift")
11891    (set_attr "length" "2")])
11892
11893 (define_insn "*ashrsi3_1"
11894   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11895         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11896                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11897    (clobber (reg:CC FLAGS_REG))]
11898   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11899   "@
11900    sar{l}\t{%2, %0|%0, %2}
11901    sar{l}\t{%b2, %0|%0, %b2}"
11902   [(set_attr "type" "ishift")
11903    (set_attr "mode" "SI")])
11904
11905 (define_insn "*ashrsi3_1_zext"
11906   [(set (match_operand:DI 0 "register_operand" "=r,r")
11907         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11908                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11911   "@
11912    sar{l}\t{%2, %k0|%k0, %2}
11913    sar{l}\t{%b2, %k0|%k0, %b2}"
11914   [(set_attr "type" "ishift")
11915    (set_attr "mode" "SI")])
11916
11917 ;; This pattern can't accept a variable shift count, since shifts by
11918 ;; zero don't affect the flags.  We assume that shifts by constant
11919 ;; zero are optimized away.
11920 (define_insn "*ashrsi3_one_bit_cmp"
11921   [(set (reg FLAGS_REG)
11922         (compare
11923           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11924                        (match_operand:QI 2 "const1_operand" ""))
11925           (const_int 0)))
11926    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11927         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11928   "ix86_match_ccmode (insn, CCGOCmode)
11929    && (TARGET_SHIFT1 || optimize_size)
11930    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11931   "sar{l}\t%0"
11932   [(set_attr "type" "ishift")
11933    (set (attr "length")
11934      (if_then_else (match_operand:SI 0 "register_operand" "")
11935         (const_string "2")
11936         (const_string "*")))])
11937
11938 (define_insn "*ashrsi3_one_bit_cconly"
11939   [(set (reg FLAGS_REG)
11940         (compare
11941           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11942                        (match_operand:QI 2 "const1_operand" ""))
11943           (const_int 0)))
11944    (clobber (match_scratch:SI 0 "=r"))]
11945   "ix86_match_ccmode (insn, CCGOCmode)
11946    && (TARGET_SHIFT1 || optimize_size)
11947    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11948   "sar{l}\t%0"
11949   [(set_attr "type" "ishift")
11950    (set_attr "length" "2")])
11951
11952 (define_insn "*ashrsi3_one_bit_cmp_zext"
11953   [(set (reg FLAGS_REG)
11954         (compare
11955           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11956                        (match_operand:QI 2 "const1_operand" ""))
11957           (const_int 0)))
11958    (set (match_operand:DI 0 "register_operand" "=r")
11959         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11960   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11961    && (TARGET_SHIFT1 || optimize_size)
11962    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11963   "sar{l}\t%k0"
11964   [(set_attr "type" "ishift")
11965    (set_attr "length" "2")])
11966
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags.  We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*ashrsi3_cmp"
11971   [(set (reg FLAGS_REG)
11972         (compare
11973           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11975           (const_int 0)))
11976    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11978   "ix86_match_ccmode (insn, CCGOCmode)
11979    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11980    && (optimize_size
11981        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11982   "sar{l}\t{%2, %0|%0, %2}"
11983   [(set_attr "type" "ishift")
11984    (set_attr "mode" "SI")])
11985
11986 (define_insn "*ashrsi3_cconly"
11987   [(set (reg FLAGS_REG)
11988         (compare
11989           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11991           (const_int 0)))
11992    (clobber (match_scratch:SI 0 "=r"))]
11993   "ix86_match_ccmode (insn, CCGOCmode)
11994    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11995    && (optimize_size
11996        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11997   "sar{l}\t{%2, %0|%0, %2}"
11998   [(set_attr "type" "ishift")
11999    (set_attr "mode" "SI")])
12000
12001 (define_insn "*ashrsi3_cmp_zext"
12002   [(set (reg FLAGS_REG)
12003         (compare
12004           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12006           (const_int 0)))
12007    (set (match_operand:DI 0 "register_operand" "=r")
12008         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12009   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12011    && (optimize_size
12012        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12013   "sar{l}\t{%2, %k0|%k0, %2}"
12014   [(set_attr "type" "ishift")
12015    (set_attr "mode" "SI")])
12016
12017 (define_expand "ashrhi3"
12018   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12019         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12020                      (match_operand:QI 2 "nonmemory_operand" "")))
12021    (clobber (reg:CC FLAGS_REG))]
12022   "TARGET_HIMODE_MATH"
12023   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12024
12025 (define_insn "*ashrhi3_1_one_bit"
12026   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12027         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12028                      (match_operand:QI 2 "const1_operand" "")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12031    && (TARGET_SHIFT1 || optimize_size)"
12032   "sar{w}\t%0"
12033   [(set_attr "type" "ishift")
12034    (set (attr "length")
12035      (if_then_else (match_operand 0 "register_operand" "")
12036         (const_string "2")
12037         (const_string "*")))])
12038
12039 (define_insn "*ashrhi3_1"
12040   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12041         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12042                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12045   "@
12046    sar{w}\t{%2, %0|%0, %2}
12047    sar{w}\t{%b2, %0|%0, %b2}"
12048   [(set_attr "type" "ishift")
12049    (set_attr "mode" "HI")])
12050
12051 ;; This pattern can't accept a variable shift count, since shifts by
12052 ;; zero don't affect the flags.  We assume that shifts by constant
12053 ;; zero are optimized away.
12054 (define_insn "*ashrhi3_one_bit_cmp"
12055   [(set (reg FLAGS_REG)
12056         (compare
12057           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058                        (match_operand:QI 2 "const1_operand" ""))
12059           (const_int 0)))
12060    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12061         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12062   "ix86_match_ccmode (insn, CCGOCmode)
12063    && (TARGET_SHIFT1 || optimize_size)
12064    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12065   "sar{w}\t%0"
12066   [(set_attr "type" "ishift")
12067    (set (attr "length")
12068      (if_then_else (match_operand 0 "register_operand" "")
12069         (const_string "2")
12070         (const_string "*")))])
12071
12072 (define_insn "*ashrhi3_one_bit_cconly"
12073   [(set (reg FLAGS_REG)
12074         (compare
12075           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076                        (match_operand:QI 2 "const1_operand" ""))
12077           (const_int 0)))
12078    (clobber (match_scratch:HI 0 "=r"))]
12079   "ix86_match_ccmode (insn, CCGOCmode)
12080    && (TARGET_SHIFT1 || optimize_size)
12081    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12082   "sar{w}\t%0"
12083   [(set_attr "type" "ishift")
12084    (set_attr "length" "2")])
12085
12086 ;; This pattern can't accept a variable shift count, since shifts by
12087 ;; zero don't affect the flags.  We assume that shifts by constant
12088 ;; zero are optimized away.
12089 (define_insn "*ashrhi3_cmp"
12090   [(set (reg FLAGS_REG)
12091         (compare
12092           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12093                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12094           (const_int 0)))
12095    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12096         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12097   "ix86_match_ccmode (insn, CCGOCmode)
12098    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12099    && (optimize_size
12100        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101   "sar{w}\t{%2, %0|%0, %2}"
12102   [(set_attr "type" "ishift")
12103    (set_attr "mode" "HI")])
12104
12105 (define_insn "*ashrhi3_cconly"
12106   [(set (reg FLAGS_REG)
12107         (compare
12108           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12109                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12110           (const_int 0)))
12111    (clobber (match_scratch:HI 0 "=r"))]
12112   "ix86_match_ccmode (insn, CCGOCmode)
12113    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12114    && (optimize_size
12115        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116   "sar{w}\t{%2, %0|%0, %2}"
12117   [(set_attr "type" "ishift")
12118    (set_attr "mode" "HI")])
12119
12120 (define_expand "ashrqi3"
12121   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12122         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12123                      (match_operand:QI 2 "nonmemory_operand" "")))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "TARGET_QIMODE_MATH"
12126   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12127
12128 (define_insn "*ashrqi3_1_one_bit"
12129   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12130         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12131                      (match_operand:QI 2 "const1_operand" "")))
12132    (clobber (reg:CC FLAGS_REG))]
12133   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12134    && (TARGET_SHIFT1 || optimize_size)"
12135   "sar{b}\t%0"
12136   [(set_attr "type" "ishift")
12137    (set (attr "length")
12138      (if_then_else (match_operand 0 "register_operand" "")
12139         (const_string "2")
12140         (const_string "*")))])
12141
12142 (define_insn "*ashrqi3_1_one_bit_slp"
12143   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12144         (ashiftrt:QI (match_dup 0)
12145                      (match_operand:QI 1 "const1_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12148    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12149    && (TARGET_SHIFT1 || optimize_size)"
12150   "sar{b}\t%0"
12151   [(set_attr "type" "ishift1")
12152    (set (attr "length")
12153      (if_then_else (match_operand 0 "register_operand" "")
12154         (const_string "2")
12155         (const_string "*")))])
12156
12157 (define_insn "*ashrqi3_1"
12158   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12159         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12160                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12161    (clobber (reg:CC FLAGS_REG))]
12162   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12163   "@
12164    sar{b}\t{%2, %0|%0, %2}
12165    sar{b}\t{%b2, %0|%0, %b2}"
12166   [(set_attr "type" "ishift")
12167    (set_attr "mode" "QI")])
12168
12169 (define_insn "*ashrqi3_1_slp"
12170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171         (ashiftrt:QI (match_dup 0)
12172                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12176   "@
12177    sar{b}\t{%1, %0|%0, %1}
12178    sar{b}\t{%b1, %0|%0, %b1}"
12179   [(set_attr "type" "ishift1")
12180    (set_attr "mode" "QI")])
12181
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags.  We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*ashrqi3_one_bit_cmp"
12186   [(set (reg FLAGS_REG)
12187         (compare
12188           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12189                        (match_operand:QI 2 "const1_operand" "I"))
12190           (const_int 0)))
12191    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12193   "ix86_match_ccmode (insn, CCGOCmode)
12194    && (TARGET_SHIFT1 || optimize_size)
12195    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12196   "sar{b}\t%0"
12197   [(set_attr "type" "ishift")
12198    (set (attr "length")
12199      (if_then_else (match_operand 0 "register_operand" "")
12200         (const_string "2")
12201         (const_string "*")))])
12202
12203 (define_insn "*ashrqi3_one_bit_cconly"
12204   [(set (reg FLAGS_REG)
12205         (compare
12206           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207                        (match_operand:QI 2 "const1_operand" "I"))
12208           (const_int 0)))
12209    (clobber (match_scratch:QI 0 "=q"))]
12210   "ix86_match_ccmode (insn, CCGOCmode)
12211    && (TARGET_SHIFT1 || optimize_size)
12212    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12213   "sar{b}\t%0"
12214   [(set_attr "type" "ishift")
12215    (set_attr "length" "2")])
12216
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags.  We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*ashrqi3_cmp"
12221   [(set (reg FLAGS_REG)
12222         (compare
12223           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12224                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12225           (const_int 0)))
12226    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12227         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12228   "ix86_match_ccmode (insn, CCGOCmode)
12229    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12230    && (optimize_size
12231        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12232   "sar{b}\t{%2, %0|%0, %2}"
12233   [(set_attr "type" "ishift")
12234    (set_attr "mode" "QI")])
12235
12236 (define_insn "*ashrqi3_cconly"
12237   [(set (reg FLAGS_REG)
12238         (compare
12239           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12240                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12241           (const_int 0)))
12242    (clobber (match_scratch:QI 0 "=q"))]
12243   "ix86_match_ccmode (insn, CCGOCmode)
12244    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12245    && (optimize_size
12246        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12247   "sar{b}\t{%2, %0|%0, %2}"
12248   [(set_attr "type" "ishift")
12249    (set_attr "mode" "QI")])
12250
12251 \f
12252 ;; Logical shift instructions
12253
12254 ;; See comment above `ashldi3' about how this works.
12255
12256 (define_expand "lshrti3"
12257   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12258                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12259                                 (match_operand:QI 2 "nonmemory_operand" "")))
12260               (clobber (reg:CC FLAGS_REG))])]
12261   "TARGET_64BIT"
12262 {
12263   if (! immediate_operand (operands[2], QImode))
12264     {
12265       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12266       DONE;
12267     }
12268   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12269   DONE;
12270 })
12271
12272 (define_insn "lshrti3_1"
12273   [(set (match_operand:TI 0 "register_operand" "=r")
12274         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12275                      (match_operand:QI 2 "register_operand" "c")))
12276    (clobber (match_scratch:DI 3 "=&r"))
12277    (clobber (reg:CC FLAGS_REG))]
12278   "TARGET_64BIT"
12279   "#"
12280   [(set_attr "type" "multi")])
12281
12282 (define_insn "*lshrti3_2"
12283   [(set (match_operand:TI 0 "register_operand" "=r")
12284         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12285                      (match_operand:QI 2 "immediate_operand" "O")))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "TARGET_64BIT"
12288   "#"
12289   [(set_attr "type" "multi")])
12290
12291 (define_split
12292   [(set (match_operand:TI 0 "register_operand" "")
12293         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12294                      (match_operand:QI 2 "register_operand" "")))
12295    (clobber (match_scratch:DI 3 ""))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "TARGET_64BIT && reload_completed"
12298   [(const_int 0)]
12299   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12300
12301 (define_split
12302   [(set (match_operand:TI 0 "register_operand" "")
12303         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12304                      (match_operand:QI 2 "immediate_operand" "")))
12305    (clobber (reg:CC FLAGS_REG))]
12306   "TARGET_64BIT && reload_completed"
12307   [(const_int 0)]
12308   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12309
12310 (define_expand "lshrdi3"
12311   [(set (match_operand:DI 0 "shiftdi_operand" "")
12312         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12313                      (match_operand:QI 2 "nonmemory_operand" "")))]
12314   ""
12315   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12316
12317 (define_insn "*lshrdi3_1_one_bit_rex64"
12318   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12319         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12320                      (match_operand:QI 2 "const1_operand" "")))
12321    (clobber (reg:CC FLAGS_REG))]
12322   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323    && (TARGET_SHIFT1 || optimize_size)"
12324   "shr{q}\t%0"
12325   [(set_attr "type" "ishift")
12326    (set (attr "length")
12327      (if_then_else (match_operand:DI 0 "register_operand" "")
12328         (const_string "2")
12329         (const_string "*")))])
12330
12331 (define_insn "*lshrdi3_1_rex64"
12332   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12333         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12334                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12337   "@
12338    shr{q}\t{%2, %0|%0, %2}
12339    shr{q}\t{%b2, %0|%0, %b2}"
12340   [(set_attr "type" "ishift")
12341    (set_attr "mode" "DI")])
12342
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags.  We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12347   [(set (reg FLAGS_REG)
12348         (compare
12349           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350                        (match_operand:QI 2 "const1_operand" ""))
12351           (const_int 0)))
12352    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12353         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12354   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12355    && (TARGET_SHIFT1 || optimize_size)
12356    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12357   "shr{q}\t%0"
12358   [(set_attr "type" "ishift")
12359    (set (attr "length")
12360      (if_then_else (match_operand:DI 0 "register_operand" "")
12361         (const_string "2")
12362         (const_string "*")))])
12363
12364 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12365   [(set (reg FLAGS_REG)
12366         (compare
12367           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))
12369           (const_int 0)))
12370    (clobber (match_scratch:DI 0 "=r"))]
12371   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12372    && (TARGET_SHIFT1 || optimize_size)
12373    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12374   "shr{q}\t%0"
12375   [(set_attr "type" "ishift")
12376    (set_attr "length" "2")])
12377
12378 ;; This pattern can't accept a variable shift count, since shifts by
12379 ;; zero don't affect the flags.  We assume that shifts by constant
12380 ;; zero are optimized away.
12381 (define_insn "*lshrdi3_cmp_rex64"
12382   [(set (reg FLAGS_REG)
12383         (compare
12384           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12385                        (match_operand:QI 2 "const_int_operand" "e"))
12386           (const_int 0)))
12387    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12388         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12389   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12390    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12391    && (optimize_size
12392        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393   "shr{q}\t{%2, %0|%0, %2}"
12394   [(set_attr "type" "ishift")
12395    (set_attr "mode" "DI")])
12396
12397 (define_insn "*lshrdi3_cconly_rex64"
12398   [(set (reg FLAGS_REG)
12399         (compare
12400           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12401                        (match_operand:QI 2 "const_int_operand" "e"))
12402           (const_int 0)))
12403    (clobber (match_scratch:DI 0 "=r"))]
12404   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12405    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12406    && (optimize_size
12407        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408   "shr{q}\t{%2, %0|%0, %2}"
12409   [(set_attr "type" "ishift")
12410    (set_attr "mode" "DI")])
12411
12412 (define_insn "*lshrdi3_1"
12413   [(set (match_operand:DI 0 "register_operand" "=r")
12414         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12415                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "!TARGET_64BIT"
12418   "#"
12419   [(set_attr "type" "multi")])
12420
12421 ;; By default we don't ask for a scratch register, because when DImode
12422 ;; values are manipulated, registers are already at a premium.  But if
12423 ;; we have one handy, we won't turn it away.
12424 (define_peephole2
12425   [(match_scratch:SI 3 "r")
12426    (parallel [(set (match_operand:DI 0 "register_operand" "")
12427                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12428                                 (match_operand:QI 2 "nonmemory_operand" "")))
12429               (clobber (reg:CC FLAGS_REG))])
12430    (match_dup 3)]
12431   "!TARGET_64BIT && TARGET_CMOVE"
12432   [(const_int 0)]
12433   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12434
12435 (define_split
12436   [(set (match_operand:DI 0 "register_operand" "")
12437         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12438                      (match_operand:QI 2 "nonmemory_operand" "")))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12441                      ? flow2_completed : reload_completed)"
12442   [(const_int 0)]
12443   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12444
12445 (define_expand "lshrsi3"
12446   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448                      (match_operand:QI 2 "nonmemory_operand" "")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   ""
12451   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12452
12453 (define_insn "*lshrsi3_1_one_bit"
12454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456                      (match_operand:QI 2 "const1_operand" "")))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12459    && (TARGET_SHIFT1 || optimize_size)"
12460   "shr{l}\t%0"
12461   [(set_attr "type" "ishift")
12462    (set (attr "length")
12463      (if_then_else (match_operand:SI 0 "register_operand" "")
12464         (const_string "2")
12465         (const_string "*")))])
12466
12467 (define_insn "*lshrsi3_1_one_bit_zext"
12468   [(set (match_operand:DI 0 "register_operand" "=r")
12469         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12470                      (match_operand:QI 2 "const1_operand" "")))
12471    (clobber (reg:CC FLAGS_REG))]
12472   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12473    && (TARGET_SHIFT1 || optimize_size)"
12474   "shr{l}\t%k0"
12475   [(set_attr "type" "ishift")
12476    (set_attr "length" "2")])
12477
12478 (define_insn "*lshrsi3_1"
12479   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12480         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12481                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482    (clobber (reg:CC FLAGS_REG))]
12483   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12484   "@
12485    shr{l}\t{%2, %0|%0, %2}
12486    shr{l}\t{%b2, %0|%0, %b2}"
12487   [(set_attr "type" "ishift")
12488    (set_attr "mode" "SI")])
12489
12490 (define_insn "*lshrsi3_1_zext"
12491   [(set (match_operand:DI 0 "register_operand" "=r,r")
12492         (zero_extend:DI
12493           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12495    (clobber (reg:CC FLAGS_REG))]
12496   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12497   "@
12498    shr{l}\t{%2, %k0|%k0, %2}
12499    shr{l}\t{%b2, %k0|%k0, %b2}"
12500   [(set_attr "type" "ishift")
12501    (set_attr "mode" "SI")])
12502
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags.  We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*lshrsi3_one_bit_cmp"
12507   [(set (reg FLAGS_REG)
12508         (compare
12509           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510                        (match_operand:QI 2 "const1_operand" ""))
12511           (const_int 0)))
12512    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12514   "ix86_match_ccmode (insn, CCGOCmode)
12515    && (TARGET_SHIFT1 || optimize_size)
12516    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12517   "shr{l}\t%0"
12518   [(set_attr "type" "ishift")
12519    (set (attr "length")
12520      (if_then_else (match_operand:SI 0 "register_operand" "")
12521         (const_string "2")
12522         (const_string "*")))])
12523
12524 (define_insn "*lshrsi3_one_bit_cconly"
12525   [(set (reg FLAGS_REG)
12526         (compare
12527           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12528                        (match_operand:QI 2 "const1_operand" ""))
12529           (const_int 0)))
12530    (clobber (match_scratch:SI 0 "=r"))]
12531   "ix86_match_ccmode (insn, CCGOCmode)
12532    && (TARGET_SHIFT1 || optimize_size)
12533    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12534   "shr{l}\t%0"
12535   [(set_attr "type" "ishift")
12536    (set_attr "length" "2")])
12537
12538 (define_insn "*lshrsi3_cmp_one_bit_zext"
12539   [(set (reg FLAGS_REG)
12540         (compare
12541           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12542                        (match_operand:QI 2 "const1_operand" ""))
12543           (const_int 0)))
12544    (set (match_operand:DI 0 "register_operand" "=r")
12545         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12546   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12547    && (TARGET_SHIFT1 || optimize_size)
12548    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12549   "shr{l}\t%k0"
12550   [(set_attr "type" "ishift")
12551    (set_attr "length" "2")])
12552
12553 ;; This pattern can't accept a variable shift count, since shifts by
12554 ;; zero don't affect the flags.  We assume that shifts by constant
12555 ;; zero are optimized away.
12556 (define_insn "*lshrsi3_cmp"
12557   [(set (reg FLAGS_REG)
12558         (compare
12559           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12560                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12561           (const_int 0)))
12562    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12563         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12564   "ix86_match_ccmode (insn, CCGOCmode)
12565    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12566    && (optimize_size
12567        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12568   "shr{l}\t{%2, %0|%0, %2}"
12569   [(set_attr "type" "ishift")
12570    (set_attr "mode" "SI")])
12571
12572 (define_insn "*lshrsi3_cconly"
12573   [(set (reg FLAGS_REG)
12574       (compare
12575         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12576                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12577         (const_int 0)))
12578    (clobber (match_scratch:SI 0 "=r"))]
12579   "ix86_match_ccmode (insn, CCGOCmode)
12580    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12581    && (optimize_size
12582        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12583   "shr{l}\t{%2, %0|%0, %2}"
12584   [(set_attr "type" "ishift")
12585    (set_attr "mode" "SI")])
12586
12587 (define_insn "*lshrsi3_cmp_zext"
12588   [(set (reg FLAGS_REG)
12589         (compare
12590           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12591                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12592           (const_int 0)))
12593    (set (match_operand:DI 0 "register_operand" "=r")
12594         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12596    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12597    && (optimize_size
12598        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12599   "shr{l}\t{%2, %k0|%k0, %2}"
12600   [(set_attr "type" "ishift")
12601    (set_attr "mode" "SI")])
12602
12603 (define_expand "lshrhi3"
12604   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12605         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12606                      (match_operand:QI 2 "nonmemory_operand" "")))
12607    (clobber (reg:CC FLAGS_REG))]
12608   "TARGET_HIMODE_MATH"
12609   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12610
12611 (define_insn "*lshrhi3_1_one_bit"
12612   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12614                      (match_operand:QI 2 "const1_operand" "")))
12615    (clobber (reg:CC FLAGS_REG))]
12616   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12617    && (TARGET_SHIFT1 || optimize_size)"
12618   "shr{w}\t%0"
12619   [(set_attr "type" "ishift")
12620    (set (attr "length")
12621      (if_then_else (match_operand 0 "register_operand" "")
12622         (const_string "2")
12623         (const_string "*")))])
12624
12625 (define_insn "*lshrhi3_1"
12626   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12627         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12628                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12629    (clobber (reg:CC FLAGS_REG))]
12630   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12631   "@
12632    shr{w}\t{%2, %0|%0, %2}
12633    shr{w}\t{%b2, %0|%0, %b2}"
12634   [(set_attr "type" "ishift")
12635    (set_attr "mode" "HI")])
12636
12637 ;; This pattern can't accept a variable shift count, since shifts by
12638 ;; zero don't affect the flags.  We assume that shifts by constant
12639 ;; zero are optimized away.
12640 (define_insn "*lshrhi3_one_bit_cmp"
12641   [(set (reg FLAGS_REG)
12642         (compare
12643           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644                        (match_operand:QI 2 "const1_operand" ""))
12645           (const_int 0)))
12646    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12647         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12648   "ix86_match_ccmode (insn, CCGOCmode)
12649    && (TARGET_SHIFT1 || optimize_size)
12650    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12651   "shr{w}\t%0"
12652   [(set_attr "type" "ishift")
12653    (set (attr "length")
12654      (if_then_else (match_operand:SI 0 "register_operand" "")
12655         (const_string "2")
12656         (const_string "*")))])
12657
12658 (define_insn "*lshrhi3_one_bit_cconly"
12659   [(set (reg FLAGS_REG)
12660         (compare
12661           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12662                        (match_operand:QI 2 "const1_operand" ""))
12663           (const_int 0)))
12664    (clobber (match_scratch:HI 0 "=r"))]
12665   "ix86_match_ccmode (insn, CCGOCmode)
12666    && (TARGET_SHIFT1 || optimize_size)
12667    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12668   "shr{w}\t%0"
12669   [(set_attr "type" "ishift")
12670    (set_attr "length" "2")])
12671
12672 ;; This pattern can't accept a variable shift count, since shifts by
12673 ;; zero don't affect the flags.  We assume that shifts by constant
12674 ;; zero are optimized away.
12675 (define_insn "*lshrhi3_cmp"
12676   [(set (reg FLAGS_REG)
12677         (compare
12678           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12679                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12680           (const_int 0)))
12681    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12683   "ix86_match_ccmode (insn, CCGOCmode)
12684    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12685    && (optimize_size
12686        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12687   "shr{w}\t{%2, %0|%0, %2}"
12688   [(set_attr "type" "ishift")
12689    (set_attr "mode" "HI")])
12690
12691 (define_insn "*lshrhi3_cconly"
12692   [(set (reg FLAGS_REG)
12693         (compare
12694           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12695                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12696           (const_int 0)))
12697    (clobber (match_scratch:HI 0 "=r"))]
12698   "ix86_match_ccmode (insn, CCGOCmode)
12699    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12700    && (optimize_size
12701        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12702   "shr{w}\t{%2, %0|%0, %2}"
12703   [(set_attr "type" "ishift")
12704    (set_attr "mode" "HI")])
12705
12706 (define_expand "lshrqi3"
12707   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709                      (match_operand:QI 2 "nonmemory_operand" "")))
12710    (clobber (reg:CC FLAGS_REG))]
12711   "TARGET_QIMODE_MATH"
12712   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12713
12714 (define_insn "*lshrqi3_1_one_bit"
12715   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12716         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717                      (match_operand:QI 2 "const1_operand" "")))
12718    (clobber (reg:CC FLAGS_REG))]
12719   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12720    && (TARGET_SHIFT1 || optimize_size)"
12721   "shr{b}\t%0"
12722   [(set_attr "type" "ishift")
12723    (set (attr "length")
12724      (if_then_else (match_operand 0 "register_operand" "")
12725         (const_string "2")
12726         (const_string "*")))])
12727
12728 (define_insn "*lshrqi3_1_one_bit_slp"
12729   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12730         (lshiftrt:QI (match_dup 0)
12731                      (match_operand:QI 1 "const1_operand" "")))
12732    (clobber (reg:CC FLAGS_REG))]
12733   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12734    && (TARGET_SHIFT1 || optimize_size)"
12735   "shr{b}\t%0"
12736   [(set_attr "type" "ishift1")
12737    (set (attr "length")
12738      (if_then_else (match_operand 0 "register_operand" "")
12739         (const_string "2")
12740         (const_string "*")))])
12741
12742 (define_insn "*lshrqi3_1"
12743   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746    (clobber (reg:CC FLAGS_REG))]
12747   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12748   "@
12749    shr{b}\t{%2, %0|%0, %2}
12750    shr{b}\t{%b2, %0|%0, %b2}"
12751   [(set_attr "type" "ishift")
12752    (set_attr "mode" "QI")])
12753
12754 (define_insn "*lshrqi3_1_slp"
12755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12756         (lshiftrt:QI (match_dup 0)
12757                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12758    (clobber (reg:CC FLAGS_REG))]
12759   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12760    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12761   "@
12762    shr{b}\t{%1, %0|%0, %1}
12763    shr{b}\t{%b1, %0|%0, %b1}"
12764   [(set_attr "type" "ishift1")
12765    (set_attr "mode" "QI")])
12766
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags.  We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrqi2_one_bit_cmp"
12771   [(set (reg FLAGS_REG)
12772         (compare
12773           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12774                        (match_operand:QI 2 "const1_operand" ""))
12775           (const_int 0)))
12776    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12778   "ix86_match_ccmode (insn, CCGOCmode)
12779    && (TARGET_SHIFT1 || optimize_size)
12780    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12781   "shr{b}\t%0"
12782   [(set_attr "type" "ishift")
12783    (set (attr "length")
12784      (if_then_else (match_operand:SI 0 "register_operand" "")
12785         (const_string "2")
12786         (const_string "*")))])
12787
12788 (define_insn "*lshrqi2_one_bit_cconly"
12789   [(set (reg FLAGS_REG)
12790         (compare
12791           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12792                        (match_operand:QI 2 "const1_operand" ""))
12793           (const_int 0)))
12794    (clobber (match_scratch:QI 0 "=q"))]
12795   "ix86_match_ccmode (insn, CCGOCmode)
12796    && (TARGET_SHIFT1 || optimize_size)
12797    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12798   "shr{b}\t%0"
12799   [(set_attr "type" "ishift")
12800    (set_attr "length" "2")])
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 "*lshrqi2_cmp"
12806   [(set (reg FLAGS_REG)
12807         (compare
12808           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12809                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12810           (const_int 0)))
12811    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12812         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12813   "ix86_match_ccmode (insn, CCGOCmode)
12814    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12815    && (optimize_size
12816        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12817   "shr{b}\t{%2, %0|%0, %2}"
12818   [(set_attr "type" "ishift")
12819    (set_attr "mode" "QI")])
12820
12821 (define_insn "*lshrqi2_cconly"
12822   [(set (reg FLAGS_REG)
12823         (compare
12824           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12825                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12826           (const_int 0)))
12827    (clobber (match_scratch:QI 0 "=q"))]
12828   "ix86_match_ccmode (insn, CCGOCmode)
12829    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12830    && (optimize_size
12831        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12832   "shr{b}\t{%2, %0|%0, %2}"
12833   [(set_attr "type" "ishift")
12834    (set_attr "mode" "QI")])
12835 \f
12836 ;; Rotate instructions
12837
12838 (define_expand "rotldi3"
12839   [(set (match_operand:DI 0 "shiftdi_operand" "")
12840         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12841                    (match_operand:QI 2 "nonmemory_operand" "")))
12842    (clobber (reg:CC FLAGS_REG))]
12843  ""
12844 {
12845   if (TARGET_64BIT)
12846     {
12847       ix86_expand_binary_operator (ROTATE, DImode, operands);
12848       DONE;
12849     }
12850   if (!const_1_to_31_operand (operands[2], VOIDmode))
12851     FAIL;
12852   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12853   DONE;
12854 })
12855
12856 ;; Implement rotation using two double-precision shift instructions
12857 ;; and a scratch register.
12858 (define_insn_and_split "ix86_rotldi3"
12859  [(set (match_operand:DI 0 "register_operand" "=r")
12860        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12861                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12862   (clobber (reg:CC FLAGS_REG))
12863   (clobber (match_scratch:SI 3 "=&r"))]
12864  "!TARGET_64BIT"
12865  ""
12866  "&& reload_completed"
12867  [(set (match_dup 3) (match_dup 4))
12868   (parallel
12869    [(set (match_dup 4)
12870          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12871                  (lshiftrt:SI (match_dup 5)
12872                               (minus:QI (const_int 32) (match_dup 2)))))
12873     (clobber (reg:CC FLAGS_REG))])
12874   (parallel
12875    [(set (match_dup 5)
12876          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12877                  (lshiftrt:SI (match_dup 3)
12878                               (minus:QI (const_int 32) (match_dup 2)))))
12879     (clobber (reg:CC FLAGS_REG))])]
12880  "split_di (operands, 1, operands + 4, operands + 5);")
12881
12882 (define_insn "*rotlsi3_1_one_bit_rex64"
12883   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12884         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12885                    (match_operand:QI 2 "const1_operand" "")))
12886    (clobber (reg:CC FLAGS_REG))]
12887   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12888    && (TARGET_SHIFT1 || optimize_size)"
12889   "rol{q}\t%0"
12890   [(set_attr "type" "rotate")
12891    (set (attr "length")
12892      (if_then_else (match_operand:DI 0 "register_operand" "")
12893         (const_string "2")
12894         (const_string "*")))])
12895
12896 (define_insn "*rotldi3_1_rex64"
12897   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12898         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12899                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12900    (clobber (reg:CC FLAGS_REG))]
12901   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12902   "@
12903    rol{q}\t{%2, %0|%0, %2}
12904    rol{q}\t{%b2, %0|%0, %b2}"
12905   [(set_attr "type" "rotate")
12906    (set_attr "mode" "DI")])
12907
12908 (define_expand "rotlsi3"
12909   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12910         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12911                    (match_operand:QI 2 "nonmemory_operand" "")))
12912    (clobber (reg:CC FLAGS_REG))]
12913   ""
12914   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12915
12916 (define_insn "*rotlsi3_1_one_bit"
12917   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12918         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12919                    (match_operand:QI 2 "const1_operand" "")))
12920    (clobber (reg:CC FLAGS_REG))]
12921   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12922    && (TARGET_SHIFT1 || optimize_size)"
12923   "rol{l}\t%0"
12924   [(set_attr "type" "rotate")
12925    (set (attr "length")
12926      (if_then_else (match_operand:SI 0 "register_operand" "")
12927         (const_string "2")
12928         (const_string "*")))])
12929
12930 (define_insn "*rotlsi3_1_one_bit_zext"
12931   [(set (match_operand:DI 0 "register_operand" "=r")
12932         (zero_extend:DI
12933           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12934                      (match_operand:QI 2 "const1_operand" ""))))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12937    && (TARGET_SHIFT1 || optimize_size)"
12938   "rol{l}\t%k0"
12939   [(set_attr "type" "rotate")
12940    (set_attr "length" "2")])
12941
12942 (define_insn "*rotlsi3_1"
12943   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12944         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12945                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12946    (clobber (reg:CC FLAGS_REG))]
12947   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12948   "@
12949    rol{l}\t{%2, %0|%0, %2}
12950    rol{l}\t{%b2, %0|%0, %b2}"
12951   [(set_attr "type" "rotate")
12952    (set_attr "mode" "SI")])
12953
12954 (define_insn "*rotlsi3_1_zext"
12955   [(set (match_operand:DI 0 "register_operand" "=r,r")
12956         (zero_extend:DI
12957           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12958                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12961   "@
12962    rol{l}\t{%2, %k0|%k0, %2}
12963    rol{l}\t{%b2, %k0|%k0, %b2}"
12964   [(set_attr "type" "rotate")
12965    (set_attr "mode" "SI")])
12966
12967 (define_expand "rotlhi3"
12968   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12969         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12970                    (match_operand:QI 2 "nonmemory_operand" "")))
12971    (clobber (reg:CC FLAGS_REG))]
12972   "TARGET_HIMODE_MATH"
12973   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12974
12975 (define_insn "*rotlhi3_1_one_bit"
12976   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12977         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12978                    (match_operand:QI 2 "const1_operand" "")))
12979    (clobber (reg:CC FLAGS_REG))]
12980   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12981    && (TARGET_SHIFT1 || optimize_size)"
12982   "rol{w}\t%0"
12983   [(set_attr "type" "rotate")
12984    (set (attr "length")
12985      (if_then_else (match_operand 0 "register_operand" "")
12986         (const_string "2")
12987         (const_string "*")))])
12988
12989 (define_insn "*rotlhi3_1"
12990   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12991         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12992                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12993    (clobber (reg:CC FLAGS_REG))]
12994   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12995   "@
12996    rol{w}\t{%2, %0|%0, %2}
12997    rol{w}\t{%b2, %0|%0, %b2}"
12998   [(set_attr "type" "rotate")
12999    (set_attr "mode" "HI")])
13000
13001 (define_expand "rotlqi3"
13002   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004                    (match_operand:QI 2 "nonmemory_operand" "")))
13005    (clobber (reg:CC FLAGS_REG))]
13006   "TARGET_QIMODE_MATH"
13007   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13008
13009 (define_insn "*rotlqi3_1_one_bit_slp"
13010   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011         (rotate:QI (match_dup 0)
13012                    (match_operand:QI 1 "const1_operand" "")))
13013    (clobber (reg:CC FLAGS_REG))]
13014   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015    && (TARGET_SHIFT1 || optimize_size)"
13016   "rol{b}\t%0"
13017   [(set_attr "type" "rotate1")
13018    (set (attr "length")
13019      (if_then_else (match_operand 0 "register_operand" "")
13020         (const_string "2")
13021         (const_string "*")))])
13022
13023 (define_insn "*rotlqi3_1_one_bit"
13024   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13025         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13026                    (match_operand:QI 2 "const1_operand" "")))
13027    (clobber (reg:CC FLAGS_REG))]
13028   "ix86_binary_operator_ok (ROTATE, QImode, operands)
13029    && (TARGET_SHIFT1 || optimize_size)"
13030   "rol{b}\t%0"
13031   [(set_attr "type" "rotate")
13032    (set (attr "length")
13033      (if_then_else (match_operand 0 "register_operand" "")
13034         (const_string "2")
13035         (const_string "*")))])
13036
13037 (define_insn "*rotlqi3_1_slp"
13038   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13039         (rotate:QI (match_dup 0)
13040                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13041    (clobber (reg:CC FLAGS_REG))]
13042   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13043    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13044   "@
13045    rol{b}\t{%1, %0|%0, %1}
13046    rol{b}\t{%b1, %0|%0, %b1}"
13047   [(set_attr "type" "rotate1")
13048    (set_attr "mode" "QI")])
13049
13050 (define_insn "*rotlqi3_1"
13051   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13052         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13053                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13054    (clobber (reg:CC FLAGS_REG))]
13055   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13056   "@
13057    rol{b}\t{%2, %0|%0, %2}
13058    rol{b}\t{%b2, %0|%0, %b2}"
13059   [(set_attr "type" "rotate")
13060    (set_attr "mode" "QI")])
13061
13062 (define_expand "rotrdi3"
13063   [(set (match_operand:DI 0 "shiftdi_operand" "")
13064         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13065                    (match_operand:QI 2 "nonmemory_operand" "")))
13066    (clobber (reg:CC FLAGS_REG))]
13067  ""
13068 {
13069   if (TARGET_64BIT)
13070     {
13071       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13072       DONE;
13073     }
13074   if (!const_1_to_31_operand (operands[2], VOIDmode))
13075     FAIL;
13076   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13077   DONE;
13078 })
13079
13080 ;; Implement rotation using two double-precision shift instructions
13081 ;; and a scratch register.
13082 (define_insn_and_split "ix86_rotrdi3"
13083  [(set (match_operand:DI 0 "register_operand" "=r")
13084        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13085                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13086   (clobber (reg:CC FLAGS_REG))
13087   (clobber (match_scratch:SI 3 "=&r"))]
13088  "!TARGET_64BIT"
13089  ""
13090  "&& reload_completed"
13091  [(set (match_dup 3) (match_dup 4))
13092   (parallel
13093    [(set (match_dup 4)
13094          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13095                  (ashift:SI (match_dup 5)
13096                             (minus:QI (const_int 32) (match_dup 2)))))
13097     (clobber (reg:CC FLAGS_REG))])
13098   (parallel
13099    [(set (match_dup 5)
13100          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13101                  (ashift:SI (match_dup 3)
13102                             (minus:QI (const_int 32) (match_dup 2)))))
13103     (clobber (reg:CC FLAGS_REG))])]
13104  "split_di (operands, 1, operands + 4, operands + 5);")
13105
13106 (define_insn "*rotrdi3_1_one_bit_rex64"
13107   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13108         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13109                      (match_operand:QI 2 "const1_operand" "")))
13110    (clobber (reg:CC FLAGS_REG))]
13111   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13112    && (TARGET_SHIFT1 || optimize_size)"
13113   "ror{q}\t%0"
13114   [(set_attr "type" "rotate")
13115    (set (attr "length")
13116      (if_then_else (match_operand:DI 0 "register_operand" "")
13117         (const_string "2")
13118         (const_string "*")))])
13119
13120 (define_insn "*rotrdi3_1_rex64"
13121   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13122         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13123                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13124    (clobber (reg:CC FLAGS_REG))]
13125   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13126   "@
13127    ror{q}\t{%2, %0|%0, %2}
13128    ror{q}\t{%b2, %0|%0, %b2}"
13129   [(set_attr "type" "rotate")
13130    (set_attr "mode" "DI")])
13131
13132 (define_expand "rotrsi3"
13133   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13134         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13135                      (match_operand:QI 2 "nonmemory_operand" "")))
13136    (clobber (reg:CC FLAGS_REG))]
13137   ""
13138   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13139
13140 (define_insn "*rotrsi3_1_one_bit"
13141   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13142         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13143                      (match_operand:QI 2 "const1_operand" "")))
13144    (clobber (reg:CC FLAGS_REG))]
13145   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13146    && (TARGET_SHIFT1 || optimize_size)"
13147   "ror{l}\t%0"
13148   [(set_attr "type" "rotate")
13149    (set (attr "length")
13150      (if_then_else (match_operand:SI 0 "register_operand" "")
13151         (const_string "2")
13152         (const_string "*")))])
13153
13154 (define_insn "*rotrsi3_1_one_bit_zext"
13155   [(set (match_operand:DI 0 "register_operand" "=r")
13156         (zero_extend:DI
13157           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13158                        (match_operand:QI 2 "const1_operand" ""))))
13159    (clobber (reg:CC FLAGS_REG))]
13160   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13161    && (TARGET_SHIFT1 || optimize_size)"
13162   "ror{l}\t%k0"
13163   [(set_attr "type" "rotate")
13164    (set (attr "length")
13165      (if_then_else (match_operand:SI 0 "register_operand" "")
13166         (const_string "2")
13167         (const_string "*")))])
13168
13169 (define_insn "*rotrsi3_1"
13170   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13171         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13172                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13173    (clobber (reg:CC FLAGS_REG))]
13174   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13175   "@
13176    ror{l}\t{%2, %0|%0, %2}
13177    ror{l}\t{%b2, %0|%0, %b2}"
13178   [(set_attr "type" "rotate")
13179    (set_attr "mode" "SI")])
13180
13181 (define_insn "*rotrsi3_1_zext"
13182   [(set (match_operand:DI 0 "register_operand" "=r,r")
13183         (zero_extend:DI
13184           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13185                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13186    (clobber (reg:CC FLAGS_REG))]
13187   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13188   "@
13189    ror{l}\t{%2, %k0|%k0, %2}
13190    ror{l}\t{%b2, %k0|%k0, %b2}"
13191   [(set_attr "type" "rotate")
13192    (set_attr "mode" "SI")])
13193
13194 (define_expand "rotrhi3"
13195   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13196         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13197                      (match_operand:QI 2 "nonmemory_operand" "")))
13198    (clobber (reg:CC FLAGS_REG))]
13199   "TARGET_HIMODE_MATH"
13200   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13201
13202 (define_insn "*rotrhi3_one_bit"
13203   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13204         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13205                      (match_operand:QI 2 "const1_operand" "")))
13206    (clobber (reg:CC FLAGS_REG))]
13207   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13208    && (TARGET_SHIFT1 || optimize_size)"
13209   "ror{w}\t%0"
13210   [(set_attr "type" "rotate")
13211    (set (attr "length")
13212      (if_then_else (match_operand 0 "register_operand" "")
13213         (const_string "2")
13214         (const_string "*")))])
13215
13216 (define_insn "*rotrhi3"
13217   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13218         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13219                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13220    (clobber (reg:CC FLAGS_REG))]
13221   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13222   "@
13223    ror{w}\t{%2, %0|%0, %2}
13224    ror{w}\t{%b2, %0|%0, %b2}"
13225   [(set_attr "type" "rotate")
13226    (set_attr "mode" "HI")])
13227
13228 (define_expand "rotrqi3"
13229   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13230         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13231                      (match_operand:QI 2 "nonmemory_operand" "")))
13232    (clobber (reg:CC FLAGS_REG))]
13233   "TARGET_QIMODE_MATH"
13234   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13235
13236 (define_insn "*rotrqi3_1_one_bit"
13237   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13238         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13239                      (match_operand:QI 2 "const1_operand" "")))
13240    (clobber (reg:CC FLAGS_REG))]
13241   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13242    && (TARGET_SHIFT1 || optimize_size)"
13243   "ror{b}\t%0"
13244   [(set_attr "type" "rotate")
13245    (set (attr "length")
13246      (if_then_else (match_operand 0 "register_operand" "")
13247         (const_string "2")
13248         (const_string "*")))])
13249
13250 (define_insn "*rotrqi3_1_one_bit_slp"
13251   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13252         (rotatert:QI (match_dup 0)
13253                      (match_operand:QI 1 "const1_operand" "")))
13254    (clobber (reg:CC FLAGS_REG))]
13255   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13256    && (TARGET_SHIFT1 || optimize_size)"
13257   "ror{b}\t%0"
13258   [(set_attr "type" "rotate1")
13259    (set (attr "length")
13260      (if_then_else (match_operand 0 "register_operand" "")
13261         (const_string "2")
13262         (const_string "*")))])
13263
13264 (define_insn "*rotrqi3_1"
13265   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268    (clobber (reg:CC FLAGS_REG))]
13269   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13270   "@
13271    ror{b}\t{%2, %0|%0, %2}
13272    ror{b}\t{%b2, %0|%0, %b2}"
13273   [(set_attr "type" "rotate")
13274    (set_attr "mode" "QI")])
13275
13276 (define_insn "*rotrqi3_1_slp"
13277   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13278         (rotatert:QI (match_dup 0)
13279                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13280    (clobber (reg:CC FLAGS_REG))]
13281   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13282    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13283   "@
13284    ror{b}\t{%1, %0|%0, %1}
13285    ror{b}\t{%b1, %0|%0, %b1}"
13286   [(set_attr "type" "rotate1")
13287    (set_attr "mode" "QI")])
13288 \f
13289 ;; Bit set / bit test instructions
13290
13291 (define_expand "extv"
13292   [(set (match_operand:SI 0 "register_operand" "")
13293         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13294                          (match_operand:SI 2 "const8_operand" "")
13295                          (match_operand:SI 3 "const8_operand" "")))]
13296   ""
13297 {
13298   /* Handle extractions from %ah et al.  */
13299   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13300     FAIL;
13301
13302   /* From mips.md: extract_bit_field doesn't verify that our source
13303      matches the predicate, so check it again here.  */
13304   if (! ext_register_operand (operands[1], VOIDmode))
13305     FAIL;
13306 })
13307
13308 (define_expand "extzv"
13309   [(set (match_operand:SI 0 "register_operand" "")
13310         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13311                          (match_operand:SI 2 "const8_operand" "")
13312                          (match_operand:SI 3 "const8_operand" "")))]
13313   ""
13314 {
13315   /* Handle extractions from %ah et al.  */
13316   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13317     FAIL;
13318
13319   /* From mips.md: extract_bit_field doesn't verify that our source
13320      matches the predicate, so check it again here.  */
13321   if (! ext_register_operand (operands[1], VOIDmode))
13322     FAIL;
13323 })
13324
13325 (define_expand "insv"
13326   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13327                       (match_operand 1 "const8_operand" "")
13328                       (match_operand 2 "const8_operand" ""))
13329         (match_operand 3 "register_operand" ""))]
13330   ""
13331 {
13332   /* Handle insertions to %ah et al.  */
13333   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13334     FAIL;
13335
13336   /* From mips.md: insert_bit_field doesn't verify that our source
13337      matches the predicate, so check it again here.  */
13338   if (! ext_register_operand (operands[0], VOIDmode))
13339     FAIL;
13340
13341   if (TARGET_64BIT)
13342     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13343   else
13344     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13345
13346   DONE;
13347 })
13348
13349 ;; %%% bts, btr, btc, bt.
13350 ;; In general these instructions are *slow* when applied to memory,
13351 ;; since they enforce atomic operation.  When applied to registers,
13352 ;; it depends on the cpu implementation.  They're never faster than
13353 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13354 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13355 ;; within the instruction itself, so operating on bits in the high
13356 ;; 32-bits of a register becomes easier.
13357 ;;
13358 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13359 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13360 ;; negdf respectively, so they can never be disabled entirely.
13361
13362 (define_insn "*btsq"
13363   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13364                          (const_int 1)
13365                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13366         (const_int 1))
13367    (clobber (reg:CC FLAGS_REG))]
13368   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13369   "bts{q} %1,%0"
13370   [(set_attr "type" "alu1")])
13371
13372 (define_insn "*btrq"
13373   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13374                          (const_int 1)
13375                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13376         (const_int 0))
13377    (clobber (reg:CC FLAGS_REG))]
13378   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13379   "btr{q} %1,%0"
13380   [(set_attr "type" "alu1")])
13381
13382 (define_insn "*btcq"
13383   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13384                          (const_int 1)
13385                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13386         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13387    (clobber (reg:CC FLAGS_REG))]
13388   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13389   "btc{q} %1,%0"
13390   [(set_attr "type" "alu1")])
13391
13392 ;; Allow Nocona to avoid these instructions if a register is available.
13393
13394 (define_peephole2
13395   [(match_scratch:DI 2 "r")
13396    (parallel [(set (zero_extract:DI
13397                      (match_operand:DI 0 "register_operand" "")
13398                      (const_int 1)
13399                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13400                    (const_int 1))
13401               (clobber (reg:CC FLAGS_REG))])]
13402   "TARGET_64BIT && !TARGET_USE_BT"
13403   [(const_int 0)]
13404 {
13405   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13406   rtx op1;
13407
13408   if (HOST_BITS_PER_WIDE_INT >= 64)
13409     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13410   else if (i < HOST_BITS_PER_WIDE_INT)
13411     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13412   else
13413     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13414
13415   op1 = immed_double_const (lo, hi, DImode);
13416   if (i >= 31)
13417     {
13418       emit_move_insn (operands[2], op1);
13419       op1 = operands[2];
13420     }
13421
13422   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13423   DONE;
13424 })
13425
13426 (define_peephole2
13427   [(match_scratch:DI 2 "r")
13428    (parallel [(set (zero_extract:DI
13429                      (match_operand:DI 0 "register_operand" "")
13430                      (const_int 1)
13431                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13432                    (const_int 0))
13433               (clobber (reg:CC FLAGS_REG))])]
13434   "TARGET_64BIT && !TARGET_USE_BT"
13435   [(const_int 0)]
13436 {
13437   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13438   rtx op1;
13439
13440   if (HOST_BITS_PER_WIDE_INT >= 64)
13441     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13442   else if (i < HOST_BITS_PER_WIDE_INT)
13443     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13444   else
13445     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13446
13447   op1 = immed_double_const (~lo, ~hi, DImode);
13448   if (i >= 32)
13449     {
13450       emit_move_insn (operands[2], op1);
13451       op1 = operands[2];
13452     }
13453
13454   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13455   DONE;
13456 })
13457
13458 (define_peephole2
13459   [(match_scratch:DI 2 "r")
13460    (parallel [(set (zero_extract:DI
13461                      (match_operand:DI 0 "register_operand" "")
13462                      (const_int 1)
13463                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13464               (not:DI (zero_extract:DI
13465                         (match_dup 0) (const_int 1) (match_dup 1))))
13466               (clobber (reg:CC FLAGS_REG))])]
13467   "TARGET_64BIT && !TARGET_USE_BT"
13468   [(const_int 0)]
13469 {
13470   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13471   rtx op1;
13472
13473   if (HOST_BITS_PER_WIDE_INT >= 64)
13474     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475   else if (i < HOST_BITS_PER_WIDE_INT)
13476     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13477   else
13478     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13479
13480   op1 = immed_double_const (lo, hi, DImode);
13481   if (i >= 31)
13482     {
13483       emit_move_insn (operands[2], op1);
13484       op1 = operands[2];
13485     }
13486
13487   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13488   DONE;
13489 })
13490 \f
13491 ;; Store-flag instructions.
13492
13493 ;; For all sCOND expanders, also expand the compare or test insn that
13494 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13495
13496 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13497 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13498 ;; way, which can later delete the movzx if only QImode is needed.
13499
13500 (define_expand "seq"
13501   [(set (match_operand:QI 0 "register_operand" "")
13502         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13503   ""
13504   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13505
13506 (define_expand "sne"
13507   [(set (match_operand:QI 0 "register_operand" "")
13508         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13509   ""
13510   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13511
13512 (define_expand "sgt"
13513   [(set (match_operand:QI 0 "register_operand" "")
13514         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13515   ""
13516   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13517
13518 (define_expand "sgtu"
13519   [(set (match_operand:QI 0 "register_operand" "")
13520         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13521   ""
13522   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13523
13524 (define_expand "slt"
13525   [(set (match_operand:QI 0 "register_operand" "")
13526         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13527   ""
13528   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13529
13530 (define_expand "sltu"
13531   [(set (match_operand:QI 0 "register_operand" "")
13532         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13533   ""
13534   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13535
13536 (define_expand "sge"
13537   [(set (match_operand:QI 0 "register_operand" "")
13538         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13539   ""
13540   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13541
13542 (define_expand "sgeu"
13543   [(set (match_operand:QI 0 "register_operand" "")
13544         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13545   ""
13546   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13547
13548 (define_expand "sle"
13549   [(set (match_operand:QI 0 "register_operand" "")
13550         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13551   ""
13552   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13553
13554 (define_expand "sleu"
13555   [(set (match_operand:QI 0 "register_operand" "")
13556         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13557   ""
13558   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13559
13560 (define_expand "sunordered"
13561   [(set (match_operand:QI 0 "register_operand" "")
13562         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563   "TARGET_80387 || TARGET_SSE"
13564   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13565
13566 (define_expand "sordered"
13567   [(set (match_operand:QI 0 "register_operand" "")
13568         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13569   "TARGET_80387"
13570   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13571
13572 (define_expand "suneq"
13573   [(set (match_operand:QI 0 "register_operand" "")
13574         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575   "TARGET_80387 || TARGET_SSE"
13576   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13577
13578 (define_expand "sunge"
13579   [(set (match_operand:QI 0 "register_operand" "")
13580         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581   "TARGET_80387 || TARGET_SSE"
13582   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13583
13584 (define_expand "sungt"
13585   [(set (match_operand:QI 0 "register_operand" "")
13586         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587   "TARGET_80387 || TARGET_SSE"
13588   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13589
13590 (define_expand "sunle"
13591   [(set (match_operand:QI 0 "register_operand" "")
13592         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593   "TARGET_80387 || TARGET_SSE"
13594   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13595
13596 (define_expand "sunlt"
13597   [(set (match_operand:QI 0 "register_operand" "")
13598         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599   "TARGET_80387 || TARGET_SSE"
13600   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13601
13602 (define_expand "sltgt"
13603   [(set (match_operand:QI 0 "register_operand" "")
13604         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605   "TARGET_80387 || TARGET_SSE"
13606   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13607
13608 (define_insn "*setcc_1"
13609   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610         (match_operator:QI 1 "ix86_comparison_operator"
13611           [(reg FLAGS_REG) (const_int 0)]))]
13612   ""
13613   "set%C1\t%0"
13614   [(set_attr "type" "setcc")
13615    (set_attr "mode" "QI")])
13616
13617 (define_insn "*setcc_2"
13618   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619         (match_operator:QI 1 "ix86_comparison_operator"
13620           [(reg FLAGS_REG) (const_int 0)]))]
13621   ""
13622   "set%C1\t%0"
13623   [(set_attr "type" "setcc")
13624    (set_attr "mode" "QI")])
13625
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one.  Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13629 ;;
13630 ;;      seta    %al
13631 ;;      testb   %al, %al
13632 ;;      sete    %al
13633
13634 (define_split
13635   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636         (ne:QI (match_operator 1 "ix86_comparison_operator"
13637                  [(reg FLAGS_REG) (const_int 0)])
13638             (const_int 0)))]
13639   ""
13640   [(set (match_dup 0) (match_dup 1))]
13641 {
13642   PUT_MODE (operands[1], QImode);
13643 })
13644
13645 (define_split
13646   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647         (ne:QI (match_operator 1 "ix86_comparison_operator"
13648                  [(reg FLAGS_REG) (const_int 0)])
13649             (const_int 0)))]
13650   ""
13651   [(set (match_dup 0) (match_dup 1))]
13652 {
13653   PUT_MODE (operands[1], QImode);
13654 })
13655
13656 (define_split
13657   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658         (eq:QI (match_operator 1 "ix86_comparison_operator"
13659                  [(reg FLAGS_REG) (const_int 0)])
13660             (const_int 0)))]
13661   ""
13662   [(set (match_dup 0) (match_dup 1))]
13663 {
13664   rtx new_op1 = copy_rtx (operands[1]);
13665   operands[1] = new_op1;
13666   PUT_MODE (new_op1, QImode);
13667   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668                                              GET_MODE (XEXP (new_op1, 0))));
13669
13670   /* Make sure that (a) the CCmode we have for the flags is strong
13671      enough for the reversed compare or (b) we have a valid FP compare.  */
13672   if (! ix86_comparison_operator (new_op1, VOIDmode))
13673     FAIL;
13674 })
13675
13676 (define_split
13677   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678         (eq:QI (match_operator 1 "ix86_comparison_operator"
13679                  [(reg FLAGS_REG) (const_int 0)])
13680             (const_int 0)))]
13681   ""
13682   [(set (match_dup 0) (match_dup 1))]
13683 {
13684   rtx new_op1 = copy_rtx (operands[1]);
13685   operands[1] = new_op1;
13686   PUT_MODE (new_op1, QImode);
13687   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688                                              GET_MODE (XEXP (new_op1, 0))));
13689
13690   /* Make sure that (a) the CCmode we have for the flags is strong
13691      enough for the reversed compare or (b) we have a valid FP compare.  */
13692   if (! ix86_comparison_operator (new_op1, VOIDmode))
13693     FAIL;
13694 })
13695
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13699 ;; it directly.
13700
13701 (define_insn "*sse_setccsf"
13702   [(set (match_operand:SF 0 "register_operand" "=x")
13703         (match_operator:SF 1 "sse_comparison_operator"
13704           [(match_operand:SF 2 "register_operand" "0")
13705            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13706   "TARGET_SSE"
13707   "cmp%D1ss\t{%3, %0|%0, %3}"
13708   [(set_attr "type" "ssecmp")
13709    (set_attr "mode" "SF")])
13710
13711 (define_insn "*sse_setccdf"
13712   [(set (match_operand:DF 0 "register_operand" "=x")
13713         (match_operator:DF 1 "sse_comparison_operator"
13714           [(match_operand:DF 2 "register_operand" "0")
13715            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13716   "TARGET_SSE2"
13717   "cmp%D1sd\t{%3, %0|%0, %3}"
13718   [(set_attr "type" "ssecmp")
13719    (set_attr "mode" "DF")])
13720 \f
13721 ;; Basic conditional jump instructions.
13722 ;; We ignore the overflow flag for signed branch instructions.
13723
13724 ;; For all bCOND expanders, also expand the compare or test insn that
13725 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13726
13727 (define_expand "beq"
13728   [(set (pc)
13729         (if_then_else (match_dup 1)
13730                       (label_ref (match_operand 0 "" ""))
13731                       (pc)))]
13732   ""
13733   "ix86_expand_branch (EQ, operands[0]); DONE;")
13734
13735 (define_expand "bne"
13736   [(set (pc)
13737         (if_then_else (match_dup 1)
13738                       (label_ref (match_operand 0 "" ""))
13739                       (pc)))]
13740   ""
13741   "ix86_expand_branch (NE, operands[0]); DONE;")
13742
13743 (define_expand "bgt"
13744   [(set (pc)
13745         (if_then_else (match_dup 1)
13746                       (label_ref (match_operand 0 "" ""))
13747                       (pc)))]
13748   ""
13749   "ix86_expand_branch (GT, operands[0]); DONE;")
13750
13751 (define_expand "bgtu"
13752   [(set (pc)
13753         (if_then_else (match_dup 1)
13754                       (label_ref (match_operand 0 "" ""))
13755                       (pc)))]
13756   ""
13757   "ix86_expand_branch (GTU, operands[0]); DONE;")
13758
13759 (define_expand "blt"
13760   [(set (pc)
13761         (if_then_else (match_dup 1)
13762                       (label_ref (match_operand 0 "" ""))
13763                       (pc)))]
13764   ""
13765   "ix86_expand_branch (LT, operands[0]); DONE;")
13766
13767 (define_expand "bltu"
13768   [(set (pc)
13769         (if_then_else (match_dup 1)
13770                       (label_ref (match_operand 0 "" ""))
13771                       (pc)))]
13772   ""
13773   "ix86_expand_branch (LTU, operands[0]); DONE;")
13774
13775 (define_expand "bge"
13776   [(set (pc)
13777         (if_then_else (match_dup 1)
13778                       (label_ref (match_operand 0 "" ""))
13779                       (pc)))]
13780   ""
13781   "ix86_expand_branch (GE, operands[0]); DONE;")
13782
13783 (define_expand "bgeu"
13784   [(set (pc)
13785         (if_then_else (match_dup 1)
13786                       (label_ref (match_operand 0 "" ""))
13787                       (pc)))]
13788   ""
13789   "ix86_expand_branch (GEU, operands[0]); DONE;")
13790
13791 (define_expand "ble"
13792   [(set (pc)
13793         (if_then_else (match_dup 1)
13794                       (label_ref (match_operand 0 "" ""))
13795                       (pc)))]
13796   ""
13797   "ix86_expand_branch (LE, operands[0]); DONE;")
13798
13799 (define_expand "bleu"
13800   [(set (pc)
13801         (if_then_else (match_dup 1)
13802                       (label_ref (match_operand 0 "" ""))
13803                       (pc)))]
13804   ""
13805   "ix86_expand_branch (LEU, operands[0]); DONE;")
13806
13807 (define_expand "bunordered"
13808   [(set (pc)
13809         (if_then_else (match_dup 1)
13810                       (label_ref (match_operand 0 "" ""))
13811                       (pc)))]
13812   "TARGET_80387 || TARGET_SSE_MATH"
13813   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13814
13815 (define_expand "bordered"
13816   [(set (pc)
13817         (if_then_else (match_dup 1)
13818                       (label_ref (match_operand 0 "" ""))
13819                       (pc)))]
13820   "TARGET_80387 || TARGET_SSE_MATH"
13821   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13822
13823 (define_expand "buneq"
13824   [(set (pc)
13825         (if_then_else (match_dup 1)
13826                       (label_ref (match_operand 0 "" ""))
13827                       (pc)))]
13828   "TARGET_80387 || TARGET_SSE_MATH"
13829   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13830
13831 (define_expand "bunge"
13832   [(set (pc)
13833         (if_then_else (match_dup 1)
13834                       (label_ref (match_operand 0 "" ""))
13835                       (pc)))]
13836   "TARGET_80387 || TARGET_SSE_MATH"
13837   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13838
13839 (define_expand "bungt"
13840   [(set (pc)
13841         (if_then_else (match_dup 1)
13842                       (label_ref (match_operand 0 "" ""))
13843                       (pc)))]
13844   "TARGET_80387 || TARGET_SSE_MATH"
13845   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13846
13847 (define_expand "bunle"
13848   [(set (pc)
13849         (if_then_else (match_dup 1)
13850                       (label_ref (match_operand 0 "" ""))
13851                       (pc)))]
13852   "TARGET_80387 || TARGET_SSE_MATH"
13853   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13854
13855 (define_expand "bunlt"
13856   [(set (pc)
13857         (if_then_else (match_dup 1)
13858                       (label_ref (match_operand 0 "" ""))
13859                       (pc)))]
13860   "TARGET_80387 || TARGET_SSE_MATH"
13861   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13862
13863 (define_expand "bltgt"
13864   [(set (pc)
13865         (if_then_else (match_dup 1)
13866                       (label_ref (match_operand 0 "" ""))
13867                       (pc)))]
13868   "TARGET_80387 || TARGET_SSE_MATH"
13869   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13870
13871 (define_insn "*jcc_1"
13872   [(set (pc)
13873         (if_then_else (match_operator 1 "ix86_comparison_operator"
13874                                       [(reg FLAGS_REG) (const_int 0)])
13875                       (label_ref (match_operand 0 "" ""))
13876                       (pc)))]
13877   ""
13878   "%+j%C1\t%l0"
13879   [(set_attr "type" "ibr")
13880    (set_attr "modrm" "0")
13881    (set (attr "length")
13882            (if_then_else (and (ge (minus (match_dup 0) (pc))
13883                                   (const_int -126))
13884                               (lt (minus (match_dup 0) (pc))
13885                                   (const_int 128)))
13886              (const_int 2)
13887              (const_int 6)))])
13888
13889 (define_insn "*jcc_2"
13890   [(set (pc)
13891         (if_then_else (match_operator 1 "ix86_comparison_operator"
13892                                       [(reg FLAGS_REG) (const_int 0)])
13893                       (pc)
13894                       (label_ref (match_operand 0 "" ""))))]
13895   ""
13896   "%+j%c1\t%l0"
13897   [(set_attr "type" "ibr")
13898    (set_attr "modrm" "0")
13899    (set (attr "length")
13900            (if_then_else (and (ge (minus (match_dup 0) (pc))
13901                                   (const_int -126))
13902                               (lt (minus (match_dup 0) (pc))
13903                                   (const_int 128)))
13904              (const_int 2)
13905              (const_int 6)))])
13906
13907 ;; In general it is not safe to assume too much about CCmode registers,
13908 ;; so simplify-rtx stops when it sees a second one.  Under certain
13909 ;; conditions this is safe on x86, so help combine not create
13910 ;;
13911 ;;      seta    %al
13912 ;;      testb   %al, %al
13913 ;;      je      Lfoo
13914
13915 (define_split
13916   [(set (pc)
13917         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13918                                       [(reg FLAGS_REG) (const_int 0)])
13919                           (const_int 0))
13920                       (label_ref (match_operand 1 "" ""))
13921                       (pc)))]
13922   ""
13923   [(set (pc)
13924         (if_then_else (match_dup 0)
13925                       (label_ref (match_dup 1))
13926                       (pc)))]
13927 {
13928   PUT_MODE (operands[0], VOIDmode);
13929 })
13930
13931 (define_split
13932   [(set (pc)
13933         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13934                                       [(reg FLAGS_REG) (const_int 0)])
13935                           (const_int 0))
13936                       (label_ref (match_operand 1 "" ""))
13937                       (pc)))]
13938   ""
13939   [(set (pc)
13940         (if_then_else (match_dup 0)
13941                       (label_ref (match_dup 1))
13942                       (pc)))]
13943 {
13944   rtx new_op0 = copy_rtx (operands[0]);
13945   operands[0] = new_op0;
13946   PUT_MODE (new_op0, VOIDmode);
13947   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13948                                              GET_MODE (XEXP (new_op0, 0))));
13949
13950   /* Make sure that (a) the CCmode we have for the flags is strong
13951      enough for the reversed compare or (b) we have a valid FP compare.  */
13952   if (! ix86_comparison_operator (new_op0, VOIDmode))
13953     FAIL;
13954 })
13955
13956 ;; Define combination compare-and-branch fp compare instructions to use
13957 ;; during early optimization.  Splitting the operation apart early makes
13958 ;; for bad code when we want to reverse the operation.
13959
13960 (define_insn "*fp_jcc_1_mixed"
13961   [(set (pc)
13962         (if_then_else (match_operator 0 "comparison_operator"
13963                         [(match_operand 1 "register_operand" "f,x")
13964                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13965           (label_ref (match_operand 3 "" ""))
13966           (pc)))
13967    (clobber (reg:CCFP FPSR_REG))
13968    (clobber (reg:CCFP FLAGS_REG))]
13969   "TARGET_MIX_SSE_I387
13970    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13971    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13972    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13973   "#")
13974
13975 (define_insn "*fp_jcc_1_sse"
13976   [(set (pc)
13977         (if_then_else (match_operator 0 "comparison_operator"
13978                         [(match_operand 1 "register_operand" "x")
13979                          (match_operand 2 "nonimmediate_operand" "xm")])
13980           (label_ref (match_operand 3 "" ""))
13981           (pc)))
13982    (clobber (reg:CCFP FPSR_REG))
13983    (clobber (reg:CCFP FLAGS_REG))]
13984   "TARGET_SSE_MATH
13985    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13986    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13987    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13988   "#")
13989
13990 (define_insn "*fp_jcc_1_387"
13991   [(set (pc)
13992         (if_then_else (match_operator 0 "comparison_operator"
13993                         [(match_operand 1 "register_operand" "f")
13994                          (match_operand 2 "register_operand" "f")])
13995           (label_ref (match_operand 3 "" ""))
13996           (pc)))
13997    (clobber (reg:CCFP FPSR_REG))
13998    (clobber (reg:CCFP FLAGS_REG))]
13999   "TARGET_CMOVE && TARGET_80387
14000    && FLOAT_MODE_P (GET_MODE (operands[1]))
14001    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14002    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14003   "#")
14004
14005 (define_insn "*fp_jcc_2_mixed"
14006   [(set (pc)
14007         (if_then_else (match_operator 0 "comparison_operator"
14008                         [(match_operand 1 "register_operand" "f,x")
14009                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14010           (pc)
14011           (label_ref (match_operand 3 "" ""))))
14012    (clobber (reg:CCFP FPSR_REG))
14013    (clobber (reg:CCFP FLAGS_REG))]
14014   "TARGET_MIX_SSE_I387
14015    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14016    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14017    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14018   "#")
14019
14020 (define_insn "*fp_jcc_2_sse"
14021   [(set (pc)
14022         (if_then_else (match_operator 0 "comparison_operator"
14023                         [(match_operand 1 "register_operand" "x")
14024                          (match_operand 2 "nonimmediate_operand" "xm")])
14025           (pc)
14026           (label_ref (match_operand 3 "" ""))))
14027    (clobber (reg:CCFP FPSR_REG))
14028    (clobber (reg:CCFP FLAGS_REG))]
14029   "TARGET_SSE_MATH
14030    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14031    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14032    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14033   "#")
14034
14035 (define_insn "*fp_jcc_2_387"
14036   [(set (pc)
14037         (if_then_else (match_operator 0 "comparison_operator"
14038                         [(match_operand 1 "register_operand" "f")
14039                          (match_operand 2 "register_operand" "f")])
14040           (pc)
14041           (label_ref (match_operand 3 "" ""))))
14042    (clobber (reg:CCFP FPSR_REG))
14043    (clobber (reg:CCFP FLAGS_REG))]
14044   "TARGET_CMOVE && TARGET_80387
14045    && FLOAT_MODE_P (GET_MODE (operands[1]))
14046    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14047    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14048   "#")
14049
14050 (define_insn "*fp_jcc_3_387"
14051   [(set (pc)
14052         (if_then_else (match_operator 0 "comparison_operator"
14053                         [(match_operand 1 "register_operand" "f")
14054                          (match_operand 2 "nonimmediate_operand" "fm")])
14055           (label_ref (match_operand 3 "" ""))
14056           (pc)))
14057    (clobber (reg:CCFP FPSR_REG))
14058    (clobber (reg:CCFP FLAGS_REG))
14059    (clobber (match_scratch:HI 4 "=a"))]
14060   "TARGET_80387
14061    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14062    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14063    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14064    && SELECT_CC_MODE (GET_CODE (operands[0]),
14065                       operands[1], operands[2]) == CCFPmode
14066    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14067   "#")
14068
14069 (define_insn "*fp_jcc_4_387"
14070   [(set (pc)
14071         (if_then_else (match_operator 0 "comparison_operator"
14072                         [(match_operand 1 "register_operand" "f")
14073                          (match_operand 2 "nonimmediate_operand" "fm")])
14074           (pc)
14075           (label_ref (match_operand 3 "" ""))))
14076    (clobber (reg:CCFP FPSR_REG))
14077    (clobber (reg:CCFP FLAGS_REG))
14078    (clobber (match_scratch:HI 4 "=a"))]
14079   "TARGET_80387
14080    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14081    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14082    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14083    && SELECT_CC_MODE (GET_CODE (operands[0]),
14084                       operands[1], operands[2]) == CCFPmode
14085    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14086   "#")
14087
14088 (define_insn "*fp_jcc_5_387"
14089   [(set (pc)
14090         (if_then_else (match_operator 0 "comparison_operator"
14091                         [(match_operand 1 "register_operand" "f")
14092                          (match_operand 2 "register_operand" "f")])
14093           (label_ref (match_operand 3 "" ""))
14094           (pc)))
14095    (clobber (reg:CCFP FPSR_REG))
14096    (clobber (reg:CCFP FLAGS_REG))
14097    (clobber (match_scratch:HI 4 "=a"))]
14098   "TARGET_80387
14099    && FLOAT_MODE_P (GET_MODE (operands[1]))
14100    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14101    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14102   "#")
14103
14104 (define_insn "*fp_jcc_6_387"
14105   [(set (pc)
14106         (if_then_else (match_operator 0 "comparison_operator"
14107                         [(match_operand 1 "register_operand" "f")
14108                          (match_operand 2 "register_operand" "f")])
14109           (pc)
14110           (label_ref (match_operand 3 "" ""))))
14111    (clobber (reg:CCFP FPSR_REG))
14112    (clobber (reg:CCFP FLAGS_REG))
14113    (clobber (match_scratch:HI 4 "=a"))]
14114   "TARGET_80387
14115    && FLOAT_MODE_P (GET_MODE (operands[1]))
14116    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14117    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14118   "#")
14119
14120 (define_insn "*fp_jcc_7_387"
14121   [(set (pc)
14122         (if_then_else (match_operator 0 "comparison_operator"
14123                         [(match_operand 1 "register_operand" "f")
14124                          (match_operand 2 "const0_operand" "X")])
14125           (label_ref (match_operand 3 "" ""))
14126           (pc)))
14127    (clobber (reg:CCFP FPSR_REG))
14128    (clobber (reg:CCFP FLAGS_REG))
14129    (clobber (match_scratch:HI 4 "=a"))]
14130   "TARGET_80387
14131    && FLOAT_MODE_P (GET_MODE (operands[1]))
14132    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134    && SELECT_CC_MODE (GET_CODE (operands[0]),
14135                       operands[1], operands[2]) == CCFPmode
14136    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14137   "#")
14138
14139 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14140 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14141 ;; with a precedence over other operators and is always put in the first
14142 ;; place. Swap condition and operands to match ficom instruction.
14143
14144 (define_insn "*fp_jcc_8<mode>_387"
14145   [(set (pc)
14146         (if_then_else (match_operator 0 "comparison_operator"
14147                         [(match_operator 1 "float_operator"
14148                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14149                            (match_operand 3 "register_operand" "f,f")])
14150           (label_ref (match_operand 4 "" ""))
14151           (pc)))
14152    (clobber (reg:CCFP FPSR_REG))
14153    (clobber (reg:CCFP FLAGS_REG))
14154    (clobber (match_scratch:HI 5 "=a,a"))]
14155   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14156    && FLOAT_MODE_P (GET_MODE (operands[3]))
14157    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14158    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14159    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14160    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14161   "#")
14162
14163 (define_split
14164   [(set (pc)
14165         (if_then_else (match_operator 0 "comparison_operator"
14166                         [(match_operand 1 "register_operand" "")
14167                          (match_operand 2 "nonimmediate_operand" "")])
14168           (match_operand 3 "" "")
14169           (match_operand 4 "" "")))
14170    (clobber (reg:CCFP FPSR_REG))
14171    (clobber (reg:CCFP FLAGS_REG))]
14172   "reload_completed"
14173   [(const_int 0)]
14174 {
14175   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14176                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14177   DONE;
14178 })
14179
14180 (define_split
14181   [(set (pc)
14182         (if_then_else (match_operator 0 "comparison_operator"
14183                         [(match_operand 1 "register_operand" "")
14184                          (match_operand 2 "general_operand" "")])
14185           (match_operand 3 "" "")
14186           (match_operand 4 "" "")))
14187    (clobber (reg:CCFP FPSR_REG))
14188    (clobber (reg:CCFP FLAGS_REG))
14189    (clobber (match_scratch:HI 5 "=a"))]
14190   "reload_completed"
14191   [(const_int 0)]
14192 {
14193   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14194                         operands[3], operands[4], operands[5], NULL_RTX);
14195   DONE;
14196 })
14197
14198 (define_split
14199   [(set (pc)
14200         (if_then_else (match_operator 0 "comparison_operator"
14201                         [(match_operator 1 "float_operator"
14202                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14203                            (match_operand 3 "register_operand" "")])
14204           (match_operand 4 "" "")
14205           (match_operand 5 "" "")))
14206    (clobber (reg:CCFP FPSR_REG))
14207    (clobber (reg:CCFP FLAGS_REG))
14208    (clobber (match_scratch:HI 6 "=a"))]
14209   "reload_completed"
14210   [(const_int 0)]
14211 {
14212   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14213   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214                         operands[3], operands[7],
14215                         operands[4], operands[5], operands[6], NULL_RTX);
14216   DONE;
14217 })
14218
14219 ;; %%% Kill this when reload knows how to do it.
14220 (define_split
14221   [(set (pc)
14222         (if_then_else (match_operator 0 "comparison_operator"
14223                         [(match_operator 1 "float_operator"
14224                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14225                            (match_operand 3 "register_operand" "")])
14226           (match_operand 4 "" "")
14227           (match_operand 5 "" "")))
14228    (clobber (reg:CCFP FPSR_REG))
14229    (clobber (reg:CCFP FLAGS_REG))
14230    (clobber (match_scratch:HI 6 "=a"))]
14231   "reload_completed"
14232   [(const_int 0)]
14233 {
14234   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14235   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14236   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14237                         operands[3], operands[7],
14238                         operands[4], operands[5], operands[6], operands[2]);
14239   DONE;
14240 })
14241 \f
14242 ;; Unconditional and other jump instructions
14243
14244 (define_insn "jump"
14245   [(set (pc)
14246         (label_ref (match_operand 0 "" "")))]
14247   ""
14248   "jmp\t%l0"
14249   [(set_attr "type" "ibr")
14250    (set (attr "length")
14251            (if_then_else (and (ge (minus (match_dup 0) (pc))
14252                                   (const_int -126))
14253                               (lt (minus (match_dup 0) (pc))
14254                                   (const_int 128)))
14255              (const_int 2)
14256              (const_int 5)))
14257    (set_attr "modrm" "0")])
14258
14259 (define_expand "indirect_jump"
14260   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14261   ""
14262   "")
14263
14264 (define_insn "*indirect_jump"
14265   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14266   "!TARGET_64BIT"
14267   "jmp\t%A0"
14268   [(set_attr "type" "ibr")
14269    (set_attr "length_immediate" "0")])
14270
14271 (define_insn "*indirect_jump_rtx64"
14272   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14273   "TARGET_64BIT"
14274   "jmp\t%A0"
14275   [(set_attr "type" "ibr")
14276    (set_attr "length_immediate" "0")])
14277
14278 (define_expand "tablejump"
14279   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14280               (use (label_ref (match_operand 1 "" "")))])]
14281   ""
14282 {
14283   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14284      relative.  Convert the relative address to an absolute address.  */
14285   if (flag_pic)
14286     {
14287       rtx op0, op1;
14288       enum rtx_code code;
14289
14290       if (TARGET_64BIT)
14291         {
14292           code = PLUS;
14293           op0 = operands[0];
14294           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14295         }
14296       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14297         {
14298           code = PLUS;
14299           op0 = operands[0];
14300           op1 = pic_offset_table_rtx;
14301         }
14302       else
14303         {
14304           code = MINUS;
14305           op0 = pic_offset_table_rtx;
14306           op1 = operands[0];
14307         }
14308
14309       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14310                                          OPTAB_DIRECT);
14311     }
14312 })
14313
14314 (define_insn "*tablejump_1"
14315   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14316    (use (label_ref (match_operand 1 "" "")))]
14317   "!TARGET_64BIT"
14318   "jmp\t%A0"
14319   [(set_attr "type" "ibr")
14320    (set_attr "length_immediate" "0")])
14321
14322 (define_insn "*tablejump_1_rtx64"
14323   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14324    (use (label_ref (match_operand 1 "" "")))]
14325   "TARGET_64BIT"
14326   "jmp\t%A0"
14327   [(set_attr "type" "ibr")
14328    (set_attr "length_immediate" "0")])
14329 \f
14330 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14331
14332 (define_peephole2
14333   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334    (set (match_operand:QI 1 "register_operand" "")
14335         (match_operator:QI 2 "ix86_comparison_operator"
14336           [(reg FLAGS_REG) (const_int 0)]))
14337    (set (match_operand 3 "q_regs_operand" "")
14338         (zero_extend (match_dup 1)))]
14339   "(peep2_reg_dead_p (3, operands[1])
14340     || operands_match_p (operands[1], operands[3]))
14341    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14342   [(set (match_dup 4) (match_dup 0))
14343    (set (strict_low_part (match_dup 5))
14344         (match_dup 2))]
14345 {
14346   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14347   operands[5] = gen_lowpart (QImode, operands[3]);
14348   ix86_expand_clear (operands[3]);
14349 })
14350
14351 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14352
14353 (define_peephole2
14354   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14355    (set (match_operand:QI 1 "register_operand" "")
14356         (match_operator:QI 2 "ix86_comparison_operator"
14357           [(reg FLAGS_REG) (const_int 0)]))
14358    (parallel [(set (match_operand 3 "q_regs_operand" "")
14359                    (zero_extend (match_dup 1)))
14360               (clobber (reg:CC FLAGS_REG))])]
14361   "(peep2_reg_dead_p (3, operands[1])
14362     || operands_match_p (operands[1], operands[3]))
14363    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14364   [(set (match_dup 4) (match_dup 0))
14365    (set (strict_low_part (match_dup 5))
14366         (match_dup 2))]
14367 {
14368   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14369   operands[5] = gen_lowpart (QImode, operands[3]);
14370   ix86_expand_clear (operands[3]);
14371 })
14372 \f
14373 ;; Call instructions.
14374
14375 ;; The predicates normally associated with named expanders are not properly
14376 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14377 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14378
14379 ;; Call subroutine returning no value.
14380
14381 (define_expand "call_pop"
14382   [(parallel [(call (match_operand:QI 0 "" "")
14383                     (match_operand:SI 1 "" ""))
14384               (set (reg:SI SP_REG)
14385                    (plus:SI (reg:SI SP_REG)
14386                             (match_operand:SI 3 "" "")))])]
14387   "!TARGET_64BIT"
14388 {
14389   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14390   DONE;
14391 })
14392
14393 (define_insn "*call_pop_0"
14394   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14395          (match_operand:SI 1 "" ""))
14396    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14397                             (match_operand:SI 2 "immediate_operand" "")))]
14398   "!TARGET_64BIT"
14399 {
14400   if (SIBLING_CALL_P (insn))
14401     return "jmp\t%P0";
14402   else
14403     return "call\t%P0";
14404 }
14405   [(set_attr "type" "call")])
14406
14407 (define_insn "*call_pop_1"
14408   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14409          (match_operand:SI 1 "" ""))
14410    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14411                             (match_operand:SI 2 "immediate_operand" "i")))]
14412   "!TARGET_64BIT"
14413 {
14414   if (constant_call_address_operand (operands[0], Pmode))
14415     {
14416       if (SIBLING_CALL_P (insn))
14417         return "jmp\t%P0";
14418       else
14419         return "call\t%P0";
14420     }
14421   if (SIBLING_CALL_P (insn))
14422     return "jmp\t%A0";
14423   else
14424     return "call\t%A0";
14425 }
14426   [(set_attr "type" "call")])
14427
14428 (define_expand "call"
14429   [(call (match_operand:QI 0 "" "")
14430          (match_operand 1 "" ""))
14431    (use (match_operand 2 "" ""))]
14432   ""
14433 {
14434   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14435   DONE;
14436 })
14437
14438 (define_expand "sibcall"
14439   [(call (match_operand:QI 0 "" "")
14440          (match_operand 1 "" ""))
14441    (use (match_operand 2 "" ""))]
14442   ""
14443 {
14444   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14445   DONE;
14446 })
14447
14448 (define_insn "*call_0"
14449   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14450          (match_operand 1 "" ""))]
14451   ""
14452 {
14453   if (SIBLING_CALL_P (insn))
14454     return "jmp\t%P0";
14455   else
14456     return "call\t%P0";
14457 }
14458   [(set_attr "type" "call")])
14459
14460 (define_insn "*call_1"
14461   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14462          (match_operand 1 "" ""))]
14463   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14464 {
14465   if (constant_call_address_operand (operands[0], Pmode))
14466     return "call\t%P0";
14467   return "call\t%A0";
14468 }
14469   [(set_attr "type" "call")])
14470
14471 (define_insn "*sibcall_1"
14472   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14473          (match_operand 1 "" ""))]
14474   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14475 {
14476   if (constant_call_address_operand (operands[0], Pmode))
14477     return "jmp\t%P0";
14478   return "jmp\t%A0";
14479 }
14480   [(set_attr "type" "call")])
14481
14482 (define_insn "*call_1_rex64"
14483   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14484          (match_operand 1 "" ""))]
14485   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14486 {
14487   if (constant_call_address_operand (operands[0], Pmode))
14488     return "call\t%P0";
14489   return "call\t%A0";
14490 }
14491   [(set_attr "type" "call")])
14492
14493 (define_insn "*sibcall_1_rex64"
14494   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14495          (match_operand 1 "" ""))]
14496   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14497   "jmp\t%P0"
14498   [(set_attr "type" "call")])
14499
14500 (define_insn "*sibcall_1_rex64_v"
14501   [(call (mem:QI (reg:DI R11_REG))
14502          (match_operand 0 "" ""))]
14503   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14504   "jmp\t*%%r11"
14505   [(set_attr "type" "call")])
14506
14507
14508 ;; Call subroutine, returning value in operand 0
14509
14510 (define_expand "call_value_pop"
14511   [(parallel [(set (match_operand 0 "" "")
14512                    (call (match_operand:QI 1 "" "")
14513                          (match_operand:SI 2 "" "")))
14514               (set (reg:SI SP_REG)
14515                    (plus:SI (reg:SI SP_REG)
14516                             (match_operand:SI 4 "" "")))])]
14517   "!TARGET_64BIT"
14518 {
14519   ix86_expand_call (operands[0], operands[1], operands[2],
14520                     operands[3], operands[4], 0);
14521   DONE;
14522 })
14523
14524 (define_expand "call_value"
14525   [(set (match_operand 0 "" "")
14526         (call (match_operand:QI 1 "" "")
14527               (match_operand:SI 2 "" "")))
14528    (use (match_operand:SI 3 "" ""))]
14529   ;; Operand 2 not used on the i386.
14530   ""
14531 {
14532   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14533   DONE;
14534 })
14535
14536 (define_expand "sibcall_value"
14537   [(set (match_operand 0 "" "")
14538         (call (match_operand:QI 1 "" "")
14539               (match_operand:SI 2 "" "")))
14540    (use (match_operand:SI 3 "" ""))]
14541   ;; Operand 2 not used on the i386.
14542   ""
14543 {
14544   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14545   DONE;
14546 })
14547
14548 ;; Call subroutine returning any type.
14549
14550 (define_expand "untyped_call"
14551   [(parallel [(call (match_operand 0 "" "")
14552                     (const_int 0))
14553               (match_operand 1 "" "")
14554               (match_operand 2 "" "")])]
14555   ""
14556 {
14557   int i;
14558
14559   /* In order to give reg-stack an easier job in validating two
14560      coprocessor registers as containing a possible return value,
14561      simply pretend the untyped call returns a complex long double
14562      value.  */
14563
14564   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14565                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14566                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14567                     NULL, 0);
14568
14569   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14570     {
14571       rtx set = XVECEXP (operands[2], 0, i);
14572       emit_move_insn (SET_DEST (set), SET_SRC (set));
14573     }
14574
14575   /* The optimizer does not know that the call sets the function value
14576      registers we stored in the result block.  We avoid problems by
14577      claiming that all hard registers are used and clobbered at this
14578      point.  */
14579   emit_insn (gen_blockage (const0_rtx));
14580
14581   DONE;
14582 })
14583 \f
14584 ;; Prologue and epilogue instructions
14585
14586 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14587 ;; all of memory.  This blocks insns from being moved across this point.
14588
14589 (define_insn "blockage"
14590   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14591   ""
14592   ""
14593   [(set_attr "length" "0")])
14594
14595 ;; Insn emitted into the body of a function to return from a function.
14596 ;; This is only done if the function's epilogue is known to be simple.
14597 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14598
14599 (define_expand "return"
14600   [(return)]
14601   "ix86_can_use_return_insn_p ()"
14602 {
14603   if (current_function_pops_args)
14604     {
14605       rtx popc = GEN_INT (current_function_pops_args);
14606       emit_jump_insn (gen_return_pop_internal (popc));
14607       DONE;
14608     }
14609 })
14610
14611 (define_insn "return_internal"
14612   [(return)]
14613   "reload_completed"
14614   "ret"
14615   [(set_attr "length" "1")
14616    (set_attr "length_immediate" "0")
14617    (set_attr "modrm" "0")])
14618
14619 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14620 ;; instruction Athlon and K8 have.
14621
14622 (define_insn "return_internal_long"
14623   [(return)
14624    (unspec [(const_int 0)] UNSPEC_REP)]
14625   "reload_completed"
14626   "rep {;} ret"
14627   [(set_attr "length" "1")
14628    (set_attr "length_immediate" "0")
14629    (set_attr "prefix_rep" "1")
14630    (set_attr "modrm" "0")])
14631
14632 (define_insn "return_pop_internal"
14633   [(return)
14634    (use (match_operand:SI 0 "const_int_operand" ""))]
14635   "reload_completed"
14636   "ret\t%0"
14637   [(set_attr "length" "3")
14638    (set_attr "length_immediate" "2")
14639    (set_attr "modrm" "0")])
14640
14641 (define_insn "return_indirect_internal"
14642   [(return)
14643    (use (match_operand:SI 0 "register_operand" "r"))]
14644   "reload_completed"
14645   "jmp\t%A0"
14646   [(set_attr "type" "ibr")
14647    (set_attr "length_immediate" "0")])
14648
14649 (define_insn "nop"
14650   [(const_int 0)]
14651   ""
14652   "nop"
14653   [(set_attr "length" "1")
14654    (set_attr "length_immediate" "0")
14655    (set_attr "modrm" "0")])
14656
14657 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14658 ;; branch prediction penalty for the third jump in a 16-byte
14659 ;; block on K8.
14660
14661 (define_insn "align"
14662   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14663   ""
14664 {
14665 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14666   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14667 #else
14668   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14669      The align insn is used to avoid 3 jump instructions in the row to improve
14670      branch prediction and the benefits hardly outweigh the cost of extra 8
14671      nops on the average inserted by full alignment pseudo operation.  */
14672 #endif
14673   return "";
14674 }
14675   [(set_attr "length" "16")])
14676
14677 (define_expand "prologue"
14678   [(const_int 1)]
14679   ""
14680   "ix86_expand_prologue (); DONE;")
14681
14682 (define_insn "set_got"
14683   [(set (match_operand:SI 0 "register_operand" "=r")
14684         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14685    (clobber (reg:CC FLAGS_REG))]
14686   "!TARGET_64BIT"
14687   { return output_set_got (operands[0], NULL_RTX); }
14688   [(set_attr "type" "multi")
14689    (set_attr "length" "12")])
14690
14691 (define_insn "set_got_labelled"
14692   [(set (match_operand:SI 0 "register_operand" "=r")
14693         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14694          UNSPEC_SET_GOT))
14695    (clobber (reg:CC FLAGS_REG))]
14696   "!TARGET_64BIT"
14697   { return output_set_got (operands[0], operands[1]); }
14698   [(set_attr "type" "multi")
14699    (set_attr "length" "12")])
14700
14701 (define_insn "set_got_rex64"
14702   [(set (match_operand:DI 0 "register_operand" "=r")
14703         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14704   "TARGET_64BIT"
14705   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14706   [(set_attr "type" "lea")
14707    (set_attr "length" "6")])
14708
14709 (define_expand "epilogue"
14710   [(const_int 1)]
14711   ""
14712   "ix86_expand_epilogue (1); DONE;")
14713
14714 (define_expand "sibcall_epilogue"
14715   [(const_int 1)]
14716   ""
14717   "ix86_expand_epilogue (0); DONE;")
14718
14719 (define_expand "eh_return"
14720   [(use (match_operand 0 "register_operand" ""))]
14721   ""
14722 {
14723   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14724
14725   /* Tricky bit: we write the address of the handler to which we will
14726      be returning into someone else's stack frame, one word below the
14727      stack address we wish to restore.  */
14728   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14729   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14730   tmp = gen_rtx_MEM (Pmode, tmp);
14731   emit_move_insn (tmp, ra);
14732
14733   if (Pmode == SImode)
14734     emit_jump_insn (gen_eh_return_si (sa));
14735   else
14736     emit_jump_insn (gen_eh_return_di (sa));
14737   emit_barrier ();
14738   DONE;
14739 })
14740
14741 (define_insn_and_split "eh_return_si"
14742   [(set (pc)
14743         (unspec [(match_operand:SI 0 "register_operand" "c")]
14744                  UNSPEC_EH_RETURN))]
14745   "!TARGET_64BIT"
14746   "#"
14747   "reload_completed"
14748   [(const_int 1)]
14749   "ix86_expand_epilogue (2); DONE;")
14750
14751 (define_insn_and_split "eh_return_di"
14752   [(set (pc)
14753         (unspec [(match_operand:DI 0 "register_operand" "c")]
14754                  UNSPEC_EH_RETURN))]
14755   "TARGET_64BIT"
14756   "#"
14757   "reload_completed"
14758   [(const_int 1)]
14759   "ix86_expand_epilogue (2); DONE;")
14760
14761 (define_insn "leave"
14762   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14763    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14764    (clobber (mem:BLK (scratch)))]
14765   "!TARGET_64BIT"
14766   "leave"
14767   [(set_attr "type" "leave")])
14768
14769 (define_insn "leave_rex64"
14770   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14771    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14772    (clobber (mem:BLK (scratch)))]
14773   "TARGET_64BIT"
14774   "leave"
14775   [(set_attr "type" "leave")])
14776 \f
14777 (define_expand "ffssi2"
14778   [(parallel
14779      [(set (match_operand:SI 0 "register_operand" "")
14780            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14781       (clobber (match_scratch:SI 2 ""))
14782       (clobber (reg:CC FLAGS_REG))])]
14783   ""
14784   "")
14785
14786 (define_insn_and_split "*ffs_cmove"
14787   [(set (match_operand:SI 0 "register_operand" "=r")
14788         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14789    (clobber (match_scratch:SI 2 "=&r"))
14790    (clobber (reg:CC FLAGS_REG))]
14791   "TARGET_CMOVE"
14792   "#"
14793   "&& reload_completed"
14794   [(set (match_dup 2) (const_int -1))
14795    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14796               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14797    (set (match_dup 0) (if_then_else:SI
14798                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14799                         (match_dup 2)
14800                         (match_dup 0)))
14801    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14802               (clobber (reg:CC FLAGS_REG))])]
14803   "")
14804
14805 (define_insn_and_split "*ffs_no_cmove"
14806   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14807         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14808    (clobber (match_scratch:SI 2 "=&q"))
14809    (clobber (reg:CC FLAGS_REG))]
14810   ""
14811   "#"
14812   "reload_completed"
14813   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14814               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14815    (set (strict_low_part (match_dup 3))
14816         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14817    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14818               (clobber (reg:CC FLAGS_REG))])
14819    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14820               (clobber (reg:CC FLAGS_REG))])
14821    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14822               (clobber (reg:CC FLAGS_REG))])]
14823 {
14824   operands[3] = gen_lowpart (QImode, operands[2]);
14825   ix86_expand_clear (operands[2]);
14826 })
14827
14828 (define_insn "*ffssi_1"
14829   [(set (reg:CCZ FLAGS_REG)
14830         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14831                      (const_int 0)))
14832    (set (match_operand:SI 0 "register_operand" "=r")
14833         (ctz:SI (match_dup 1)))]
14834   ""
14835   "bsf{l}\t{%1, %0|%0, %1}"
14836   [(set_attr "prefix_0f" "1")])
14837
14838 (define_expand "ffsdi2"
14839   [(parallel
14840      [(set (match_operand:DI 0 "register_operand" "")
14841            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14842       (clobber (match_scratch:DI 2 ""))
14843       (clobber (reg:CC FLAGS_REG))])]
14844   "TARGET_64BIT && TARGET_CMOVE"
14845   "")
14846
14847 (define_insn_and_split "*ffs_rex64"
14848   [(set (match_operand:DI 0 "register_operand" "=r")
14849         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14850    (clobber (match_scratch:DI 2 "=&r"))
14851    (clobber (reg:CC FLAGS_REG))]
14852   "TARGET_64BIT && TARGET_CMOVE"
14853   "#"
14854   "&& reload_completed"
14855   [(set (match_dup 2) (const_int -1))
14856    (parallel [(set (reg:CCZ FLAGS_REG)
14857                    (compare:CCZ (match_dup 1) (const_int 0)))
14858               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14859    (set (match_dup 0) (if_then_else:DI
14860                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14861                         (match_dup 2)
14862                         (match_dup 0)))
14863    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14864               (clobber (reg:CC FLAGS_REG))])]
14865   "")
14866
14867 (define_insn "*ffsdi_1"
14868   [(set (reg:CCZ FLAGS_REG)
14869         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14870                      (const_int 0)))
14871    (set (match_operand:DI 0 "register_operand" "=r")
14872         (ctz:DI (match_dup 1)))]
14873   "TARGET_64BIT"
14874   "bsf{q}\t{%1, %0|%0, %1}"
14875   [(set_attr "prefix_0f" "1")])
14876
14877 (define_insn "ctzsi2"
14878   [(set (match_operand:SI 0 "register_operand" "=r")
14879         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14880    (clobber (reg:CC FLAGS_REG))]
14881   ""
14882   "bsf{l}\t{%1, %0|%0, %1}"
14883   [(set_attr "prefix_0f" "1")])
14884
14885 (define_insn "ctzdi2"
14886   [(set (match_operand:DI 0 "register_operand" "=r")
14887         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14888    (clobber (reg:CC FLAGS_REG))]
14889   "TARGET_64BIT"
14890   "bsf{q}\t{%1, %0|%0, %1}"
14891   [(set_attr "prefix_0f" "1")])
14892
14893 (define_expand "clzsi2"
14894   [(parallel
14895      [(set (match_operand:SI 0 "register_operand" "")
14896            (minus:SI (const_int 31)
14897                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14898       (clobber (reg:CC FLAGS_REG))])
14899    (parallel
14900      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14901       (clobber (reg:CC FLAGS_REG))])]
14902   ""
14903 {
14904   if (TARGET_ABM)
14905     {
14906       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14907       DONE;
14908     }
14909 })
14910
14911 (define_insn "clzsi2_abm"
14912   [(set (match_operand:SI 0 "register_operand" "=r")
14913         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14914    (clobber (reg:CC FLAGS_REG))]
14915   "TARGET_ABM"
14916   "lzcnt{l}\t{%1, %0|%0, %1}"
14917   [(set_attr "prefix_rep" "1")
14918    (set_attr "type" "bitmanip")
14919    (set_attr "mode" "SI")])
14920
14921 (define_insn "*bsr"
14922   [(set (match_operand:SI 0 "register_operand" "=r")
14923         (minus:SI (const_int 31)
14924                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14925    (clobber (reg:CC FLAGS_REG))]
14926   ""
14927   "bsr{l}\t{%1, %0|%0, %1}"
14928   [(set_attr "prefix_0f" "1")
14929    (set_attr "mode" "SI")])
14930
14931 (define_insn "popcountsi2"
14932   [(set (match_operand:SI 0 "register_operand" "=r")
14933         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14934    (clobber (reg:CC FLAGS_REG))]
14935   "TARGET_POPCNT"
14936   "popcnt{l}\t{%1, %0|%0, %1}"
14937   [(set_attr "prefix_rep" "1")
14938    (set_attr "type" "bitmanip")
14939    (set_attr "mode" "SI")])
14940
14941 (define_insn "*popcountsi2_cmp"
14942   [(set (reg FLAGS_REG)
14943         (compare
14944           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14945           (const_int 0)))
14946    (set (match_operand:SI 0 "register_operand" "=r")
14947         (popcount:SI (match_dup 1)))]
14948   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14949   "popcnt{l}\t{%1, %0|%0, %1}"
14950   [(set_attr "prefix_rep" "1")
14951    (set_attr "type" "bitmanip")
14952    (set_attr "mode" "SI")])
14953
14954 (define_insn "*popcountsi2_cmp_zext"
14955   [(set (reg FLAGS_REG)
14956         (compare
14957           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14958           (const_int 0)))
14959    (set (match_operand:DI 0 "register_operand" "=r")
14960         (zero_extend:DI(popcount:SI (match_dup 1))))]
14961   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14962   "popcnt{l}\t{%1, %0|%0, %1}"
14963   [(set_attr "prefix_rep" "1")
14964    (set_attr "type" "bitmanip")
14965    (set_attr "mode" "SI")])
14966
14967 (define_insn "bswapsi2"
14968   [(set (match_operand:SI 0 "register_operand" "=r")
14969         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14970    (clobber (reg:CC FLAGS_REG))]
14971   "TARGET_BSWAP"
14972   "bswap\t%k0"
14973   [(set_attr "prefix_0f" "1")
14974    (set_attr "length" "2")])
14975
14976 (define_insn "bswapdi2"
14977   [(set (match_operand:DI 0 "register_operand" "=r")
14978         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14979    (clobber (reg:CC FLAGS_REG))]
14980   "TARGET_64BIT && TARGET_BSWAP"
14981   "bswap\t%0"
14982   [(set_attr "prefix_0f" "1")
14983    (set_attr "length" "3")])
14984
14985 (define_expand "clzdi2"
14986   [(parallel
14987      [(set (match_operand:DI 0 "register_operand" "")
14988            (minus:DI (const_int 63)
14989                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14990       (clobber (reg:CC FLAGS_REG))])
14991    (parallel
14992      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14993       (clobber (reg:CC FLAGS_REG))])]
14994   "TARGET_64BIT"
14995 {
14996   if (TARGET_ABM)
14997     {
14998       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14999       DONE;
15000     }
15001 })
15002
15003 (define_insn "clzdi2_abm"
15004   [(set (match_operand:DI 0 "register_operand" "=r")
15005         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15006    (clobber (reg:CC FLAGS_REG))]
15007   "TARGET_64BIT && TARGET_ABM"
15008   "lzcnt{q}\t{%1, %0|%0, %1}"
15009   [(set_attr "prefix_rep" "1")
15010    (set_attr "type" "bitmanip")
15011    (set_attr "mode" "DI")])
15012
15013 (define_insn "*bsr_rex64"
15014   [(set (match_operand:DI 0 "register_operand" "=r")
15015         (minus:DI (const_int 63)
15016                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15017    (clobber (reg:CC FLAGS_REG))]
15018   "TARGET_64BIT"
15019   "bsr{q}\t{%1, %0|%0, %1}"
15020   [(set_attr "prefix_0f" "1")
15021    (set_attr "mode" "DI")])
15022
15023 (define_insn "popcountdi2"
15024   [(set (match_operand:DI 0 "register_operand" "=r")
15025         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15026    (clobber (reg:CC FLAGS_REG))]
15027   "TARGET_64BIT && TARGET_POPCNT"
15028   "popcnt{q}\t{%1, %0|%0, %1}"
15029   [(set_attr "prefix_rep" "1")
15030    (set_attr "type" "bitmanip")
15031    (set_attr "mode" "DI")])
15032
15033 (define_insn "*popcountdi2_cmp"
15034   [(set (reg FLAGS_REG)
15035         (compare
15036           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15037           (const_int 0)))
15038    (set (match_operand:DI 0 "register_operand" "=r")
15039         (popcount:DI (match_dup 1)))]
15040   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15041   "popcnt{q}\t{%1, %0|%0, %1}"
15042   [(set_attr "prefix_rep" "1")
15043    (set_attr "type" "bitmanip")
15044    (set_attr "mode" "DI")])
15045
15046 (define_expand "clzhi2"
15047   [(parallel
15048      [(set (match_operand:HI 0 "register_operand" "")
15049            (minus:HI (const_int 15)
15050                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15051       (clobber (reg:CC FLAGS_REG))])
15052    (parallel
15053      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15054       (clobber (reg:CC FLAGS_REG))])]
15055   ""
15056 {
15057   if (TARGET_ABM)
15058     {
15059       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15060       DONE;
15061     }
15062 })
15063
15064 (define_insn "clzhi2_abm"
15065   [(set (match_operand:HI 0 "register_operand" "=r")
15066         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15067    (clobber (reg:CC FLAGS_REG))]
15068   "TARGET_ABM"
15069   "lzcnt{w}\t{%1, %0|%0, %1}"
15070   [(set_attr "prefix_rep" "1")
15071    (set_attr "type" "bitmanip")
15072    (set_attr "mode" "HI")])
15073
15074 (define_insn "*bsrhi"
15075   [(set (match_operand:HI 0 "register_operand" "=r")
15076         (minus:HI (const_int 15)
15077                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15078    (clobber (reg:CC FLAGS_REG))]
15079   ""
15080   "bsr{w}\t{%1, %0|%0, %1}"
15081   [(set_attr "prefix_0f" "1")
15082    (set_attr "mode" "HI")])
15083
15084 (define_insn "popcounthi2"
15085   [(set (match_operand:HI 0 "register_operand" "=r")
15086         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15087    (clobber (reg:CC FLAGS_REG))]
15088   "TARGET_POPCNT"
15089   "popcnt{w}\t{%1, %0|%0, %1}"
15090   [(set_attr "prefix_rep" "1")
15091    (set_attr "type" "bitmanip")
15092    (set_attr "mode" "HI")])
15093
15094 (define_insn "*popcounthi2_cmp"
15095   [(set (reg FLAGS_REG)
15096         (compare
15097           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15098           (const_int 0)))
15099    (set (match_operand:HI 0 "register_operand" "=r")
15100         (popcount:HI (match_dup 1)))]
15101   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15102   "popcnt{w}\t{%1, %0|%0, %1}"
15103   [(set_attr "prefix_rep" "1")
15104    (set_attr "type" "bitmanip")
15105    (set_attr "mode" "HI")])
15106 \f
15107 ;; Thread-local storage patterns for ELF.
15108 ;;
15109 ;; Note that these code sequences must appear exactly as shown
15110 ;; in order to allow linker relaxation.
15111
15112 (define_insn "*tls_global_dynamic_32_gnu"
15113   [(set (match_operand:SI 0 "register_operand" "=a")
15114         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15115                     (match_operand:SI 2 "tls_symbolic_operand" "")
15116                     (match_operand:SI 3 "call_insn_operand" "")]
15117                     UNSPEC_TLS_GD))
15118    (clobber (match_scratch:SI 4 "=d"))
15119    (clobber (match_scratch:SI 5 "=c"))
15120    (clobber (reg:CC FLAGS_REG))]
15121   "!TARGET_64BIT && TARGET_GNU_TLS"
15122   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15123   [(set_attr "type" "multi")
15124    (set_attr "length" "12")])
15125
15126 (define_insn "*tls_global_dynamic_32_sun"
15127   [(set (match_operand:SI 0 "register_operand" "=a")
15128         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15129                     (match_operand:SI 2 "tls_symbolic_operand" "")
15130                     (match_operand:SI 3 "call_insn_operand" "")]
15131                     UNSPEC_TLS_GD))
15132    (clobber (match_scratch:SI 4 "=d"))
15133    (clobber (match_scratch:SI 5 "=c"))
15134    (clobber (reg:CC FLAGS_REG))]
15135   "!TARGET_64BIT && TARGET_SUN_TLS"
15136   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15137         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15138   [(set_attr "type" "multi")
15139    (set_attr "length" "14")])
15140
15141 (define_expand "tls_global_dynamic_32"
15142   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15143                    (unspec:SI
15144                     [(match_dup 2)
15145                      (match_operand:SI 1 "tls_symbolic_operand" "")
15146                      (match_dup 3)]
15147                     UNSPEC_TLS_GD))
15148               (clobber (match_scratch:SI 4 ""))
15149               (clobber (match_scratch:SI 5 ""))
15150               (clobber (reg:CC FLAGS_REG))])]
15151   ""
15152 {
15153   if (flag_pic)
15154     operands[2] = pic_offset_table_rtx;
15155   else
15156     {
15157       operands[2] = gen_reg_rtx (Pmode);
15158       emit_insn (gen_set_got (operands[2]));
15159     }
15160   if (TARGET_GNU2_TLS)
15161     {
15162        emit_insn (gen_tls_dynamic_gnu2_32
15163                   (operands[0], operands[1], operands[2]));
15164        DONE;
15165     }
15166   operands[3] = ix86_tls_get_addr ();
15167 })
15168
15169 (define_insn "*tls_global_dynamic_64"
15170   [(set (match_operand:DI 0 "register_operand" "=a")
15171         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15172                  (match_operand:DI 3 "" "")))
15173    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15174               UNSPEC_TLS_GD)]
15175   "TARGET_64BIT"
15176   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15177   [(set_attr "type" "multi")
15178    (set_attr "length" "16")])
15179
15180 (define_expand "tls_global_dynamic_64"
15181   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15182                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15183               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15184                          UNSPEC_TLS_GD)])]
15185   ""
15186 {
15187   if (TARGET_GNU2_TLS)
15188     {
15189        emit_insn (gen_tls_dynamic_gnu2_64
15190                   (operands[0], operands[1]));
15191        DONE;
15192     }
15193   operands[2] = ix86_tls_get_addr ();
15194 })
15195
15196 (define_insn "*tls_local_dynamic_base_32_gnu"
15197   [(set (match_operand:SI 0 "register_operand" "=a")
15198         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15199                     (match_operand:SI 2 "call_insn_operand" "")]
15200                    UNSPEC_TLS_LD_BASE))
15201    (clobber (match_scratch:SI 3 "=d"))
15202    (clobber (match_scratch:SI 4 "=c"))
15203    (clobber (reg:CC FLAGS_REG))]
15204   "!TARGET_64BIT && TARGET_GNU_TLS"
15205   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15206   [(set_attr "type" "multi")
15207    (set_attr "length" "11")])
15208
15209 (define_insn "*tls_local_dynamic_base_32_sun"
15210   [(set (match_operand:SI 0 "register_operand" "=a")
15211         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15212                     (match_operand:SI 2 "call_insn_operand" "")]
15213                    UNSPEC_TLS_LD_BASE))
15214    (clobber (match_scratch:SI 3 "=d"))
15215    (clobber (match_scratch:SI 4 "=c"))
15216    (clobber (reg:CC FLAGS_REG))]
15217   "!TARGET_64BIT && TARGET_SUN_TLS"
15218   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15219         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15220   [(set_attr "type" "multi")
15221    (set_attr "length" "13")])
15222
15223 (define_expand "tls_local_dynamic_base_32"
15224   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15225                    (unspec:SI [(match_dup 1) (match_dup 2)]
15226                               UNSPEC_TLS_LD_BASE))
15227               (clobber (match_scratch:SI 3 ""))
15228               (clobber (match_scratch:SI 4 ""))
15229               (clobber (reg:CC FLAGS_REG))])]
15230   ""
15231 {
15232   if (flag_pic)
15233     operands[1] = pic_offset_table_rtx;
15234   else
15235     {
15236       operands[1] = gen_reg_rtx (Pmode);
15237       emit_insn (gen_set_got (operands[1]));
15238     }
15239   if (TARGET_GNU2_TLS)
15240     {
15241        emit_insn (gen_tls_dynamic_gnu2_32
15242                   (operands[0], ix86_tls_module_base (), operands[1]));
15243        DONE;
15244     }
15245   operands[2] = ix86_tls_get_addr ();
15246 })
15247
15248 (define_insn "*tls_local_dynamic_base_64"
15249   [(set (match_operand:DI 0 "register_operand" "=a")
15250         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15251                  (match_operand:DI 2 "" "")))
15252    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15253   "TARGET_64BIT"
15254   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15255   [(set_attr "type" "multi")
15256    (set_attr "length" "12")])
15257
15258 (define_expand "tls_local_dynamic_base_64"
15259   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15260                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15261               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15262   ""
15263 {
15264   if (TARGET_GNU2_TLS)
15265     {
15266        emit_insn (gen_tls_dynamic_gnu2_64
15267                   (operands[0], ix86_tls_module_base ()));
15268        DONE;
15269     }
15270   operands[1] = ix86_tls_get_addr ();
15271 })
15272
15273 ;; Local dynamic of a single variable is a lose.  Show combine how
15274 ;; to convert that back to global dynamic.
15275
15276 (define_insn_and_split "*tls_local_dynamic_32_once"
15277   [(set (match_operand:SI 0 "register_operand" "=a")
15278         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15279                              (match_operand:SI 2 "call_insn_operand" "")]
15280                             UNSPEC_TLS_LD_BASE)
15281                  (const:SI (unspec:SI
15282                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15283                             UNSPEC_DTPOFF))))
15284    (clobber (match_scratch:SI 4 "=d"))
15285    (clobber (match_scratch:SI 5 "=c"))
15286    (clobber (reg:CC FLAGS_REG))]
15287   ""
15288   "#"
15289   ""
15290   [(parallel [(set (match_dup 0)
15291                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15292                               UNSPEC_TLS_GD))
15293               (clobber (match_dup 4))
15294               (clobber (match_dup 5))
15295               (clobber (reg:CC FLAGS_REG))])]
15296   "")
15297
15298 ;; Load and add the thread base pointer from %gs:0.
15299
15300 (define_insn "*load_tp_si"
15301   [(set (match_operand:SI 0 "register_operand" "=r")
15302         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15303   "!TARGET_64BIT"
15304   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15305   [(set_attr "type" "imov")
15306    (set_attr "modrm" "0")
15307    (set_attr "length" "7")
15308    (set_attr "memory" "load")
15309    (set_attr "imm_disp" "false")])
15310
15311 (define_insn "*add_tp_si"
15312   [(set (match_operand:SI 0 "register_operand" "=r")
15313         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15314                  (match_operand:SI 1 "register_operand" "0")))
15315    (clobber (reg:CC FLAGS_REG))]
15316   "!TARGET_64BIT"
15317   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15318   [(set_attr "type" "alu")
15319    (set_attr "modrm" "0")
15320    (set_attr "length" "7")
15321    (set_attr "memory" "load")
15322    (set_attr "imm_disp" "false")])
15323
15324 (define_insn "*load_tp_di"
15325   [(set (match_operand:DI 0 "register_operand" "=r")
15326         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15327   "TARGET_64BIT"
15328   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15329   [(set_attr "type" "imov")
15330    (set_attr "modrm" "0")
15331    (set_attr "length" "7")
15332    (set_attr "memory" "load")
15333    (set_attr "imm_disp" "false")])
15334
15335 (define_insn "*add_tp_di"
15336   [(set (match_operand:DI 0 "register_operand" "=r")
15337         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15338                  (match_operand:DI 1 "register_operand" "0")))
15339    (clobber (reg:CC FLAGS_REG))]
15340   "TARGET_64BIT"
15341   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15342   [(set_attr "type" "alu")
15343    (set_attr "modrm" "0")
15344    (set_attr "length" "7")
15345    (set_attr "memory" "load")
15346    (set_attr "imm_disp" "false")])
15347
15348 ;; GNU2 TLS patterns can be split.
15349
15350 (define_expand "tls_dynamic_gnu2_32"
15351   [(set (match_dup 3)
15352         (plus:SI (match_operand:SI 2 "register_operand" "")
15353                  (const:SI
15354                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15355                              UNSPEC_TLSDESC))))
15356    (parallel
15357     [(set (match_operand:SI 0 "register_operand" "")
15358           (unspec:SI [(match_dup 1) (match_dup 3)
15359                       (match_dup 2) (reg:SI SP_REG)]
15360                       UNSPEC_TLSDESC))
15361      (clobber (reg:CC FLAGS_REG))])]
15362   "!TARGET_64BIT && TARGET_GNU2_TLS"
15363 {
15364   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15365   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15366 })
15367
15368 (define_insn "*tls_dynamic_lea_32"
15369   [(set (match_operand:SI 0 "register_operand" "=r")
15370         (plus:SI (match_operand:SI 1 "register_operand" "b")
15371                  (const:SI
15372                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15373                               UNSPEC_TLSDESC))))]
15374   "!TARGET_64BIT && TARGET_GNU2_TLS"
15375   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15376   [(set_attr "type" "lea")
15377    (set_attr "mode" "SI")
15378    (set_attr "length" "6")
15379    (set_attr "length_address" "4")])
15380
15381 (define_insn "*tls_dynamic_call_32"
15382   [(set (match_operand:SI 0 "register_operand" "=a")
15383         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15384                     (match_operand:SI 2 "register_operand" "0")
15385                     ;; we have to make sure %ebx still points to the GOT
15386                     (match_operand:SI 3 "register_operand" "b")
15387                     (reg:SI SP_REG)]
15388                    UNSPEC_TLSDESC))
15389    (clobber (reg:CC FLAGS_REG))]
15390   "!TARGET_64BIT && TARGET_GNU2_TLS"
15391   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15392   [(set_attr "type" "call")
15393    (set_attr "length" "2")
15394    (set_attr "length_address" "0")])
15395
15396 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15397   [(set (match_operand:SI 0 "register_operand" "=&a")
15398         (plus:SI
15399          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15400                      (match_operand:SI 4 "" "")
15401                      (match_operand:SI 2 "register_operand" "b")
15402                      (reg:SI SP_REG)]
15403                     UNSPEC_TLSDESC)
15404          (const:SI (unspec:SI
15405                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15406                     UNSPEC_DTPOFF))))
15407    (clobber (reg:CC FLAGS_REG))]
15408   "!TARGET_64BIT && TARGET_GNU2_TLS"
15409   "#"
15410   ""
15411   [(set (match_dup 0) (match_dup 5))]
15412 {
15413   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15414   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15415 })
15416
15417 (define_expand "tls_dynamic_gnu2_64"
15418   [(set (match_dup 2)
15419         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15420                    UNSPEC_TLSDESC))
15421    (parallel
15422     [(set (match_operand:DI 0 "register_operand" "")
15423           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15424                      UNSPEC_TLSDESC))
15425      (clobber (reg:CC FLAGS_REG))])]
15426   "TARGET_64BIT && TARGET_GNU2_TLS"
15427 {
15428   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15429   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15430 })
15431
15432 (define_insn "*tls_dynamic_lea_64"
15433   [(set (match_operand:DI 0 "register_operand" "=r")
15434         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15435                    UNSPEC_TLSDESC))]
15436   "TARGET_64BIT && TARGET_GNU2_TLS"
15437   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15438   [(set_attr "type" "lea")
15439    (set_attr "mode" "DI")
15440    (set_attr "length" "7")
15441    (set_attr "length_address" "4")])
15442
15443 (define_insn "*tls_dynamic_call_64"
15444   [(set (match_operand:DI 0 "register_operand" "=a")
15445         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15446                     (match_operand:DI 2 "register_operand" "0")
15447                     (reg:DI SP_REG)]
15448                    UNSPEC_TLSDESC))
15449    (clobber (reg:CC FLAGS_REG))]
15450   "TARGET_64BIT && TARGET_GNU2_TLS"
15451   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15452   [(set_attr "type" "call")
15453    (set_attr "length" "2")
15454    (set_attr "length_address" "0")])
15455
15456 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15457   [(set (match_operand:DI 0 "register_operand" "=&a")
15458         (plus:DI
15459          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15460                      (match_operand:DI 3 "" "")
15461                      (reg:DI SP_REG)]
15462                     UNSPEC_TLSDESC)
15463          (const:DI (unspec:DI
15464                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15465                     UNSPEC_DTPOFF))))
15466    (clobber (reg:CC FLAGS_REG))]
15467   "TARGET_64BIT && TARGET_GNU2_TLS"
15468   "#"
15469   ""
15470   [(set (match_dup 0) (match_dup 4))]
15471 {
15472   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15473   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15474 })
15475
15476 ;;
15477 \f
15478 ;; These patterns match the binary 387 instructions for addM3, subM3,
15479 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15480 ;; SFmode.  The first is the normal insn, the second the same insn but
15481 ;; with one operand a conversion, and the third the same insn but with
15482 ;; the other operand a conversion.  The conversion may be SFmode or
15483 ;; SImode if the target mode DFmode, but only SImode if the target mode
15484 ;; is SFmode.
15485
15486 ;; Gcc is slightly more smart about handling normal two address instructions
15487 ;; so use special patterns for add and mull.
15488
15489 (define_insn "*fop_sf_comm_mixed"
15490   [(set (match_operand:SF 0 "register_operand" "=f,x")
15491         (match_operator:SF 3 "binary_fp_operator"
15492                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15493                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15494   "TARGET_MIX_SSE_I387
15495    && COMMUTATIVE_ARITH_P (operands[3])
15496    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15497   "* return output_387_binary_op (insn, operands);"
15498   [(set (attr "type")
15499         (if_then_else (eq_attr "alternative" "1")
15500            (if_then_else (match_operand:SF 3 "mult_operator" "")
15501               (const_string "ssemul")
15502               (const_string "sseadd"))
15503            (if_then_else (match_operand:SF 3 "mult_operator" "")
15504               (const_string "fmul")
15505               (const_string "fop"))))
15506    (set_attr "mode" "SF")])
15507
15508 (define_insn "*fop_sf_comm_sse"
15509   [(set (match_operand:SF 0 "register_operand" "=x")
15510         (match_operator:SF 3 "binary_fp_operator"
15511                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15512                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15513   "TARGET_SSE_MATH
15514    && COMMUTATIVE_ARITH_P (operands[3])
15515    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15516   "* return output_387_binary_op (insn, operands);"
15517   [(set (attr "type")
15518         (if_then_else (match_operand:SF 3 "mult_operator" "")
15519            (const_string "ssemul")
15520            (const_string "sseadd")))
15521    (set_attr "mode" "SF")])
15522
15523 (define_insn "*fop_sf_comm_i387"
15524   [(set (match_operand:SF 0 "register_operand" "=f")
15525         (match_operator:SF 3 "binary_fp_operator"
15526                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15527                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15528   "TARGET_80387
15529    && COMMUTATIVE_ARITH_P (operands[3])
15530    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15531   "* return output_387_binary_op (insn, operands);"
15532   [(set (attr "type")
15533         (if_then_else (match_operand:SF 3 "mult_operator" "")
15534            (const_string "fmul")
15535            (const_string "fop")))
15536    (set_attr "mode" "SF")])
15537
15538 (define_insn "*fop_sf_1_mixed"
15539   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15540         (match_operator:SF 3 "binary_fp_operator"
15541                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15542                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15543   "TARGET_MIX_SSE_I387
15544    && !COMMUTATIVE_ARITH_P (operands[3])
15545    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15546   "* return output_387_binary_op (insn, operands);"
15547   [(set (attr "type")
15548         (cond [(and (eq_attr "alternative" "2")
15549                     (match_operand:SF 3 "mult_operator" ""))
15550                  (const_string "ssemul")
15551                (and (eq_attr "alternative" "2")
15552                     (match_operand:SF 3 "div_operator" ""))
15553                  (const_string "ssediv")
15554                (eq_attr "alternative" "2")
15555                  (const_string "sseadd")
15556                (match_operand:SF 3 "mult_operator" "")
15557                  (const_string "fmul")
15558                (match_operand:SF 3 "div_operator" "")
15559                  (const_string "fdiv")
15560               ]
15561               (const_string "fop")))
15562    (set_attr "mode" "SF")])
15563
15564 (define_insn "*fop_sf_1_sse"
15565   [(set (match_operand:SF 0 "register_operand" "=x")
15566         (match_operator:SF 3 "binary_fp_operator"
15567                         [(match_operand:SF 1 "register_operand" "0")
15568                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15569   "TARGET_SSE_MATH
15570    && !COMMUTATIVE_ARITH_P (operands[3])"
15571   "* return output_387_binary_op (insn, operands);"
15572   [(set (attr "type")
15573         (cond [(match_operand:SF 3 "mult_operator" "")
15574                  (const_string "ssemul")
15575                (match_operand:SF 3 "div_operator" "")
15576                  (const_string "ssediv")
15577               ]
15578               (const_string "sseadd")))
15579    (set_attr "mode" "SF")])
15580
15581 ;; This pattern is not fully shadowed by the pattern above.
15582 (define_insn "*fop_sf_1_i387"
15583   [(set (match_operand:SF 0 "register_operand" "=f,f")
15584         (match_operator:SF 3 "binary_fp_operator"
15585                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15586                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15587   "TARGET_80387 && !TARGET_SSE_MATH
15588    && !COMMUTATIVE_ARITH_P (operands[3])
15589    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15590   "* return output_387_binary_op (insn, operands);"
15591   [(set (attr "type")
15592         (cond [(match_operand:SF 3 "mult_operator" "")
15593                  (const_string "fmul")
15594                (match_operand:SF 3 "div_operator" "")
15595                  (const_string "fdiv")
15596               ]
15597               (const_string "fop")))
15598    (set_attr "mode" "SF")])
15599
15600 ;; ??? Add SSE splitters for these!
15601 (define_insn "*fop_sf_2<mode>_i387"
15602   [(set (match_operand:SF 0 "register_operand" "=f,f")
15603         (match_operator:SF 3 "binary_fp_operator"
15604           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15605            (match_operand:SF 2 "register_operand" "0,0")]))]
15606   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15607   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15608   [(set (attr "type")
15609         (cond [(match_operand:SF 3 "mult_operator" "")
15610                  (const_string "fmul")
15611                (match_operand:SF 3 "div_operator" "")
15612                  (const_string "fdiv")
15613               ]
15614               (const_string "fop")))
15615    (set_attr "fp_int_src" "true")
15616    (set_attr "mode" "<MODE>")])
15617
15618 (define_insn "*fop_sf_3<mode>_i387"
15619   [(set (match_operand:SF 0 "register_operand" "=f,f")
15620         (match_operator:SF 3 "binary_fp_operator"
15621           [(match_operand:SF 1 "register_operand" "0,0")
15622            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15623   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15624   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15625   [(set (attr "type")
15626         (cond [(match_operand:SF 3 "mult_operator" "")
15627                  (const_string "fmul")
15628                (match_operand:SF 3 "div_operator" "")
15629                  (const_string "fdiv")
15630               ]
15631               (const_string "fop")))
15632    (set_attr "fp_int_src" "true")
15633    (set_attr "mode" "<MODE>")])
15634
15635 (define_insn "*fop_df_comm_mixed"
15636   [(set (match_operand:DF 0 "register_operand" "=f,x")
15637         (match_operator:DF 3 "binary_fp_operator"
15638           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15639            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15640   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15641    && COMMUTATIVE_ARITH_P (operands[3])
15642    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15643   "* return output_387_binary_op (insn, operands);"
15644   [(set (attr "type")
15645         (if_then_else (eq_attr "alternative" "1")
15646            (if_then_else (match_operand:DF 3 "mult_operator" "")
15647               (const_string "ssemul")
15648               (const_string "sseadd"))
15649            (if_then_else (match_operand:DF 3 "mult_operator" "")
15650               (const_string "fmul")
15651               (const_string "fop"))))
15652    (set_attr "mode" "DF")])
15653
15654 (define_insn "*fop_df_comm_sse"
15655   [(set (match_operand:DF 0 "register_operand" "=x")
15656         (match_operator:DF 3 "binary_fp_operator"
15657           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15658            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15659   "TARGET_SSE2 && TARGET_SSE_MATH
15660    && COMMUTATIVE_ARITH_P (operands[3])
15661    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15662   "* return output_387_binary_op (insn, operands);"
15663   [(set (attr "type")
15664         (if_then_else (match_operand:DF 3 "mult_operator" "")
15665            (const_string "ssemul")
15666            (const_string "sseadd")))
15667    (set_attr "mode" "DF")])
15668
15669 (define_insn "*fop_df_comm_i387"
15670   [(set (match_operand:DF 0 "register_operand" "=f")
15671         (match_operator:DF 3 "binary_fp_operator"
15672                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15673                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15674   "TARGET_80387
15675    && COMMUTATIVE_ARITH_P (operands[3])
15676    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15677   "* return output_387_binary_op (insn, operands);"
15678   [(set (attr "type")
15679         (if_then_else (match_operand:DF 3 "mult_operator" "")
15680            (const_string "fmul")
15681            (const_string "fop")))
15682    (set_attr "mode" "DF")])
15683
15684 (define_insn "*fop_df_1_mixed"
15685   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15686         (match_operator:DF 3 "binary_fp_operator"
15687           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15688            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15689   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15690    && !COMMUTATIVE_ARITH_P (operands[3])
15691    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15692   "* return output_387_binary_op (insn, operands);"
15693   [(set (attr "type")
15694         (cond [(and (eq_attr "alternative" "2")
15695                     (match_operand:DF 3 "mult_operator" ""))
15696                  (const_string "ssemul")
15697                (and (eq_attr "alternative" "2")
15698                     (match_operand:DF 3 "div_operator" ""))
15699                  (const_string "ssediv")
15700                (eq_attr "alternative" "2")
15701                  (const_string "sseadd")
15702                (match_operand:DF 3 "mult_operator" "")
15703                  (const_string "fmul")
15704                (match_operand:DF 3 "div_operator" "")
15705                  (const_string "fdiv")
15706               ]
15707               (const_string "fop")))
15708    (set_attr "mode" "DF")])
15709
15710 (define_insn "*fop_df_1_sse"
15711   [(set (match_operand:DF 0 "register_operand" "=x")
15712         (match_operator:DF 3 "binary_fp_operator"
15713           [(match_operand:DF 1 "register_operand" "0")
15714            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15715   "TARGET_SSE2 && TARGET_SSE_MATH
15716    && !COMMUTATIVE_ARITH_P (operands[3])"
15717   "* return output_387_binary_op (insn, operands);"
15718   [(set_attr "mode" "DF")
15719    (set (attr "type")
15720         (cond [(match_operand:DF 3 "mult_operator" "")
15721                  (const_string "ssemul")
15722                (match_operand:DF 3 "div_operator" "")
15723                  (const_string "ssediv")
15724               ]
15725               (const_string "sseadd")))])
15726
15727 ;; This pattern is not fully shadowed by the pattern above.
15728 (define_insn "*fop_df_1_i387"
15729   [(set (match_operand:DF 0 "register_operand" "=f,f")
15730         (match_operator:DF 3 "binary_fp_operator"
15731                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15732                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15733   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15734    && !COMMUTATIVE_ARITH_P (operands[3])
15735    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15736   "* return output_387_binary_op (insn, operands);"
15737   [(set (attr "type")
15738         (cond [(match_operand:DF 3 "mult_operator" "")
15739                  (const_string "fmul")
15740                (match_operand:DF 3 "div_operator" "")
15741                  (const_string "fdiv")
15742               ]
15743               (const_string "fop")))
15744    (set_attr "mode" "DF")])
15745
15746 ;; ??? Add SSE splitters for these!
15747 (define_insn "*fop_df_2<mode>_i387"
15748   [(set (match_operand:DF 0 "register_operand" "=f,f")
15749         (match_operator:DF 3 "binary_fp_operator"
15750            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15751             (match_operand:DF 2 "register_operand" "0,0")]))]
15752   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15753    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15754   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15755   [(set (attr "type")
15756         (cond [(match_operand:DF 3 "mult_operator" "")
15757                  (const_string "fmul")
15758                (match_operand:DF 3 "div_operator" "")
15759                  (const_string "fdiv")
15760               ]
15761               (const_string "fop")))
15762    (set_attr "fp_int_src" "true")
15763    (set_attr "mode" "<MODE>")])
15764
15765 (define_insn "*fop_df_3<mode>_i387"
15766   [(set (match_operand:DF 0 "register_operand" "=f,f")
15767         (match_operator:DF 3 "binary_fp_operator"
15768            [(match_operand:DF 1 "register_operand" "0,0")
15769             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15770   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15771    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15772   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15773   [(set (attr "type")
15774         (cond [(match_operand:DF 3 "mult_operator" "")
15775                  (const_string "fmul")
15776                (match_operand:DF 3 "div_operator" "")
15777                  (const_string "fdiv")
15778               ]
15779               (const_string "fop")))
15780    (set_attr "fp_int_src" "true")
15781    (set_attr "mode" "<MODE>")])
15782
15783 (define_insn "*fop_df_4_i387"
15784   [(set (match_operand:DF 0 "register_operand" "=f,f")
15785         (match_operator:DF 3 "binary_fp_operator"
15786            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15787             (match_operand:DF 2 "register_operand" "0,f")]))]
15788   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15789    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15790   "* return output_387_binary_op (insn, operands);"
15791   [(set (attr "type")
15792         (cond [(match_operand:DF 3 "mult_operator" "")
15793                  (const_string "fmul")
15794                (match_operand:DF 3 "div_operator" "")
15795                  (const_string "fdiv")
15796               ]
15797               (const_string "fop")))
15798    (set_attr "mode" "SF")])
15799
15800 (define_insn "*fop_df_5_i387"
15801   [(set (match_operand:DF 0 "register_operand" "=f,f")
15802         (match_operator:DF 3 "binary_fp_operator"
15803           [(match_operand:DF 1 "register_operand" "0,f")
15804            (float_extend:DF
15805             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15806   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15807   "* return output_387_binary_op (insn, operands);"
15808   [(set (attr "type")
15809         (cond [(match_operand:DF 3 "mult_operator" "")
15810                  (const_string "fmul")
15811                (match_operand:DF 3 "div_operator" "")
15812                  (const_string "fdiv")
15813               ]
15814               (const_string "fop")))
15815    (set_attr "mode" "SF")])
15816
15817 (define_insn "*fop_df_6_i387"
15818   [(set (match_operand:DF 0 "register_operand" "=f,f")
15819         (match_operator:DF 3 "binary_fp_operator"
15820           [(float_extend:DF
15821             (match_operand:SF 1 "register_operand" "0,f"))
15822            (float_extend:DF
15823             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15824   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15825   "* return output_387_binary_op (insn, operands);"
15826   [(set (attr "type")
15827         (cond [(match_operand:DF 3 "mult_operator" "")
15828                  (const_string "fmul")
15829                (match_operand:DF 3 "div_operator" "")
15830                  (const_string "fdiv")
15831               ]
15832               (const_string "fop")))
15833    (set_attr "mode" "SF")])
15834
15835 (define_insn "*fop_xf_comm_i387"
15836   [(set (match_operand:XF 0 "register_operand" "=f")
15837         (match_operator:XF 3 "binary_fp_operator"
15838                         [(match_operand:XF 1 "register_operand" "%0")
15839                          (match_operand:XF 2 "register_operand" "f")]))]
15840   "TARGET_80387
15841    && COMMUTATIVE_ARITH_P (operands[3])"
15842   "* return output_387_binary_op (insn, operands);"
15843   [(set (attr "type")
15844         (if_then_else (match_operand:XF 3 "mult_operator" "")
15845            (const_string "fmul")
15846            (const_string "fop")))
15847    (set_attr "mode" "XF")])
15848
15849 (define_insn "*fop_xf_1_i387"
15850   [(set (match_operand:XF 0 "register_operand" "=f,f")
15851         (match_operator:XF 3 "binary_fp_operator"
15852                         [(match_operand:XF 1 "register_operand" "0,f")
15853                          (match_operand:XF 2 "register_operand" "f,0")]))]
15854   "TARGET_80387
15855    && !COMMUTATIVE_ARITH_P (operands[3])"
15856   "* return output_387_binary_op (insn, operands);"
15857   [(set (attr "type")
15858         (cond [(match_operand:XF 3 "mult_operator" "")
15859                  (const_string "fmul")
15860                (match_operand:XF 3 "div_operator" "")
15861                  (const_string "fdiv")
15862               ]
15863               (const_string "fop")))
15864    (set_attr "mode" "XF")])
15865
15866 (define_insn "*fop_xf_2<mode>_i387"
15867   [(set (match_operand:XF 0 "register_operand" "=f,f")
15868         (match_operator:XF 3 "binary_fp_operator"
15869            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15870             (match_operand:XF 2 "register_operand" "0,0")]))]
15871   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15872   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15873   [(set (attr "type")
15874         (cond [(match_operand:XF 3 "mult_operator" "")
15875                  (const_string "fmul")
15876                (match_operand:XF 3 "div_operator" "")
15877                  (const_string "fdiv")
15878               ]
15879               (const_string "fop")))
15880    (set_attr "fp_int_src" "true")
15881    (set_attr "mode" "<MODE>")])
15882
15883 (define_insn "*fop_xf_3<mode>_i387"
15884   [(set (match_operand:XF 0 "register_operand" "=f,f")
15885         (match_operator:XF 3 "binary_fp_operator"
15886           [(match_operand:XF 1 "register_operand" "0,0")
15887            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15888   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15889   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15890   [(set (attr "type")
15891         (cond [(match_operand:XF 3 "mult_operator" "")
15892                  (const_string "fmul")
15893                (match_operand:XF 3 "div_operator" "")
15894                  (const_string "fdiv")
15895               ]
15896               (const_string "fop")))
15897    (set_attr "fp_int_src" "true")
15898    (set_attr "mode" "<MODE>")])
15899
15900 (define_insn "*fop_xf_4_i387"
15901   [(set (match_operand:XF 0 "register_operand" "=f,f")
15902         (match_operator:XF 3 "binary_fp_operator"
15903            [(float_extend:XF
15904               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15905             (match_operand:XF 2 "register_operand" "0,f")]))]
15906   "TARGET_80387"
15907   "* return output_387_binary_op (insn, operands);"
15908   [(set (attr "type")
15909         (cond [(match_operand:XF 3 "mult_operator" "")
15910                  (const_string "fmul")
15911                (match_operand:XF 3 "div_operator" "")
15912                  (const_string "fdiv")
15913               ]
15914               (const_string "fop")))
15915    (set_attr "mode" "SF")])
15916
15917 (define_insn "*fop_xf_5_i387"
15918   [(set (match_operand:XF 0 "register_operand" "=f,f")
15919         (match_operator:XF 3 "binary_fp_operator"
15920           [(match_operand:XF 1 "register_operand" "0,f")
15921            (float_extend:XF
15922              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15923   "TARGET_80387"
15924   "* return output_387_binary_op (insn, operands);"
15925   [(set (attr "type")
15926         (cond [(match_operand:XF 3 "mult_operator" "")
15927                  (const_string "fmul")
15928                (match_operand:XF 3 "div_operator" "")
15929                  (const_string "fdiv")
15930               ]
15931               (const_string "fop")))
15932    (set_attr "mode" "SF")])
15933
15934 (define_insn "*fop_xf_6_i387"
15935   [(set (match_operand:XF 0 "register_operand" "=f,f")
15936         (match_operator:XF 3 "binary_fp_operator"
15937           [(float_extend:XF
15938              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15939            (float_extend:XF
15940              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15941   "TARGET_80387"
15942   "* return output_387_binary_op (insn, operands);"
15943   [(set (attr "type")
15944         (cond [(match_operand:XF 3 "mult_operator" "")
15945                  (const_string "fmul")
15946                (match_operand:XF 3 "div_operator" "")
15947                  (const_string "fdiv")
15948               ]
15949               (const_string "fop")))
15950    (set_attr "mode" "SF")])
15951
15952 (define_split
15953   [(set (match_operand 0 "register_operand" "")
15954         (match_operator 3 "binary_fp_operator"
15955            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15956             (match_operand 2 "register_operand" "")]))]
15957   "TARGET_80387 && reload_completed
15958    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15959   [(const_int 0)]
15960 {
15961   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15962   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15963   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15964                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15965                                           GET_MODE (operands[3]),
15966                                           operands[4],
15967                                           operands[2])));
15968   ix86_free_from_memory (GET_MODE (operands[1]));
15969   DONE;
15970 })
15971
15972 (define_split
15973   [(set (match_operand 0 "register_operand" "")
15974         (match_operator 3 "binary_fp_operator"
15975            [(match_operand 1 "register_operand" "")
15976             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15977   "TARGET_80387 && reload_completed
15978    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15979   [(const_int 0)]
15980 {
15981   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15982   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15983   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15984                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15985                                           GET_MODE (operands[3]),
15986                                           operands[1],
15987                                           operands[4])));
15988   ix86_free_from_memory (GET_MODE (operands[2]));
15989   DONE;
15990 })
15991 \f
15992 ;; FPU special functions.
15993
15994 ;; This pattern implements a no-op XFmode truncation for
15995 ;; all fancy i386 XFmode math functions.
15996
15997 (define_insn "truncxf<mode>2_i387_noop_unspec"
15998   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15999         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16000         UNSPEC_TRUNC_NOOP))]
16001   "TARGET_USE_FANCY_MATH_387"
16002   "* return output_387_reg_move (insn, operands);"
16003   [(set_attr "type" "fmov")
16004    (set_attr "mode" "<MODE>")])
16005
16006 (define_insn "sqrtxf2"
16007   [(set (match_operand:XF 0 "register_operand" "=f")
16008         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16009   "TARGET_USE_FANCY_MATH_387"
16010   "fsqrt"
16011   [(set_attr "type" "fpspc")
16012    (set_attr "mode" "XF")
16013    (set_attr "athlon_decode" "direct")
16014    (set_attr "amdfam10_decode" "direct")])
16015
16016 (define_insn "sqrt_extend<mode>xf2_i387"
16017   [(set (match_operand:XF 0 "register_operand" "=f")
16018         (sqrt:XF
16019           (float_extend:XF
16020             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16021   "TARGET_USE_FANCY_MATH_387"
16022   "fsqrt"
16023   [(set_attr "type" "fpspc")
16024    (set_attr "mode" "XF")
16025    (set_attr "athlon_decode" "direct")   
16026    (set_attr "amdfam10_decode" "direct")])
16027
16028 (define_insn "*sqrt<mode>2_sse"
16029   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16030         (sqrt:SSEMODEF
16031           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16032   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16033   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16034   [(set_attr "type" "sse")
16035    (set_attr "mode" "<MODE>")
16036    (set_attr "athlon_decode" "*")
16037    (set_attr "amdfam10_decode" "*")])
16038
16039 (define_expand "sqrt<mode>2"
16040   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16041         (sqrt:X87MODEF12
16042           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16043   "TARGET_USE_FANCY_MATH_387
16044    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16045 {
16046   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16047     {
16048       rtx op0 = gen_reg_rtx (XFmode);
16049       rtx op1 = force_reg (<MODE>mode, operands[1]);
16050
16051       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16052       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16053       DONE;
16054    }
16055 })
16056
16057 (define_insn "fpremxf4_i387"
16058   [(set (match_operand:XF 0 "register_operand" "=f")
16059         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16060                     (match_operand:XF 3 "register_operand" "1")]
16061                    UNSPEC_FPREM_F))
16062    (set (match_operand:XF 1 "register_operand" "=u")
16063         (unspec:XF [(match_dup 2) (match_dup 3)]
16064                    UNSPEC_FPREM_U))
16065    (set (reg:CCFP FPSR_REG)
16066         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16067   "TARGET_USE_FANCY_MATH_387"
16068   "fprem"
16069   [(set_attr "type" "fpspc")
16070    (set_attr "mode" "XF")])
16071
16072 (define_expand "fmodxf3"
16073   [(use (match_operand:XF 0 "register_operand" ""))
16074    (use (match_operand:XF 1 "register_operand" ""))
16075    (use (match_operand:XF 2 "register_operand" ""))]
16076   "TARGET_USE_FANCY_MATH_387"
16077 {
16078   rtx label = gen_label_rtx ();
16079
16080   emit_label (label);
16081
16082   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16083                                 operands[1], operands[2]));
16084   ix86_emit_fp_unordered_jump (label);
16085
16086   emit_move_insn (operands[0], operands[1]);
16087   DONE;
16088 })
16089
16090 (define_expand "fmod<mode>3"
16091   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16092    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16093    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16094   "TARGET_USE_FANCY_MATH_387"
16095 {
16096   rtx label = gen_label_rtx ();
16097
16098   rtx op1 = gen_reg_rtx (XFmode);
16099   rtx op2 = gen_reg_rtx (XFmode);
16100
16101   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16102   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16103
16104   emit_label (label);
16105   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16106   ix86_emit_fp_unordered_jump (label);
16107
16108   /* Truncate the result properly for strict SSE math.  */
16109   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16110       && !TARGET_MIX_SSE_I387)
16111     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16112   else
16113     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16114
16115   DONE;
16116 })
16117
16118 (define_insn "fprem1xf4_i387"
16119   [(set (match_operand:XF 0 "register_operand" "=f")
16120         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16121                     (match_operand:XF 3 "register_operand" "1")]
16122                    UNSPEC_FPREM1_F))
16123    (set (match_operand:XF 1 "register_operand" "=u")
16124         (unspec:XF [(match_dup 2) (match_dup 3)]
16125                    UNSPEC_FPREM1_U))
16126    (set (reg:CCFP FPSR_REG)
16127         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16128   "TARGET_USE_FANCY_MATH_387"
16129   "fprem1"
16130   [(set_attr "type" "fpspc")
16131    (set_attr "mode" "XF")])
16132
16133 (define_expand "remainderxf3"
16134   [(use (match_operand:XF 0 "register_operand" ""))
16135    (use (match_operand:XF 1 "register_operand" ""))
16136    (use (match_operand:XF 2 "register_operand" ""))]
16137   "TARGET_USE_FANCY_MATH_387"
16138 {
16139   rtx label = gen_label_rtx ();
16140
16141   emit_label (label);
16142
16143   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16144                                  operands[1], operands[2]));
16145   ix86_emit_fp_unordered_jump (label);
16146
16147   emit_move_insn (operands[0], operands[1]);
16148   DONE;
16149 })
16150
16151 (define_expand "remainder<mode>3"
16152   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16153    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16154    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16155   "TARGET_USE_FANCY_MATH_387"
16156 {
16157   rtx label = gen_label_rtx ();
16158
16159   rtx op1 = gen_reg_rtx (XFmode);
16160   rtx op2 = gen_reg_rtx (XFmode);
16161
16162   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16163   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16164
16165   emit_label (label);
16166
16167   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16168   ix86_emit_fp_unordered_jump (label);
16169
16170   /* Truncate the result properly for strict SSE math.  */
16171   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16172       && !TARGET_MIX_SSE_I387)
16173     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16174   else
16175     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16176
16177   DONE;
16178 })
16179
16180 (define_insn "*sinxf2_i387"
16181   [(set (match_operand:XF 0 "register_operand" "=f")
16182         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16185   "fsin"
16186   [(set_attr "type" "fpspc")
16187    (set_attr "mode" "XF")])
16188
16189 (define_insn "*sin_extend<mode>xf2_i387"
16190   [(set (match_operand:XF 0 "register_operand" "=f")
16191         (unspec:XF [(float_extend:XF
16192                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16193                    UNSPEC_SIN))]
16194   "TARGET_USE_FANCY_MATH_387
16195    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16196        || TARGET_MIX_SSE_I387)
16197    && flag_unsafe_math_optimizations"
16198   "fsin"
16199   [(set_attr "type" "fpspc")
16200    (set_attr "mode" "XF")])
16201
16202 (define_insn "*cosxf2_i387"
16203   [(set (match_operand:XF 0 "register_operand" "=f")
16204         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16205   "TARGET_USE_FANCY_MATH_387
16206    && flag_unsafe_math_optimizations"
16207   "fcos"
16208   [(set_attr "type" "fpspc")
16209    (set_attr "mode" "XF")])
16210
16211 (define_insn "*cos_extend<mode>xf2_i387"
16212   [(set (match_operand:XF 0 "register_operand" "=f")
16213         (unspec:XF [(float_extend:XF
16214                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16215                    UNSPEC_COS))]
16216   "TARGET_USE_FANCY_MATH_387
16217    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16218        || TARGET_MIX_SSE_I387)
16219    && flag_unsafe_math_optimizations"
16220   "fcos"
16221   [(set_attr "type" "fpspc")
16222    (set_attr "mode" "XF")])
16223
16224 ;; When sincos pattern is defined, sin and cos builtin functions will be
16225 ;; expanded to sincos pattern with one of its outputs left unused.
16226 ;; CSE pass will figure out if two sincos patterns can be combined,
16227 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16228 ;; depending on the unused output.
16229
16230 (define_insn "sincosxf3"
16231   [(set (match_operand:XF 0 "register_operand" "=f")
16232         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16233                    UNSPEC_SINCOS_COS))
16234    (set (match_operand:XF 1 "register_operand" "=u")
16235         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16236   "TARGET_USE_FANCY_MATH_387
16237    && flag_unsafe_math_optimizations"
16238   "fsincos"
16239   [(set_attr "type" "fpspc")
16240    (set_attr "mode" "XF")])
16241
16242 (define_split
16243   [(set (match_operand:XF 0 "register_operand" "")
16244         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16245                    UNSPEC_SINCOS_COS))
16246    (set (match_operand:XF 1 "register_operand" "")
16247         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16248   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16249    && !reload_completed && !reload_in_progress"
16250   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16251   "")
16252
16253 (define_split
16254   [(set (match_operand:XF 0 "register_operand" "")
16255         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16256                    UNSPEC_SINCOS_COS))
16257    (set (match_operand:XF 1 "register_operand" "")
16258         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16259   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16260    && !reload_completed && !reload_in_progress"
16261   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16262   "")
16263
16264 (define_insn "sincos_extend<mode>xf3_i387"
16265   [(set (match_operand:XF 0 "register_operand" "=f")
16266         (unspec:XF [(float_extend:XF
16267                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16268                    UNSPEC_SINCOS_COS))
16269    (set (match_operand:XF 1 "register_operand" "=u")
16270         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16271   "TARGET_USE_FANCY_MATH_387
16272    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16273        || TARGET_MIX_SSE_I387)
16274    && flag_unsafe_math_optimizations"
16275   "fsincos"
16276   [(set_attr "type" "fpspc")
16277    (set_attr "mode" "XF")])
16278
16279 (define_split
16280   [(set (match_operand:XF 0 "register_operand" "")
16281         (unspec:XF [(float_extend:XF
16282                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16283                    UNSPEC_SINCOS_COS))
16284    (set (match_operand:XF 1 "register_operand" "")
16285         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16286   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16287    && !reload_completed && !reload_in_progress"
16288   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16289   "")
16290
16291 (define_split
16292   [(set (match_operand:XF 0 "register_operand" "")
16293         (unspec:XF [(float_extend:XF
16294                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16295                    UNSPEC_SINCOS_COS))
16296    (set (match_operand:XF 1 "register_operand" "")
16297         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16298   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16299    && !reload_completed && !reload_in_progress"
16300   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16301   "")
16302
16303 (define_expand "sincos<mode>3"
16304   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16305    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16306    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16309        || TARGET_MIX_SSE_I387)
16310    && flag_unsafe_math_optimizations"
16311 {
16312   rtx op0 = gen_reg_rtx (XFmode);
16313   rtx op1 = gen_reg_rtx (XFmode);
16314
16315   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16316   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16317   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16318   DONE;
16319 })
16320
16321 (define_insn "fptanxf4_i387"
16322   [(set (match_operand:XF 0 "register_operand" "=f")
16323         (match_operand:XF 3 "const_double_operand" "F"))
16324    (set (match_operand:XF 1 "register_operand" "=u")
16325         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16326                    UNSPEC_TAN))]
16327   "TARGET_USE_FANCY_MATH_387
16328    && flag_unsafe_math_optimizations
16329    && standard_80387_constant_p (operands[3]) == 2"
16330   "fptan"
16331   [(set_attr "type" "fpspc")
16332    (set_attr "mode" "XF")])
16333
16334 (define_insn "fptan_extend<mode>xf4_i387"
16335   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16336         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16337    (set (match_operand:XF 1 "register_operand" "=u")
16338         (unspec:XF [(float_extend:XF
16339                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16340                    UNSPEC_TAN))]
16341   "TARGET_USE_FANCY_MATH_387
16342    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16343        || TARGET_MIX_SSE_I387)
16344    && flag_unsafe_math_optimizations
16345    && standard_80387_constant_p (operands[3]) == 2"
16346   "fptan"
16347   [(set_attr "type" "fpspc")
16348    (set_attr "mode" "XF")])
16349
16350 (define_expand "tanxf2"
16351   [(use (match_operand:XF 0 "register_operand" ""))
16352    (use (match_operand:XF 1 "register_operand" ""))]
16353   "TARGET_USE_FANCY_MATH_387
16354    && flag_unsafe_math_optimizations"
16355 {
16356   rtx one = gen_reg_rtx (XFmode);
16357   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16358
16359   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16360   DONE;
16361 })
16362
16363 (define_expand "tan<mode>2"
16364   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16365    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16366   "TARGET_USE_FANCY_MATH_387
16367    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16368        || TARGET_MIX_SSE_I387)
16369    && flag_unsafe_math_optimizations"
16370 {
16371   rtx op0 = gen_reg_rtx (XFmode);
16372
16373   rtx one = gen_reg_rtx (<MODE>mode);
16374   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16375
16376   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16377                                              operands[1], op2));
16378   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16379   DONE;
16380 })
16381
16382 (define_insn "*fpatanxf3_i387"
16383   [(set (match_operand:XF 0 "register_operand" "=f")
16384         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16385                     (match_operand:XF 2 "register_operand" "u")]
16386                    UNSPEC_FPATAN))
16387    (clobber (match_scratch:XF 3 "=2"))]
16388   "TARGET_USE_FANCY_MATH_387
16389    && flag_unsafe_math_optimizations"
16390   "fpatan"
16391   [(set_attr "type" "fpspc")
16392    (set_attr "mode" "XF")])
16393
16394 (define_insn "fpatan_extend<mode>xf3_i387"
16395   [(set (match_operand:XF 0 "register_operand" "=f")
16396         (unspec:XF [(float_extend:XF
16397                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16398                     (float_extend:XF
16399                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16400                    UNSPEC_FPATAN))
16401    (clobber (match_scratch:XF 3 "=2"))]
16402   "TARGET_USE_FANCY_MATH_387
16403    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16404        || TARGET_MIX_SSE_I387)
16405    && flag_unsafe_math_optimizations"
16406   "fpatan"
16407   [(set_attr "type" "fpspc")
16408    (set_attr "mode" "XF")])
16409
16410 (define_expand "atan2xf3"
16411   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16412                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16413                                (match_operand:XF 1 "register_operand" "")]
16414                               UNSPEC_FPATAN))
16415               (clobber (match_scratch:XF 3 ""))])]
16416   "TARGET_USE_FANCY_MATH_387
16417    && flag_unsafe_math_optimizations"
16418   "")
16419
16420 (define_expand "atan2<mode>3"
16421   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16422    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16423    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16426        || TARGET_MIX_SSE_I387)
16427    && flag_unsafe_math_optimizations"
16428 {
16429   rtx op0 = gen_reg_rtx (XFmode);
16430
16431   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16432   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16433   DONE;
16434 })
16435
16436 (define_expand "atanxf2"
16437   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16438                    (unspec:XF [(match_dup 2)
16439                                (match_operand:XF 1 "register_operand" "")]
16440                               UNSPEC_FPATAN))
16441               (clobber (match_scratch:XF 3 ""))])]
16442   "TARGET_USE_FANCY_MATH_387
16443    && flag_unsafe_math_optimizations"
16444 {
16445   operands[2] = gen_reg_rtx (XFmode);
16446   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16447 })
16448
16449 (define_expand "atan<mode>2"
16450   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16451    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16452   "TARGET_USE_FANCY_MATH_387
16453    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16454        || TARGET_MIX_SSE_I387)
16455    && flag_unsafe_math_optimizations"
16456 {
16457   rtx op0 = gen_reg_rtx (XFmode);
16458
16459   rtx op2 = gen_reg_rtx (<MODE>mode);
16460   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16461
16462   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16463   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16464   DONE;
16465 })
16466
16467 (define_expand "asinxf2"
16468   [(set (match_dup 2)
16469         (mult:XF (match_operand:XF 1 "register_operand" "")
16470                  (match_dup 1)))
16471    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16472    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16473    (parallel [(set (match_operand:XF 0 "register_operand" "")
16474                    (unspec:XF [(match_dup 5) (match_dup 1)]
16475                               UNSPEC_FPATAN))
16476               (clobber (match_scratch:XF 6 ""))])]
16477   "TARGET_USE_FANCY_MATH_387
16478    && flag_unsafe_math_optimizations && !optimize_size"
16479 {
16480   int i;
16481
16482   for (i = 2; i < 6; i++)
16483     operands[i] = gen_reg_rtx (XFmode);
16484
16485   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16486 })
16487
16488 (define_expand "asin<mode>2"
16489   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16490    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16491  "TARGET_USE_FANCY_MATH_387
16492    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16493        || TARGET_MIX_SSE_I387)
16494    && flag_unsafe_math_optimizations && !optimize_size"
16495 {
16496   rtx op0 = gen_reg_rtx (XFmode);
16497   rtx op1 = gen_reg_rtx (XFmode);
16498
16499   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16500   emit_insn (gen_asinxf2 (op0, op1));
16501   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16502   DONE;
16503 })
16504
16505 (define_expand "acosxf2"
16506   [(set (match_dup 2)
16507         (mult:XF (match_operand:XF 1 "register_operand" "")
16508                  (match_dup 1)))
16509    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16510    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16511    (parallel [(set (match_operand:XF 0 "register_operand" "")
16512                    (unspec:XF [(match_dup 1) (match_dup 5)]
16513                               UNSPEC_FPATAN))
16514               (clobber (match_scratch:XF 6 ""))])]
16515   "TARGET_USE_FANCY_MATH_387
16516    && flag_unsafe_math_optimizations && !optimize_size"
16517 {
16518   int i;
16519
16520   for (i = 2; i < 6; i++)
16521     operands[i] = gen_reg_rtx (XFmode);
16522
16523   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16524 })
16525
16526 (define_expand "acos<mode>2"
16527   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16528    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16529  "TARGET_USE_FANCY_MATH_387
16530    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16531        || TARGET_MIX_SSE_I387)
16532    && flag_unsafe_math_optimizations && !optimize_size"
16533 {
16534   rtx op0 = gen_reg_rtx (XFmode);
16535   rtx op1 = gen_reg_rtx (XFmode);
16536
16537   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16538   emit_insn (gen_acosxf2 (op0, op1));
16539   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16540   DONE;
16541 })
16542
16543 (define_insn "fyl2xxf3_i387"
16544   [(set (match_operand:XF 0 "register_operand" "=f")
16545         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16546                     (match_operand:XF 2 "register_operand" "u")]
16547                    UNSPEC_FYL2X))
16548    (clobber (match_scratch:XF 3 "=2"))]
16549   "TARGET_USE_FANCY_MATH_387
16550    && flag_unsafe_math_optimizations"
16551   "fyl2x"
16552   [(set_attr "type" "fpspc")
16553    (set_attr "mode" "XF")])
16554
16555 (define_insn "fyl2x_extend<mode>xf3_i387"
16556   [(set (match_operand:XF 0 "register_operand" "=f")
16557         (unspec:XF [(float_extend:XF
16558                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16559                     (match_operand:XF 2 "register_operand" "u")]
16560                    UNSPEC_FYL2X))
16561    (clobber (match_scratch:XF 3 "=2"))]
16562   "TARGET_USE_FANCY_MATH_387
16563    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16564        || TARGET_MIX_SSE_I387)
16565    && flag_unsafe_math_optimizations"
16566   "fyl2x"
16567   [(set_attr "type" "fpspc")
16568    (set_attr "mode" "XF")])
16569
16570 (define_expand "logxf2"
16571   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16572                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16573                                (match_dup 2)] UNSPEC_FYL2X))
16574               (clobber (match_scratch:XF 3 ""))])]
16575   "TARGET_USE_FANCY_MATH_387
16576    && flag_unsafe_math_optimizations"
16577 {
16578   operands[2] = gen_reg_rtx (XFmode);
16579   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16580 })
16581
16582 (define_expand "log<mode>2"
16583   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16584    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16585   "TARGET_USE_FANCY_MATH_387
16586    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16587        || TARGET_MIX_SSE_I387)
16588    && flag_unsafe_math_optimizations"
16589 {
16590   rtx op0 = gen_reg_rtx (XFmode);
16591
16592   rtx op2 = gen_reg_rtx (XFmode);
16593   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16594
16595   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16596   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16597   DONE;
16598 })
16599
16600 (define_expand "log10xf2"
16601   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16602                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16603                                (match_dup 2)] UNSPEC_FYL2X))
16604               (clobber (match_scratch:XF 3 ""))])]
16605   "TARGET_USE_FANCY_MATH_387
16606    && flag_unsafe_math_optimizations"
16607 {
16608   operands[2] = gen_reg_rtx (XFmode);
16609   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16610 })
16611
16612 (define_expand "log10<mode>2"
16613   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16614    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16615   "TARGET_USE_FANCY_MATH_387
16616    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16617        || TARGET_MIX_SSE_I387)
16618    && flag_unsafe_math_optimizations"
16619 {
16620   rtx op0 = gen_reg_rtx (XFmode);
16621
16622   rtx op2 = gen_reg_rtx (XFmode);
16623   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16624
16625   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16626   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16627   DONE;
16628 })
16629
16630 (define_expand "log2xf2"
16631   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16632                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16633                                (match_dup 2)] UNSPEC_FYL2X))
16634               (clobber (match_scratch:XF 3 ""))])]
16635   "TARGET_USE_FANCY_MATH_387
16636    && flag_unsafe_math_optimizations"
16637 {
16638   operands[2] = gen_reg_rtx (XFmode);
16639   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16640 })
16641
16642 (define_expand "log2<mode>2"
16643   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16644    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16645   "TARGET_USE_FANCY_MATH_387
16646    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16647        || TARGET_MIX_SSE_I387)
16648    && flag_unsafe_math_optimizations"
16649 {
16650   rtx op0 = gen_reg_rtx (XFmode);
16651
16652   rtx op2 = gen_reg_rtx (XFmode);
16653   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16654
16655   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16656   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16657   DONE;
16658 })
16659
16660 (define_insn "fyl2xp1xf3_i387"
16661   [(set (match_operand:XF 0 "register_operand" "=f")
16662         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16663                     (match_operand:XF 2 "register_operand" "u")]
16664                    UNSPEC_FYL2XP1))
16665    (clobber (match_scratch:XF 3 "=2"))]
16666   "TARGET_USE_FANCY_MATH_387
16667    && flag_unsafe_math_optimizations"
16668   "fyl2xp1"
16669   [(set_attr "type" "fpspc")
16670    (set_attr "mode" "XF")])
16671
16672 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16673   [(set (match_operand:XF 0 "register_operand" "=f")
16674         (unspec:XF [(float_extend:XF
16675                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16676                     (match_operand:XF 2 "register_operand" "u")]
16677                    UNSPEC_FYL2XP1))
16678    (clobber (match_scratch:XF 3 "=2"))]
16679   "TARGET_USE_FANCY_MATH_387
16680    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16681        || TARGET_MIX_SSE_I387)
16682    && flag_unsafe_math_optimizations"
16683   "fyl2xp1"
16684   [(set_attr "type" "fpspc")
16685    (set_attr "mode" "XF")])
16686
16687 (define_expand "log1pxf2"
16688   [(use (match_operand:XF 0 "register_operand" ""))
16689    (use (match_operand:XF 1 "register_operand" ""))]
16690   "TARGET_USE_FANCY_MATH_387
16691    && flag_unsafe_math_optimizations && !optimize_size"
16692 {
16693   ix86_emit_i387_log1p (operands[0], operands[1]);
16694   DONE;
16695 })
16696
16697 (define_expand "log1p<mode>2"
16698   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16699    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16700   "TARGET_USE_FANCY_MATH_387
16701    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16702        || TARGET_MIX_SSE_I387)
16703    && flag_unsafe_math_optimizations && !optimize_size"
16704 {
16705   rtx op0 = gen_reg_rtx (XFmode);
16706
16707   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16708
16709   ix86_emit_i387_log1p (op0, operands[1]);
16710   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16711   DONE;
16712 })
16713
16714 (define_insn "fxtractxf3_i387"
16715   [(set (match_operand:XF 0 "register_operand" "=f")
16716         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16717                    UNSPEC_XTRACT_FRACT))
16718    (set (match_operand:XF 1 "register_operand" "=u")
16719         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16720   "TARGET_USE_FANCY_MATH_387
16721    && flag_unsafe_math_optimizations"
16722   "fxtract"
16723   [(set_attr "type" "fpspc")
16724    (set_attr "mode" "XF")])
16725
16726 (define_insn "fxtract_extend<mode>xf3_i387"
16727   [(set (match_operand:XF 0 "register_operand" "=f")
16728         (unspec:XF [(float_extend:XF
16729                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16730                    UNSPEC_XTRACT_FRACT))
16731    (set (match_operand:XF 1 "register_operand" "=u")
16732         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16735        || TARGET_MIX_SSE_I387)
16736    && flag_unsafe_math_optimizations"
16737   "fxtract"
16738   [(set_attr "type" "fpspc")
16739    (set_attr "mode" "XF")])
16740
16741 (define_expand "logbxf2"
16742   [(parallel [(set (match_dup 2)
16743                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16744                               UNSPEC_XTRACT_FRACT))
16745               (set (match_operand:XF 0 "register_operand" "")
16746                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16747   "TARGET_USE_FANCY_MATH_387
16748    && flag_unsafe_math_optimizations"
16749 {
16750   operands[2] = gen_reg_rtx (XFmode);
16751 })
16752
16753 (define_expand "logb<mode>2"
16754   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16755    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16756   "TARGET_USE_FANCY_MATH_387
16757    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16758        || TARGET_MIX_SSE_I387)
16759    && flag_unsafe_math_optimizations"
16760 {
16761   rtx op0 = gen_reg_rtx (XFmode);
16762   rtx op1 = gen_reg_rtx (XFmode);
16763
16764   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16765   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16766   DONE;
16767 })
16768
16769 (define_expand "ilogbxf2"
16770   [(use (match_operand:SI 0 "register_operand" ""))
16771    (use (match_operand:XF 1 "register_operand" ""))]
16772   "TARGET_USE_FANCY_MATH_387
16773    && flag_unsafe_math_optimizations && !optimize_size"
16774 {
16775   rtx op0 = gen_reg_rtx (XFmode);
16776   rtx op1 = gen_reg_rtx (XFmode);
16777
16778   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16779   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16780   DONE;
16781 })
16782
16783 (define_expand "ilogb<mode>2"
16784   [(use (match_operand:SI 0 "register_operand" ""))
16785    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16786   "TARGET_USE_FANCY_MATH_387
16787    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788        || TARGET_MIX_SSE_I387)
16789    && flag_unsafe_math_optimizations && !optimize_size"
16790 {
16791   rtx op0 = gen_reg_rtx (XFmode);
16792   rtx op1 = gen_reg_rtx (XFmode);
16793
16794   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16795   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16796   DONE;
16797 })
16798
16799 (define_insn "*f2xm1xf2_i387"
16800   [(set (match_operand:XF 0 "register_operand" "=f")
16801         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16802                    UNSPEC_F2XM1))]
16803   "TARGET_USE_FANCY_MATH_387
16804    && flag_unsafe_math_optimizations"
16805   "f2xm1"
16806   [(set_attr "type" "fpspc")
16807    (set_attr "mode" "XF")])
16808
16809 (define_insn "*fscalexf4_i387"
16810   [(set (match_operand:XF 0 "register_operand" "=f")
16811         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16812                     (match_operand:XF 3 "register_operand" "1")]
16813                    UNSPEC_FSCALE_FRACT))
16814    (set (match_operand:XF 1 "register_operand" "=u")
16815         (unspec:XF [(match_dup 2) (match_dup 3)]
16816                    UNSPEC_FSCALE_EXP))]
16817   "TARGET_USE_FANCY_MATH_387
16818    && flag_unsafe_math_optimizations"
16819   "fscale"
16820   [(set_attr "type" "fpspc")
16821    (set_attr "mode" "XF")])
16822
16823 (define_expand "expNcorexf3"
16824   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16825                                (match_operand:XF 2 "register_operand" "")))
16826    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16827    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16828    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16829    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16830    (parallel [(set (match_operand:XF 0 "register_operand" "")
16831                    (unspec:XF [(match_dup 8) (match_dup 4)]
16832                               UNSPEC_FSCALE_FRACT))
16833               (set (match_dup 9)
16834                    (unspec:XF [(match_dup 8) (match_dup 4)]
16835                               UNSPEC_FSCALE_EXP))])]
16836   "TARGET_USE_FANCY_MATH_387
16837    && flag_unsafe_math_optimizations && !optimize_size"
16838 {
16839   int i;
16840
16841   for (i = 3; i < 10; i++)
16842     operands[i] = gen_reg_rtx (XFmode);
16843
16844   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16845 })
16846
16847 (define_expand "expxf2"
16848   [(use (match_operand:XF 0 "register_operand" ""))
16849    (use (match_operand:XF 1 "register_operand" ""))]
16850   "TARGET_USE_FANCY_MATH_387
16851    && flag_unsafe_math_optimizations && !optimize_size"
16852 {
16853   rtx op2 = gen_reg_rtx (XFmode);
16854   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16855
16856   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16857   DONE;
16858 })
16859
16860 (define_expand "exp<mode>2"
16861   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16862    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16863  "TARGET_USE_FANCY_MATH_387
16864    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16865        || TARGET_MIX_SSE_I387)
16866    && flag_unsafe_math_optimizations && !optimize_size"
16867 {
16868   rtx op0 = gen_reg_rtx (XFmode);
16869   rtx op1 = gen_reg_rtx (XFmode);
16870
16871   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16872   emit_insn (gen_expxf2 (op0, op1));
16873   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16874   DONE;
16875 })
16876
16877 (define_expand "exp10xf2"
16878   [(use (match_operand:XF 0 "register_operand" ""))
16879    (use (match_operand:XF 1 "register_operand" ""))]
16880   "TARGET_USE_FANCY_MATH_387
16881    && flag_unsafe_math_optimizations && !optimize_size"
16882 {
16883   rtx op2 = gen_reg_rtx (XFmode);
16884   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16885
16886   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16887   DONE;
16888 })
16889
16890 (define_expand "exp10<mode>2"
16891   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16892    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16893  "TARGET_USE_FANCY_MATH_387
16894    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16895        || TARGET_MIX_SSE_I387)
16896    && flag_unsafe_math_optimizations && !optimize_size"
16897 {
16898   rtx op0 = gen_reg_rtx (XFmode);
16899   rtx op1 = gen_reg_rtx (XFmode);
16900
16901   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16902   emit_insn (gen_exp10xf2 (op0, op1));
16903   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16904   DONE;
16905 })
16906
16907 (define_expand "exp2xf2"
16908   [(use (match_operand:XF 0 "register_operand" ""))
16909    (use (match_operand:XF 1 "register_operand" ""))]
16910   "TARGET_USE_FANCY_MATH_387
16911    && flag_unsafe_math_optimizations && !optimize_size"
16912 {
16913   rtx op2 = gen_reg_rtx (XFmode);
16914   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16915
16916   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16917   DONE;
16918 })
16919
16920 (define_expand "exp2<mode>2"
16921   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16922    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16923  "TARGET_USE_FANCY_MATH_387
16924    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925        || TARGET_MIX_SSE_I387)
16926    && flag_unsafe_math_optimizations && !optimize_size"
16927 {
16928   rtx op0 = gen_reg_rtx (XFmode);
16929   rtx op1 = gen_reg_rtx (XFmode);
16930
16931   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16932   emit_insn (gen_exp2xf2 (op0, op1));
16933   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16934   DONE;
16935 })
16936
16937 (define_expand "expm1xf2"
16938   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16939                                (match_dup 2)))
16940    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16941    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16942    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16943    (parallel [(set (match_dup 7)
16944                    (unspec:XF [(match_dup 6) (match_dup 4)]
16945                               UNSPEC_FSCALE_FRACT))
16946                    (set (match_dup 8)
16947                    (unspec:XF [(match_dup 6) (match_dup 4)]
16948                               UNSPEC_FSCALE_EXP))])
16949    (parallel [(set (match_dup 10)
16950                    (unspec:XF [(match_dup 9) (match_dup 8)]
16951                               UNSPEC_FSCALE_FRACT))
16952               (set (match_dup 11)
16953                    (unspec:XF [(match_dup 9) (match_dup 8)]
16954                               UNSPEC_FSCALE_EXP))])
16955    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16956    (set (match_operand:XF 0 "register_operand" "")
16957         (plus:XF (match_dup 12) (match_dup 7)))]
16958   "TARGET_USE_FANCY_MATH_387
16959    && flag_unsafe_math_optimizations && !optimize_size"
16960 {
16961   int i;
16962
16963   for (i = 2; i < 13; i++)
16964     operands[i] = gen_reg_rtx (XFmode);
16965  
16966   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16967   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16968 })
16969
16970 (define_expand "expm1<mode>2"
16971   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16972    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16973  "TARGET_USE_FANCY_MATH_387
16974    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16975        || TARGET_MIX_SSE_I387)
16976    && flag_unsafe_math_optimizations && !optimize_size"
16977 {
16978   rtx op0 = gen_reg_rtx (XFmode);
16979   rtx op1 = gen_reg_rtx (XFmode);
16980
16981   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16982   emit_insn (gen_expm1xf2 (op0, op1));
16983   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16984   DONE;
16985 })
16986
16987 (define_expand "ldexpxf3"
16988   [(set (match_dup 3)
16989         (float:XF (match_operand:SI 2 "register_operand" "")))
16990    (parallel [(set (match_operand:XF 0 " register_operand" "")
16991                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16992                                (match_dup 3)]
16993                               UNSPEC_FSCALE_FRACT))
16994               (set (match_dup 4)
16995                    (unspec:XF [(match_dup 1) (match_dup 3)]
16996                               UNSPEC_FSCALE_EXP))])]
16997   "TARGET_USE_FANCY_MATH_387
16998    && flag_unsafe_math_optimizations && !optimize_size"
16999 {
17000   operands[3] = gen_reg_rtx (XFmode);
17001   operands[4] = gen_reg_rtx (XFmode);
17002 })
17003
17004 (define_expand "ldexp<mode>3"
17005   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17006    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17007    (use (match_operand:SI 2 "register_operand" ""))]
17008  "TARGET_USE_FANCY_MATH_387
17009    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17010        || TARGET_MIX_SSE_I387)
17011    && flag_unsafe_math_optimizations && !optimize_size"
17012 {
17013   rtx op0 = gen_reg_rtx (XFmode);
17014   rtx op1 = gen_reg_rtx (XFmode);
17015
17016   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17017   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17018   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17019   DONE;
17020 })
17021 \f
17022
17023 (define_insn "frndintxf2"
17024   [(set (match_operand:XF 0 "register_operand" "=f")
17025         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17026          UNSPEC_FRNDINT))]
17027   "TARGET_USE_FANCY_MATH_387
17028    && flag_unsafe_math_optimizations"
17029   "frndint"
17030   [(set_attr "type" "fpspc")
17031    (set_attr "mode" "XF")])
17032
17033 (define_expand "rintdf2"
17034   [(use (match_operand:DF 0 "register_operand" ""))
17035    (use (match_operand:DF 1 "register_operand" ""))]
17036   "(TARGET_USE_FANCY_MATH_387
17037     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17038     && flag_unsafe_math_optimizations)
17039    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17040        && !flag_trapping_math
17041        && !optimize_size)"
17042 {
17043   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17044       && !flag_trapping_math
17045       && !optimize_size)
17046     ix86_expand_rint (operand0, operand1);
17047   else
17048     {
17049       rtx op0 = gen_reg_rtx (XFmode);
17050       rtx op1 = gen_reg_rtx (XFmode);
17051
17052       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17053       emit_insn (gen_frndintxf2 (op0, op1));
17054
17055       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17056     }
17057   DONE;
17058 })
17059
17060 (define_expand "rintsf2"
17061   [(use (match_operand:SF 0 "register_operand" ""))
17062    (use (match_operand:SF 1 "register_operand" ""))]
17063   "(TARGET_USE_FANCY_MATH_387
17064     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17065     && flag_unsafe_math_optimizations)
17066    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17067        && !flag_trapping_math
17068        && !optimize_size)"
17069 {
17070   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17071       && !flag_trapping_math
17072       && !optimize_size)
17073     ix86_expand_rint (operand0, operand1);
17074   else
17075     {
17076       rtx op0 = gen_reg_rtx (XFmode);
17077       rtx op1 = gen_reg_rtx (XFmode);
17078
17079       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17080       emit_insn (gen_frndintxf2 (op0, op1));
17081
17082       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17083     }
17084   DONE;
17085 })
17086
17087 (define_expand "rintxf2"
17088   [(use (match_operand:XF 0 "register_operand" ""))
17089    (use (match_operand:XF 1 "register_operand" ""))]
17090   "TARGET_USE_FANCY_MATH_387
17091    && flag_unsafe_math_optimizations && !optimize_size"
17092 {
17093   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17094   DONE;
17095 })
17096
17097 (define_expand "roundsf2"
17098   [(match_operand:SF 0 "register_operand" "")
17099    (match_operand:SF 1 "nonimmediate_operand" "")]
17100   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17101    && !flag_trapping_math && !flag_rounding_math
17102    && !optimize_size"
17103 {
17104   ix86_expand_round (operand0, operand1);
17105   DONE;
17106 })
17107
17108 (define_expand "rounddf2"
17109   [(match_operand:DF 0 "register_operand" "")
17110    (match_operand:DF 1 "nonimmediate_operand" "")]
17111   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17112    && !flag_trapping_math && !flag_rounding_math
17113    && !optimize_size"
17114 {
17115   if (TARGET_64BIT)
17116     ix86_expand_round (operand0, operand1);
17117   else
17118     ix86_expand_rounddf_32 (operand0, operand1);
17119   DONE;
17120 })
17121
17122 (define_insn_and_split "*fistdi2_1"
17123   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17124         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17125          UNSPEC_FIST))]
17126   "TARGET_USE_FANCY_MATH_387
17127    && !(reload_completed || reload_in_progress)"
17128   "#"
17129   "&& 1"
17130   [(const_int 0)]
17131 {
17132   if (memory_operand (operands[0], VOIDmode))
17133     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17134   else
17135     {
17136       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17137       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17138                                          operands[2]));
17139     }
17140   DONE;
17141 }
17142   [(set_attr "type" "fpspc")
17143    (set_attr "mode" "DI")])
17144
17145 (define_insn "fistdi2"
17146   [(set (match_operand:DI 0 "memory_operand" "=m")
17147         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17148          UNSPEC_FIST))
17149    (clobber (match_scratch:XF 2 "=&1f"))]
17150   "TARGET_USE_FANCY_MATH_387"
17151   "* return output_fix_trunc (insn, operands, 0);"
17152   [(set_attr "type" "fpspc")
17153    (set_attr "mode" "DI")])
17154
17155 (define_insn "fistdi2_with_temp"
17156   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17157         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17158          UNSPEC_FIST))
17159    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17160    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17161   "TARGET_USE_FANCY_MATH_387"
17162   "#"
17163   [(set_attr "type" "fpspc")
17164    (set_attr "mode" "DI")])
17165
17166 (define_split
17167   [(set (match_operand:DI 0 "register_operand" "")
17168         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17169          UNSPEC_FIST))
17170    (clobber (match_operand:DI 2 "memory_operand" ""))
17171    (clobber (match_scratch 3 ""))]
17172   "reload_completed"
17173   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17174               (clobber (match_dup 3))])
17175    (set (match_dup 0) (match_dup 2))]
17176   "")
17177
17178 (define_split
17179   [(set (match_operand:DI 0 "memory_operand" "")
17180         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17181          UNSPEC_FIST))
17182    (clobber (match_operand:DI 2 "memory_operand" ""))
17183    (clobber (match_scratch 3 ""))]
17184   "reload_completed"
17185   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17186               (clobber (match_dup 3))])]
17187   "")
17188
17189 (define_insn_and_split "*fist<mode>2_1"
17190   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17191         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17192          UNSPEC_FIST))]
17193   "TARGET_USE_FANCY_MATH_387
17194    && !(reload_completed || reload_in_progress)"
17195   "#"
17196   "&& 1"
17197   [(const_int 0)]
17198 {
17199   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17200   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17201                                         operands[2]));
17202   DONE;
17203 }
17204   [(set_attr "type" "fpspc")
17205    (set_attr "mode" "<MODE>")])
17206
17207 (define_insn "fist<mode>2"
17208   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17209         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17210          UNSPEC_FIST))]
17211   "TARGET_USE_FANCY_MATH_387"
17212   "* return output_fix_trunc (insn, operands, 0);"
17213   [(set_attr "type" "fpspc")
17214    (set_attr "mode" "<MODE>")])
17215
17216 (define_insn "fist<mode>2_with_temp"
17217   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17218         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17219          UNSPEC_FIST))
17220    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17221   "TARGET_USE_FANCY_MATH_387"
17222   "#"
17223   [(set_attr "type" "fpspc")
17224    (set_attr "mode" "<MODE>")])
17225
17226 (define_split
17227   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17228         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17229          UNSPEC_FIST))
17230    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17231   "reload_completed"
17232   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17233                        UNSPEC_FIST))
17234    (set (match_dup 0) (match_dup 2))]
17235   "")
17236
17237 (define_split
17238   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17239         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17240          UNSPEC_FIST))
17241    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17242   "reload_completed"
17243   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17244                        UNSPEC_FIST))]
17245   "")
17246
17247 (define_expand "lrintxf<mode>2"
17248   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17249      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17250       UNSPEC_FIST))]
17251   "TARGET_USE_FANCY_MATH_387"
17252   "")
17253
17254 (define_expand "lrint<mode>di2"
17255   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17256      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17257       UNSPEC_FIX_NOTRUNC))]
17258   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17259   "")
17260
17261 (define_expand "lrint<mode>si2"
17262   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17263      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17264       UNSPEC_FIX_NOTRUNC))]
17265   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17266   "")
17267
17268 (define_expand "lround<mode>di2"
17269   [(match_operand:DI 0 "nonimmediate_operand" "")
17270    (match_operand:SSEMODEF 1 "register_operand" "")]
17271   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17272    && !flag_trapping_math && !flag_rounding_math
17273    && !optimize_size"
17274 {
17275   ix86_expand_lround (operand0, operand1);
17276   DONE;
17277 })
17278
17279 (define_expand "lround<mode>si2"
17280   [(match_operand:SI 0 "nonimmediate_operand" "")
17281    (match_operand:SSEMODEF 1 "register_operand" "")]
17282   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17283    && !flag_trapping_math && !flag_rounding_math
17284    && !optimize_size"
17285 {
17286   ix86_expand_lround (operand0, operand1);
17287   DONE;
17288 })
17289
17290 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17291 (define_insn_and_split "frndintxf2_floor"
17292   [(set (match_operand:XF 0 "register_operand" "=f")
17293         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17294          UNSPEC_FRNDINT_FLOOR))
17295    (clobber (reg:CC FLAGS_REG))]
17296   "TARGET_USE_FANCY_MATH_387
17297    && flag_unsafe_math_optimizations
17298    && !(reload_completed || reload_in_progress)"
17299   "#"
17300   "&& 1"
17301   [(const_int 0)]
17302 {
17303   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17304
17305   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17306   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17307
17308   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17309                                         operands[2], operands[3]));
17310   DONE;
17311 }
17312   [(set_attr "type" "frndint")
17313    (set_attr "i387_cw" "floor")
17314    (set_attr "mode" "XF")])
17315
17316 (define_insn "frndintxf2_floor_i387"
17317   [(set (match_operand:XF 0 "register_operand" "=f")
17318         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17319          UNSPEC_FRNDINT_FLOOR))
17320    (use (match_operand:HI 2 "memory_operand" "m"))
17321    (use (match_operand:HI 3 "memory_operand" "m"))]
17322   "TARGET_USE_FANCY_MATH_387
17323    && flag_unsafe_math_optimizations"
17324   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17325   [(set_attr "type" "frndint")
17326    (set_attr "i387_cw" "floor")
17327    (set_attr "mode" "XF")])
17328
17329 (define_expand "floorxf2"
17330   [(use (match_operand:XF 0 "register_operand" ""))
17331    (use (match_operand:XF 1 "register_operand" ""))]
17332   "TARGET_USE_FANCY_MATH_387
17333    && flag_unsafe_math_optimizations && !optimize_size"
17334 {
17335   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17336   DONE;
17337 })
17338
17339 (define_expand "floordf2"
17340   [(use (match_operand:DF 0 "register_operand" ""))
17341    (use (match_operand:DF 1 "register_operand" ""))]
17342   "((TARGET_USE_FANCY_MATH_387
17343      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17344      && flag_unsafe_math_optimizations)
17345     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17346         && !flag_trapping_math))
17347    && !optimize_size"
17348 {
17349   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17350       && !flag_trapping_math)
17351     {
17352       if (TARGET_64BIT)
17353         ix86_expand_floorceil (operand0, operand1, true);
17354       else
17355         ix86_expand_floorceildf_32 (operand0, operand1, true);
17356     }
17357   else
17358     {
17359       rtx op0 = gen_reg_rtx (XFmode);
17360       rtx op1 = gen_reg_rtx (XFmode);
17361
17362       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17363       emit_insn (gen_frndintxf2_floor (op0, op1));
17364
17365       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17366     }
17367   DONE;
17368 })
17369
17370 (define_expand "floorsf2"
17371   [(use (match_operand:SF 0 "register_operand" ""))
17372    (use (match_operand:SF 1 "register_operand" ""))]
17373   "((TARGET_USE_FANCY_MATH_387
17374      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17375      && flag_unsafe_math_optimizations)
17376     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17377         && !flag_trapping_math))
17378    && !optimize_size"
17379 {
17380   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17381       && !flag_trapping_math)
17382     ix86_expand_floorceil (operand0, operand1, true);
17383   else
17384     {
17385       rtx op0 = gen_reg_rtx (XFmode);
17386       rtx op1 = gen_reg_rtx (XFmode);
17387
17388       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17389       emit_insn (gen_frndintxf2_floor (op0, op1));
17390
17391       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17392     }
17393   DONE;
17394 })
17395
17396 (define_insn_and_split "*fist<mode>2_floor_1"
17397   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17398         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17399          UNSPEC_FIST_FLOOR))
17400    (clobber (reg:CC FLAGS_REG))]
17401   "TARGET_USE_FANCY_MATH_387
17402    && flag_unsafe_math_optimizations
17403    && !(reload_completed || reload_in_progress)"
17404   "#"
17405   "&& 1"
17406   [(const_int 0)]
17407 {
17408   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17409
17410   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17411   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17412   if (memory_operand (operands[0], VOIDmode))
17413     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17414                                       operands[2], operands[3]));
17415   else
17416     {
17417       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17418       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17419                                                   operands[2], operands[3],
17420                                                   operands[4]));
17421     }
17422   DONE;
17423 }
17424   [(set_attr "type" "fistp")
17425    (set_attr "i387_cw" "floor")
17426    (set_attr "mode" "<MODE>")])
17427
17428 (define_insn "fistdi2_floor"
17429   [(set (match_operand:DI 0 "memory_operand" "=m")
17430         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17431          UNSPEC_FIST_FLOOR))
17432    (use (match_operand:HI 2 "memory_operand" "m"))
17433    (use (match_operand:HI 3 "memory_operand" "m"))
17434    (clobber (match_scratch:XF 4 "=&1f"))]
17435   "TARGET_USE_FANCY_MATH_387
17436    && flag_unsafe_math_optimizations"
17437   "* return output_fix_trunc (insn, operands, 0);"
17438   [(set_attr "type" "fistp")
17439    (set_attr "i387_cw" "floor")
17440    (set_attr "mode" "DI")])
17441
17442 (define_insn "fistdi2_floor_with_temp"
17443   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17444         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17445          UNSPEC_FIST_FLOOR))
17446    (use (match_operand:HI 2 "memory_operand" "m,m"))
17447    (use (match_operand:HI 3 "memory_operand" "m,m"))
17448    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17449    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17450   "TARGET_USE_FANCY_MATH_387
17451    && flag_unsafe_math_optimizations"
17452   "#"
17453   [(set_attr "type" "fistp")
17454    (set_attr "i387_cw" "floor")
17455    (set_attr "mode" "DI")])
17456
17457 (define_split
17458   [(set (match_operand:DI 0 "register_operand" "")
17459         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17460          UNSPEC_FIST_FLOOR))
17461    (use (match_operand:HI 2 "memory_operand" ""))
17462    (use (match_operand:HI 3 "memory_operand" ""))
17463    (clobber (match_operand:DI 4 "memory_operand" ""))
17464    (clobber (match_scratch 5 ""))]
17465   "reload_completed"
17466   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17467               (use (match_dup 2))
17468               (use (match_dup 3))
17469               (clobber (match_dup 5))])
17470    (set (match_dup 0) (match_dup 4))]
17471   "")
17472
17473 (define_split
17474   [(set (match_operand:DI 0 "memory_operand" "")
17475         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17476          UNSPEC_FIST_FLOOR))
17477    (use (match_operand:HI 2 "memory_operand" ""))
17478    (use (match_operand:HI 3 "memory_operand" ""))
17479    (clobber (match_operand:DI 4 "memory_operand" ""))
17480    (clobber (match_scratch 5 ""))]
17481   "reload_completed"
17482   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17483               (use (match_dup 2))
17484               (use (match_dup 3))
17485               (clobber (match_dup 5))])]
17486   "")
17487
17488 (define_insn "fist<mode>2_floor"
17489   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17490         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17491          UNSPEC_FIST_FLOOR))
17492    (use (match_operand:HI 2 "memory_operand" "m"))
17493    (use (match_operand:HI 3 "memory_operand" "m"))]
17494   "TARGET_USE_FANCY_MATH_387
17495    && flag_unsafe_math_optimizations"
17496   "* return output_fix_trunc (insn, operands, 0);"
17497   [(set_attr "type" "fistp")
17498    (set_attr "i387_cw" "floor")
17499    (set_attr "mode" "<MODE>")])
17500
17501 (define_insn "fist<mode>2_floor_with_temp"
17502   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17503         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17504          UNSPEC_FIST_FLOOR))
17505    (use (match_operand:HI 2 "memory_operand" "m,m"))
17506    (use (match_operand:HI 3 "memory_operand" "m,m"))
17507    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17508   "TARGET_USE_FANCY_MATH_387
17509    && flag_unsafe_math_optimizations"
17510   "#"
17511   [(set_attr "type" "fistp")
17512    (set_attr "i387_cw" "floor")
17513    (set_attr "mode" "<MODE>")])
17514
17515 (define_split
17516   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17517         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17518          UNSPEC_FIST_FLOOR))
17519    (use (match_operand:HI 2 "memory_operand" ""))
17520    (use (match_operand:HI 3 "memory_operand" ""))
17521    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17522   "reload_completed"
17523   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17524                                   UNSPEC_FIST_FLOOR))
17525               (use (match_dup 2))
17526               (use (match_dup 3))])
17527    (set (match_dup 0) (match_dup 4))]
17528   "")
17529
17530 (define_split
17531   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17532         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17533          UNSPEC_FIST_FLOOR))
17534    (use (match_operand:HI 2 "memory_operand" ""))
17535    (use (match_operand:HI 3 "memory_operand" ""))
17536    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17537   "reload_completed"
17538   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17539                                   UNSPEC_FIST_FLOOR))
17540               (use (match_dup 2))
17541               (use (match_dup 3))])]
17542   "")
17543
17544 (define_expand "lfloorxf<mode>2"
17545   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17546                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17547                     UNSPEC_FIST_FLOOR))
17548               (clobber (reg:CC FLAGS_REG))])]
17549   "TARGET_USE_FANCY_MATH_387
17550    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17551    && flag_unsafe_math_optimizations"
17552   "")
17553
17554 (define_expand "lfloor<mode>di2"
17555   [(match_operand:DI 0 "nonimmediate_operand" "")
17556    (match_operand:SSEMODEF 1 "register_operand" "")]
17557   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17558    && !flag_trapping_math
17559    && !optimize_size"
17560 {
17561   ix86_expand_lfloorceil (operand0, operand1, true);
17562   DONE;
17563 })
17564
17565 (define_expand "lfloor<mode>si2"
17566   [(match_operand:SI 0 "nonimmediate_operand" "")
17567    (match_operand:SSEMODEF 1 "register_operand" "")]
17568   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17569    && !flag_trapping_math
17570    && (!optimize_size || !TARGET_64BIT)"
17571 {
17572   ix86_expand_lfloorceil (operand0, operand1, true);
17573   DONE;
17574 })
17575
17576 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17577 (define_insn_and_split "frndintxf2_ceil"
17578   [(set (match_operand:XF 0 "register_operand" "=f")
17579         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17580          UNSPEC_FRNDINT_CEIL))
17581    (clobber (reg:CC FLAGS_REG))]
17582   "TARGET_USE_FANCY_MATH_387
17583    && flag_unsafe_math_optimizations
17584    && !(reload_completed || reload_in_progress)"
17585   "#"
17586   "&& 1"
17587   [(const_int 0)]
17588 {
17589   ix86_optimize_mode_switching[I387_CEIL] = 1;
17590
17591   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17592   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17593
17594   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17595                                        operands[2], operands[3]));
17596   DONE;
17597 }
17598   [(set_attr "type" "frndint")
17599    (set_attr "i387_cw" "ceil")
17600    (set_attr "mode" "XF")])
17601
17602 (define_insn "frndintxf2_ceil_i387"
17603   [(set (match_operand:XF 0 "register_operand" "=f")
17604         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17605          UNSPEC_FRNDINT_CEIL))
17606    (use (match_operand:HI 2 "memory_operand" "m"))
17607    (use (match_operand:HI 3 "memory_operand" "m"))]
17608   "TARGET_USE_FANCY_MATH_387
17609    && flag_unsafe_math_optimizations"
17610   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17611   [(set_attr "type" "frndint")
17612    (set_attr "i387_cw" "ceil")
17613    (set_attr "mode" "XF")])
17614
17615 (define_expand "ceilxf2"
17616   [(use (match_operand:XF 0 "register_operand" ""))
17617    (use (match_operand:XF 1 "register_operand" ""))]
17618   "TARGET_USE_FANCY_MATH_387
17619    && flag_unsafe_math_optimizations && !optimize_size"
17620 {
17621   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17622   DONE;
17623 })
17624
17625 (define_expand "ceildf2"
17626   [(use (match_operand:DF 0 "register_operand" ""))
17627    (use (match_operand:DF 1 "register_operand" ""))]
17628   "((TARGET_USE_FANCY_MATH_387
17629      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17630      && flag_unsafe_math_optimizations)
17631     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17632         && !flag_trapping_math))
17633    && !optimize_size"
17634 {
17635   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17636       && !flag_trapping_math)
17637     {
17638       if (TARGET_64BIT)
17639         ix86_expand_floorceil (operand0, operand1, false);
17640       else
17641         ix86_expand_floorceildf_32 (operand0, operand1, false);
17642     }
17643   else
17644     {
17645       rtx op0 = gen_reg_rtx (XFmode);
17646       rtx op1 = gen_reg_rtx (XFmode);
17647
17648       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17649       emit_insn (gen_frndintxf2_ceil (op0, op1));
17650
17651       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17652     }
17653   DONE;
17654 })
17655
17656 (define_expand "ceilsf2"
17657   [(use (match_operand:SF 0 "register_operand" ""))
17658    (use (match_operand:SF 1 "register_operand" ""))]
17659   "((TARGET_USE_FANCY_MATH_387
17660      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17661      && flag_unsafe_math_optimizations)
17662     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17663         && !flag_trapping_math))
17664    && !optimize_size"
17665 {
17666   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17667       && !flag_trapping_math)
17668     ix86_expand_floorceil (operand0, operand1, false);
17669   else
17670     {
17671       rtx op0 = gen_reg_rtx (XFmode);
17672       rtx op1 = gen_reg_rtx (XFmode);
17673
17674       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17675       emit_insn (gen_frndintxf2_ceil (op0, op1));
17676
17677       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17678     }
17679   DONE;
17680 })
17681
17682 (define_insn_and_split "*fist<mode>2_ceil_1"
17683   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17684         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17685          UNSPEC_FIST_CEIL))
17686    (clobber (reg:CC FLAGS_REG))]
17687   "TARGET_USE_FANCY_MATH_387
17688    && flag_unsafe_math_optimizations
17689    && !(reload_completed || reload_in_progress)"
17690   "#"
17691   "&& 1"
17692   [(const_int 0)]
17693 {
17694   ix86_optimize_mode_switching[I387_CEIL] = 1;
17695
17696   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17697   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17698   if (memory_operand (operands[0], VOIDmode))
17699     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17700                                      operands[2], operands[3]));
17701   else
17702     {
17703       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17704       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17705                                                  operands[2], operands[3],
17706                                                  operands[4]));
17707     }
17708   DONE;
17709 }
17710   [(set_attr "type" "fistp")
17711    (set_attr "i387_cw" "ceil")
17712    (set_attr "mode" "<MODE>")])
17713
17714 (define_insn "fistdi2_ceil"
17715   [(set (match_operand:DI 0 "memory_operand" "=m")
17716         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17717          UNSPEC_FIST_CEIL))
17718    (use (match_operand:HI 2 "memory_operand" "m"))
17719    (use (match_operand:HI 3 "memory_operand" "m"))
17720    (clobber (match_scratch:XF 4 "=&1f"))]
17721   "TARGET_USE_FANCY_MATH_387
17722    && flag_unsafe_math_optimizations"
17723   "* return output_fix_trunc (insn, operands, 0);"
17724   [(set_attr "type" "fistp")
17725    (set_attr "i387_cw" "ceil")
17726    (set_attr "mode" "DI")])
17727
17728 (define_insn "fistdi2_ceil_with_temp"
17729   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17730         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17731          UNSPEC_FIST_CEIL))
17732    (use (match_operand:HI 2 "memory_operand" "m,m"))
17733    (use (match_operand:HI 3 "memory_operand" "m,m"))
17734    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17735    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17736   "TARGET_USE_FANCY_MATH_387
17737    && flag_unsafe_math_optimizations"
17738   "#"
17739   [(set_attr "type" "fistp")
17740    (set_attr "i387_cw" "ceil")
17741    (set_attr "mode" "DI")])
17742
17743 (define_split
17744   [(set (match_operand:DI 0 "register_operand" "")
17745         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17746          UNSPEC_FIST_CEIL))
17747    (use (match_operand:HI 2 "memory_operand" ""))
17748    (use (match_operand:HI 3 "memory_operand" ""))
17749    (clobber (match_operand:DI 4 "memory_operand" ""))
17750    (clobber (match_scratch 5 ""))]
17751   "reload_completed"
17752   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17753               (use (match_dup 2))
17754               (use (match_dup 3))
17755               (clobber (match_dup 5))])
17756    (set (match_dup 0) (match_dup 4))]
17757   "")
17758
17759 (define_split
17760   [(set (match_operand:DI 0 "memory_operand" "")
17761         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17762          UNSPEC_FIST_CEIL))
17763    (use (match_operand:HI 2 "memory_operand" ""))
17764    (use (match_operand:HI 3 "memory_operand" ""))
17765    (clobber (match_operand:DI 4 "memory_operand" ""))
17766    (clobber (match_scratch 5 ""))]
17767   "reload_completed"
17768   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17769               (use (match_dup 2))
17770               (use (match_dup 3))
17771               (clobber (match_dup 5))])]
17772   "")
17773
17774 (define_insn "fist<mode>2_ceil"
17775   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17776         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17777          UNSPEC_FIST_CEIL))
17778    (use (match_operand:HI 2 "memory_operand" "m"))
17779    (use (match_operand:HI 3 "memory_operand" "m"))]
17780   "TARGET_USE_FANCY_MATH_387
17781    && flag_unsafe_math_optimizations"
17782   "* return output_fix_trunc (insn, operands, 0);"
17783   [(set_attr "type" "fistp")
17784    (set_attr "i387_cw" "ceil")
17785    (set_attr "mode" "<MODE>")])
17786
17787 (define_insn "fist<mode>2_ceil_with_temp"
17788   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17789         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17790          UNSPEC_FIST_CEIL))
17791    (use (match_operand:HI 2 "memory_operand" "m,m"))
17792    (use (match_operand:HI 3 "memory_operand" "m,m"))
17793    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17794   "TARGET_USE_FANCY_MATH_387
17795    && flag_unsafe_math_optimizations"
17796   "#"
17797   [(set_attr "type" "fistp")
17798    (set_attr "i387_cw" "ceil")
17799    (set_attr "mode" "<MODE>")])
17800
17801 (define_split
17802   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17803         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17804          UNSPEC_FIST_CEIL))
17805    (use (match_operand:HI 2 "memory_operand" ""))
17806    (use (match_operand:HI 3 "memory_operand" ""))
17807    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17808   "reload_completed"
17809   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17810                                   UNSPEC_FIST_CEIL))
17811               (use (match_dup 2))
17812               (use (match_dup 3))])
17813    (set (match_dup 0) (match_dup 4))]
17814   "")
17815
17816 (define_split
17817   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17818         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17819          UNSPEC_FIST_CEIL))
17820    (use (match_operand:HI 2 "memory_operand" ""))
17821    (use (match_operand:HI 3 "memory_operand" ""))
17822    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17823   "reload_completed"
17824   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17825                                   UNSPEC_FIST_CEIL))
17826               (use (match_dup 2))
17827               (use (match_dup 3))])]
17828   "")
17829
17830 (define_expand "lceilxf<mode>2"
17831   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17832                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17833                     UNSPEC_FIST_CEIL))
17834               (clobber (reg:CC FLAGS_REG))])]
17835   "TARGET_USE_FANCY_MATH_387
17836    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17837    && flag_unsafe_math_optimizations"
17838   "")
17839
17840 (define_expand "lceil<mode>di2"
17841   [(match_operand:DI 0 "nonimmediate_operand" "")
17842    (match_operand:SSEMODEF 1 "register_operand" "")]
17843   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17844    && !flag_trapping_math"
17845 {
17846   ix86_expand_lfloorceil (operand0, operand1, false);
17847   DONE;
17848 })
17849
17850 (define_expand "lceil<mode>si2"
17851   [(match_operand:SI 0 "nonimmediate_operand" "")
17852    (match_operand:SSEMODEF 1 "register_operand" "")]
17853   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17854    && !flag_trapping_math"
17855 {
17856   ix86_expand_lfloorceil (operand0, operand1, false);
17857   DONE;
17858 })
17859
17860 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17861 (define_insn_and_split "frndintxf2_trunc"
17862   [(set (match_operand:XF 0 "register_operand" "=f")
17863         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17864          UNSPEC_FRNDINT_TRUNC))
17865    (clobber (reg:CC FLAGS_REG))]
17866   "TARGET_USE_FANCY_MATH_387
17867    && flag_unsafe_math_optimizations
17868    && !(reload_completed || reload_in_progress)"
17869   "#"
17870   "&& 1"
17871   [(const_int 0)]
17872 {
17873   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17874
17875   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17876   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17877
17878   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17879                                         operands[2], operands[3]));
17880   DONE;
17881 }
17882   [(set_attr "type" "frndint")
17883    (set_attr "i387_cw" "trunc")
17884    (set_attr "mode" "XF")])
17885
17886 (define_insn "frndintxf2_trunc_i387"
17887   [(set (match_operand:XF 0 "register_operand" "=f")
17888         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17889          UNSPEC_FRNDINT_TRUNC))
17890    (use (match_operand:HI 2 "memory_operand" "m"))
17891    (use (match_operand:HI 3 "memory_operand" "m"))]
17892   "TARGET_USE_FANCY_MATH_387
17893    && flag_unsafe_math_optimizations"
17894   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17895   [(set_attr "type" "frndint")
17896    (set_attr "i387_cw" "trunc")
17897    (set_attr "mode" "XF")])
17898
17899 (define_expand "btruncxf2"
17900   [(use (match_operand:XF 0 "register_operand" ""))
17901    (use (match_operand:XF 1 "register_operand" ""))]
17902   "TARGET_USE_FANCY_MATH_387
17903    && flag_unsafe_math_optimizations && !optimize_size"
17904 {
17905   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17906   DONE;
17907 })
17908
17909 (define_expand "btruncdf2"
17910   [(use (match_operand:DF 0 "register_operand" ""))
17911    (use (match_operand:DF 1 "register_operand" ""))]
17912   "((TARGET_USE_FANCY_MATH_387
17913      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17914      && flag_unsafe_math_optimizations)
17915     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17916         && !flag_trapping_math))
17917    && !optimize_size"
17918 {
17919   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17920       && !flag_trapping_math)
17921     {
17922       if (TARGET_64BIT)
17923         ix86_expand_trunc (operand0, operand1);
17924       else
17925         ix86_expand_truncdf_32 (operand0, operand1);
17926     }
17927   else
17928     {
17929       rtx op0 = gen_reg_rtx (XFmode);
17930       rtx op1 = gen_reg_rtx (XFmode);
17931
17932       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17933       emit_insn (gen_frndintxf2_trunc (op0, op1));
17934
17935       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17936     }
17937   DONE;
17938 })
17939
17940 (define_expand "btruncsf2"
17941   [(use (match_operand:SF 0 "register_operand" ""))
17942    (use (match_operand:SF 1 "register_operand" ""))]
17943   "((TARGET_USE_FANCY_MATH_387
17944      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17945      && flag_unsafe_math_optimizations)
17946     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17947         && !flag_trapping_math))
17948    && !optimize_size"
17949 {
17950   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17951       && !flag_trapping_math)
17952     ix86_expand_trunc (operand0, operand1);
17953   else
17954     {
17955       rtx op0 = gen_reg_rtx (XFmode);
17956       rtx op1 = gen_reg_rtx (XFmode);
17957
17958       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17959       emit_insn (gen_frndintxf2_trunc (op0, op1));
17960
17961       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17962     }
17963   DONE;
17964 })
17965
17966 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17967 (define_insn_and_split "frndintxf2_mask_pm"
17968   [(set (match_operand:XF 0 "register_operand" "=f")
17969         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17970          UNSPEC_FRNDINT_MASK_PM))
17971    (clobber (reg:CC FLAGS_REG))]
17972   "TARGET_USE_FANCY_MATH_387
17973    && flag_unsafe_math_optimizations
17974    && !(reload_completed || reload_in_progress)"
17975   "#"
17976   "&& 1"
17977   [(const_int 0)]
17978 {
17979   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17980
17981   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17982   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17983
17984   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17985                                           operands[2], operands[3]));
17986   DONE;
17987 }
17988   [(set_attr "type" "frndint")
17989    (set_attr "i387_cw" "mask_pm")
17990    (set_attr "mode" "XF")])
17991
17992 (define_insn "frndintxf2_mask_pm_i387"
17993   [(set (match_operand:XF 0 "register_operand" "=f")
17994         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17995          UNSPEC_FRNDINT_MASK_PM))
17996    (use (match_operand:HI 2 "memory_operand" "m"))
17997    (use (match_operand:HI 3 "memory_operand" "m"))]
17998   "TARGET_USE_FANCY_MATH_387
17999    && flag_unsafe_math_optimizations"
18000   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18001   [(set_attr "type" "frndint")
18002    (set_attr "i387_cw" "mask_pm")
18003    (set_attr "mode" "XF")])
18004
18005 (define_expand "nearbyintxf2"
18006   [(use (match_operand:XF 0 "register_operand" ""))
18007    (use (match_operand:XF 1 "register_operand" ""))]
18008   "TARGET_USE_FANCY_MATH_387
18009    && flag_unsafe_math_optimizations"
18010 {
18011   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18012
18013   DONE;
18014 })
18015
18016 (define_expand "nearbyintdf2"
18017   [(use (match_operand:DF 0 "register_operand" ""))
18018    (use (match_operand:DF 1 "register_operand" ""))]
18019   "TARGET_USE_FANCY_MATH_387
18020    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18021    && flag_unsafe_math_optimizations"
18022 {
18023   rtx op0 = gen_reg_rtx (XFmode);
18024   rtx op1 = gen_reg_rtx (XFmode);
18025
18026   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18027   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18028
18029   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18030   DONE;
18031 })
18032
18033 (define_expand "nearbyintsf2"
18034   [(use (match_operand:SF 0 "register_operand" ""))
18035    (use (match_operand:SF 1 "register_operand" ""))]
18036   "TARGET_USE_FANCY_MATH_387
18037    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18038    && flag_unsafe_math_optimizations"
18039 {
18040   rtx op0 = gen_reg_rtx (XFmode);
18041   rtx op1 = gen_reg_rtx (XFmode);
18042
18043   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18044   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18045
18046   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18047   DONE;
18048 })
18049
18050 (define_insn "fxam<mode>2_i387"
18051   [(set (match_operand:HI 0 "register_operand" "=a")
18052         (unspec:HI
18053           [(match_operand:X87MODEF 1 "register_operand" "f")]
18054           UNSPEC_FXAM))]
18055   "TARGET_USE_FANCY_MATH_387"
18056   "fxam\n\tfnstsw\t%0"
18057   [(set_attr "type" "multi")
18058    (set_attr "unit" "i387")
18059    (set_attr "mode" "<MODE>")])
18060
18061 (define_expand "isinf<mode>2"
18062   [(use (match_operand:SI 0 "register_operand" ""))
18063    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18064   "TARGET_USE_FANCY_MATH_387
18065   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18066       || TARGET_MIX_SSE_I387)"
18067 {
18068   rtx mask = GEN_INT (0x45);
18069   rtx val = GEN_INT (0x05);
18070
18071   rtx cond;
18072
18073   rtx scratch = gen_reg_rtx (HImode);
18074   rtx res = gen_reg_rtx (QImode);
18075
18076   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18077   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18078   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18079   cond = gen_rtx_fmt_ee (EQ, QImode,
18080                          gen_rtx_REG (CCmode, FLAGS_REG),
18081                          const0_rtx);
18082   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18083   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18084   DONE;
18085 })
18086
18087 \f
18088 ;; Block operation instructions
18089
18090 (define_expand "movmemsi"
18091   [(use (match_operand:BLK 0 "memory_operand" ""))
18092    (use (match_operand:BLK 1 "memory_operand" ""))
18093    (use (match_operand:SI 2 "nonmemory_operand" ""))
18094    (use (match_operand:SI 3 "const_int_operand" ""))
18095    (use (match_operand:SI 4 "const_int_operand" ""))
18096    (use (match_operand:SI 5 "const_int_operand" ""))]
18097   ""
18098 {
18099  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18100                          operands[4], operands[5]))
18101    DONE;
18102  else
18103    FAIL;
18104 })
18105
18106 (define_expand "movmemdi"
18107   [(use (match_operand:BLK 0 "memory_operand" ""))
18108    (use (match_operand:BLK 1 "memory_operand" ""))
18109    (use (match_operand:DI 2 "nonmemory_operand" ""))
18110    (use (match_operand:DI 3 "const_int_operand" ""))
18111    (use (match_operand:SI 4 "const_int_operand" ""))
18112    (use (match_operand:SI 5 "const_int_operand" ""))]
18113   "TARGET_64BIT"
18114 {
18115  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18116                          operands[4], operands[5]))
18117    DONE;
18118  else
18119    FAIL;
18120 })
18121
18122 ;; Most CPUs don't like single string operations
18123 ;; Handle this case here to simplify previous expander.
18124
18125 (define_expand "strmov"
18126   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18127    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18128    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18129               (clobber (reg:CC FLAGS_REG))])
18130    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18131               (clobber (reg:CC FLAGS_REG))])]
18132   ""
18133 {
18134   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18135
18136   /* If .md ever supports :P for Pmode, these can be directly
18137      in the pattern above.  */
18138   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18139   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18140
18141   if (TARGET_SINGLE_STRINGOP || optimize_size)
18142     {
18143       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18144                                       operands[2], operands[3],
18145                                       operands[5], operands[6]));
18146       DONE;
18147     }
18148
18149   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18150 })
18151
18152 (define_expand "strmov_singleop"
18153   [(parallel [(set (match_operand 1 "memory_operand" "")
18154                    (match_operand 3 "memory_operand" ""))
18155               (set (match_operand 0 "register_operand" "")
18156                    (match_operand 4 "" ""))
18157               (set (match_operand 2 "register_operand" "")
18158                    (match_operand 5 "" ""))])]
18159   "TARGET_SINGLE_STRINGOP || optimize_size"
18160   "")
18161
18162 (define_insn "*strmovdi_rex_1"
18163   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18164         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18165    (set (match_operand:DI 0 "register_operand" "=D")
18166         (plus:DI (match_dup 2)
18167                  (const_int 8)))
18168    (set (match_operand:DI 1 "register_operand" "=S")
18169         (plus:DI (match_dup 3)
18170                  (const_int 8)))]
18171   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18172   "movsq"
18173   [(set_attr "type" "str")
18174    (set_attr "mode" "DI")
18175    (set_attr "memory" "both")])
18176
18177 (define_insn "*strmovsi_1"
18178   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18179         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18180    (set (match_operand:SI 0 "register_operand" "=D")
18181         (plus:SI (match_dup 2)
18182                  (const_int 4)))
18183    (set (match_operand:SI 1 "register_operand" "=S")
18184         (plus:SI (match_dup 3)
18185                  (const_int 4)))]
18186   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18187   "{movsl|movsd}"
18188   [(set_attr "type" "str")
18189    (set_attr "mode" "SI")
18190    (set_attr "memory" "both")])
18191
18192 (define_insn "*strmovsi_rex_1"
18193   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18194         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18195    (set (match_operand:DI 0 "register_operand" "=D")
18196         (plus:DI (match_dup 2)
18197                  (const_int 4)))
18198    (set (match_operand:DI 1 "register_operand" "=S")
18199         (plus:DI (match_dup 3)
18200                  (const_int 4)))]
18201   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18202   "{movsl|movsd}"
18203   [(set_attr "type" "str")
18204    (set_attr "mode" "SI")
18205    (set_attr "memory" "both")])
18206
18207 (define_insn "*strmovhi_1"
18208   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18209         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18210    (set (match_operand:SI 0 "register_operand" "=D")
18211         (plus:SI (match_dup 2)
18212                  (const_int 2)))
18213    (set (match_operand:SI 1 "register_operand" "=S")
18214         (plus:SI (match_dup 3)
18215                  (const_int 2)))]
18216   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18217   "movsw"
18218   [(set_attr "type" "str")
18219    (set_attr "memory" "both")
18220    (set_attr "mode" "HI")])
18221
18222 (define_insn "*strmovhi_rex_1"
18223   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18224         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18225    (set (match_operand:DI 0 "register_operand" "=D")
18226         (plus:DI (match_dup 2)
18227                  (const_int 2)))
18228    (set (match_operand:DI 1 "register_operand" "=S")
18229         (plus:DI (match_dup 3)
18230                  (const_int 2)))]
18231   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18232   "movsw"
18233   [(set_attr "type" "str")
18234    (set_attr "memory" "both")
18235    (set_attr "mode" "HI")])
18236
18237 (define_insn "*strmovqi_1"
18238   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18239         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18240    (set (match_operand:SI 0 "register_operand" "=D")
18241         (plus:SI (match_dup 2)
18242                  (const_int 1)))
18243    (set (match_operand:SI 1 "register_operand" "=S")
18244         (plus:SI (match_dup 3)
18245                  (const_int 1)))]
18246   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18247   "movsb"
18248   [(set_attr "type" "str")
18249    (set_attr "memory" "both")
18250    (set_attr "mode" "QI")])
18251
18252 (define_insn "*strmovqi_rex_1"
18253   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18254         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18255    (set (match_operand:DI 0 "register_operand" "=D")
18256         (plus:DI (match_dup 2)
18257                  (const_int 1)))
18258    (set (match_operand:DI 1 "register_operand" "=S")
18259         (plus:DI (match_dup 3)
18260                  (const_int 1)))]
18261   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18262   "movsb"
18263   [(set_attr "type" "str")
18264    (set_attr "memory" "both")
18265    (set_attr "mode" "QI")])
18266
18267 (define_expand "rep_mov"
18268   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18269               (set (match_operand 0 "register_operand" "")
18270                    (match_operand 5 "" ""))
18271               (set (match_operand 2 "register_operand" "")
18272                    (match_operand 6 "" ""))
18273               (set (match_operand 1 "memory_operand" "")
18274                    (match_operand 3 "memory_operand" ""))
18275               (use (match_dup 4))])]
18276   ""
18277   "")
18278
18279 (define_insn "*rep_movdi_rex64"
18280   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18281    (set (match_operand:DI 0 "register_operand" "=D")
18282         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18283                             (const_int 3))
18284                  (match_operand:DI 3 "register_operand" "0")))
18285    (set (match_operand:DI 1 "register_operand" "=S")
18286         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18287                  (match_operand:DI 4 "register_operand" "1")))
18288    (set (mem:BLK (match_dup 3))
18289         (mem:BLK (match_dup 4)))
18290    (use (match_dup 5))]
18291   "TARGET_64BIT"
18292   "{rep\;movsq|rep movsq}"
18293   [(set_attr "type" "str")
18294    (set_attr "prefix_rep" "1")
18295    (set_attr "memory" "both")
18296    (set_attr "mode" "DI")])
18297
18298 (define_insn "*rep_movsi"
18299   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18300    (set (match_operand:SI 0 "register_operand" "=D")
18301         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18302                             (const_int 2))
18303                  (match_operand:SI 3 "register_operand" "0")))
18304    (set (match_operand:SI 1 "register_operand" "=S")
18305         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18306                  (match_operand:SI 4 "register_operand" "1")))
18307    (set (mem:BLK (match_dup 3))
18308         (mem:BLK (match_dup 4)))
18309    (use (match_dup 5))]
18310   "!TARGET_64BIT"
18311   "{rep\;movsl|rep movsd}"
18312   [(set_attr "type" "str")
18313    (set_attr "prefix_rep" "1")
18314    (set_attr "memory" "both")
18315    (set_attr "mode" "SI")])
18316
18317 (define_insn "*rep_movsi_rex64"
18318   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18319    (set (match_operand:DI 0 "register_operand" "=D")
18320         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18321                             (const_int 2))
18322                  (match_operand:DI 3 "register_operand" "0")))
18323    (set (match_operand:DI 1 "register_operand" "=S")
18324         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18325                  (match_operand:DI 4 "register_operand" "1")))
18326    (set (mem:BLK (match_dup 3))
18327         (mem:BLK (match_dup 4)))
18328    (use (match_dup 5))]
18329   "TARGET_64BIT"
18330   "{rep\;movsl|rep movsd}"
18331   [(set_attr "type" "str")
18332    (set_attr "prefix_rep" "1")
18333    (set_attr "memory" "both")
18334    (set_attr "mode" "SI")])
18335
18336 (define_insn "*rep_movqi"
18337   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18338    (set (match_operand:SI 0 "register_operand" "=D")
18339         (plus:SI (match_operand:SI 3 "register_operand" "0")
18340                  (match_operand:SI 5 "register_operand" "2")))
18341    (set (match_operand:SI 1 "register_operand" "=S")
18342         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18343    (set (mem:BLK (match_dup 3))
18344         (mem:BLK (match_dup 4)))
18345    (use (match_dup 5))]
18346   "!TARGET_64BIT"
18347   "{rep\;movsb|rep movsb}"
18348   [(set_attr "type" "str")
18349    (set_attr "prefix_rep" "1")
18350    (set_attr "memory" "both")
18351    (set_attr "mode" "SI")])
18352
18353 (define_insn "*rep_movqi_rex64"
18354   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18355    (set (match_operand:DI 0 "register_operand" "=D")
18356         (plus:DI (match_operand:DI 3 "register_operand" "0")
18357                  (match_operand:DI 5 "register_operand" "2")))
18358    (set (match_operand:DI 1 "register_operand" "=S")
18359         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18360    (set (mem:BLK (match_dup 3))
18361         (mem:BLK (match_dup 4)))
18362    (use (match_dup 5))]
18363   "TARGET_64BIT"
18364   "{rep\;movsb|rep movsb}"
18365   [(set_attr "type" "str")
18366    (set_attr "prefix_rep" "1")
18367    (set_attr "memory" "both")
18368    (set_attr "mode" "SI")])
18369
18370 (define_expand "setmemsi"
18371    [(use (match_operand:BLK 0 "memory_operand" ""))
18372     (use (match_operand:SI 1 "nonmemory_operand" ""))
18373     (use (match_operand 2 "const_int_operand" ""))
18374     (use (match_operand 3 "const_int_operand" ""))
18375     (use (match_operand:SI 4 "const_int_operand" ""))
18376     (use (match_operand:SI 5 "const_int_operand" ""))]
18377   ""
18378 {
18379  if (ix86_expand_setmem (operands[0], operands[1],
18380                          operands[2], operands[3],
18381                          operands[4], operands[5]))
18382    DONE;
18383  else
18384    FAIL;
18385 })
18386
18387 (define_expand "setmemdi"
18388    [(use (match_operand:BLK 0 "memory_operand" ""))
18389     (use (match_operand:DI 1 "nonmemory_operand" ""))
18390     (use (match_operand 2 "const_int_operand" ""))
18391     (use (match_operand 3 "const_int_operand" ""))
18392     (use (match_operand 4 "const_int_operand" ""))
18393     (use (match_operand 5 "const_int_operand" ""))]
18394   "TARGET_64BIT"
18395 {
18396  if (ix86_expand_setmem (operands[0], operands[1],
18397                          operands[2], operands[3],
18398                          operands[4], operands[5]))
18399    DONE;
18400  else
18401    FAIL;
18402 })
18403
18404 ;; Most CPUs don't like single string operations
18405 ;; Handle this case here to simplify previous expander.
18406
18407 (define_expand "strset"
18408   [(set (match_operand 1 "memory_operand" "")
18409         (match_operand 2 "register_operand" ""))
18410    (parallel [(set (match_operand 0 "register_operand" "")
18411                    (match_dup 3))
18412               (clobber (reg:CC FLAGS_REG))])]
18413   ""
18414 {
18415   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18416     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18417
18418   /* If .md ever supports :P for Pmode, this can be directly
18419      in the pattern above.  */
18420   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18421                               GEN_INT (GET_MODE_SIZE (GET_MODE
18422                                                       (operands[2]))));
18423   if (TARGET_SINGLE_STRINGOP || optimize_size)
18424     {
18425       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18426                                       operands[3]));
18427       DONE;
18428     }
18429 })
18430
18431 (define_expand "strset_singleop"
18432   [(parallel [(set (match_operand 1 "memory_operand" "")
18433                    (match_operand 2 "register_operand" ""))
18434               (set (match_operand 0 "register_operand" "")
18435                    (match_operand 3 "" ""))])]
18436   "TARGET_SINGLE_STRINGOP || optimize_size"
18437   "")
18438
18439 (define_insn "*strsetdi_rex_1"
18440   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18441         (match_operand:DI 2 "register_operand" "a"))
18442    (set (match_operand:DI 0 "register_operand" "=D")
18443         (plus:DI (match_dup 1)
18444                  (const_int 8)))]
18445   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18446   "stosq"
18447   [(set_attr "type" "str")
18448    (set_attr "memory" "store")
18449    (set_attr "mode" "DI")])
18450
18451 (define_insn "*strsetsi_1"
18452   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18453         (match_operand:SI 2 "register_operand" "a"))
18454    (set (match_operand:SI 0 "register_operand" "=D")
18455         (plus:SI (match_dup 1)
18456                  (const_int 4)))]
18457   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18458   "{stosl|stosd}"
18459   [(set_attr "type" "str")
18460    (set_attr "memory" "store")
18461    (set_attr "mode" "SI")])
18462
18463 (define_insn "*strsetsi_rex_1"
18464   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18465         (match_operand:SI 2 "register_operand" "a"))
18466    (set (match_operand:DI 0 "register_operand" "=D")
18467         (plus:DI (match_dup 1)
18468                  (const_int 4)))]
18469   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18470   "{stosl|stosd}"
18471   [(set_attr "type" "str")
18472    (set_attr "memory" "store")
18473    (set_attr "mode" "SI")])
18474
18475 (define_insn "*strsethi_1"
18476   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18477         (match_operand:HI 2 "register_operand" "a"))
18478    (set (match_operand:SI 0 "register_operand" "=D")
18479         (plus:SI (match_dup 1)
18480                  (const_int 2)))]
18481   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18482   "stosw"
18483   [(set_attr "type" "str")
18484    (set_attr "memory" "store")
18485    (set_attr "mode" "HI")])
18486
18487 (define_insn "*strsethi_rex_1"
18488   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18489         (match_operand:HI 2 "register_operand" "a"))
18490    (set (match_operand:DI 0 "register_operand" "=D")
18491         (plus:DI (match_dup 1)
18492                  (const_int 2)))]
18493   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18494   "stosw"
18495   [(set_attr "type" "str")
18496    (set_attr "memory" "store")
18497    (set_attr "mode" "HI")])
18498
18499 (define_insn "*strsetqi_1"
18500   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18501         (match_operand:QI 2 "register_operand" "a"))
18502    (set (match_operand:SI 0 "register_operand" "=D")
18503         (plus:SI (match_dup 1)
18504                  (const_int 1)))]
18505   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18506   "stosb"
18507   [(set_attr "type" "str")
18508    (set_attr "memory" "store")
18509    (set_attr "mode" "QI")])
18510
18511 (define_insn "*strsetqi_rex_1"
18512   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18513         (match_operand:QI 2 "register_operand" "a"))
18514    (set (match_operand:DI 0 "register_operand" "=D")
18515         (plus:DI (match_dup 1)
18516                  (const_int 1)))]
18517   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18518   "stosb"
18519   [(set_attr "type" "str")
18520    (set_attr "memory" "store")
18521    (set_attr "mode" "QI")])
18522
18523 (define_expand "rep_stos"
18524   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18525               (set (match_operand 0 "register_operand" "")
18526                    (match_operand 4 "" ""))
18527               (set (match_operand 2 "memory_operand" "") (const_int 0))
18528               (use (match_operand 3 "register_operand" ""))
18529               (use (match_dup 1))])]
18530   ""
18531   "")
18532
18533 (define_insn "*rep_stosdi_rex64"
18534   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18535    (set (match_operand:DI 0 "register_operand" "=D")
18536         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18537                             (const_int 3))
18538                  (match_operand:DI 3 "register_operand" "0")))
18539    (set (mem:BLK (match_dup 3))
18540         (const_int 0))
18541    (use (match_operand:DI 2 "register_operand" "a"))
18542    (use (match_dup 4))]
18543   "TARGET_64BIT"
18544   "{rep\;stosq|rep stosq}"
18545   [(set_attr "type" "str")
18546    (set_attr "prefix_rep" "1")
18547    (set_attr "memory" "store")
18548    (set_attr "mode" "DI")])
18549
18550 (define_insn "*rep_stossi"
18551   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18552    (set (match_operand:SI 0 "register_operand" "=D")
18553         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18554                             (const_int 2))
18555                  (match_operand:SI 3 "register_operand" "0")))
18556    (set (mem:BLK (match_dup 3))
18557         (const_int 0))
18558    (use (match_operand:SI 2 "register_operand" "a"))
18559    (use (match_dup 4))]
18560   "!TARGET_64BIT"
18561   "{rep\;stosl|rep stosd}"
18562   [(set_attr "type" "str")
18563    (set_attr "prefix_rep" "1")
18564    (set_attr "memory" "store")
18565    (set_attr "mode" "SI")])
18566
18567 (define_insn "*rep_stossi_rex64"
18568   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18569    (set (match_operand:DI 0 "register_operand" "=D")
18570         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18571                             (const_int 2))
18572                  (match_operand:DI 3 "register_operand" "0")))
18573    (set (mem:BLK (match_dup 3))
18574         (const_int 0))
18575    (use (match_operand:SI 2 "register_operand" "a"))
18576    (use (match_dup 4))]
18577   "TARGET_64BIT"
18578   "{rep\;stosl|rep stosd}"
18579   [(set_attr "type" "str")
18580    (set_attr "prefix_rep" "1")
18581    (set_attr "memory" "store")
18582    (set_attr "mode" "SI")])
18583
18584 (define_insn "*rep_stosqi"
18585   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18586    (set (match_operand:SI 0 "register_operand" "=D")
18587         (plus:SI (match_operand:SI 3 "register_operand" "0")
18588                  (match_operand:SI 4 "register_operand" "1")))
18589    (set (mem:BLK (match_dup 3))
18590         (const_int 0))
18591    (use (match_operand:QI 2 "register_operand" "a"))
18592    (use (match_dup 4))]
18593   "!TARGET_64BIT"
18594   "{rep\;stosb|rep stosb}"
18595   [(set_attr "type" "str")
18596    (set_attr "prefix_rep" "1")
18597    (set_attr "memory" "store")
18598    (set_attr "mode" "QI")])
18599
18600 (define_insn "*rep_stosqi_rex64"
18601   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18602    (set (match_operand:DI 0 "register_operand" "=D")
18603         (plus:DI (match_operand:DI 3 "register_operand" "0")
18604                  (match_operand:DI 4 "register_operand" "1")))
18605    (set (mem:BLK (match_dup 3))
18606         (const_int 0))
18607    (use (match_operand:QI 2 "register_operand" "a"))
18608    (use (match_dup 4))]
18609   "TARGET_64BIT"
18610   "{rep\;stosb|rep stosb}"
18611   [(set_attr "type" "str")
18612    (set_attr "prefix_rep" "1")
18613    (set_attr "memory" "store")
18614    (set_attr "mode" "QI")])
18615
18616 (define_expand "cmpstrnsi"
18617   [(set (match_operand:SI 0 "register_operand" "")
18618         (compare:SI (match_operand:BLK 1 "general_operand" "")
18619                     (match_operand:BLK 2 "general_operand" "")))
18620    (use (match_operand 3 "general_operand" ""))
18621    (use (match_operand 4 "immediate_operand" ""))]
18622   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18623 {
18624   rtx addr1, addr2, out, outlow, count, countreg, align;
18625
18626   /* Can't use this if the user has appropriated esi or edi.  */
18627   if (global_regs[4] || global_regs[5])
18628     FAIL;
18629
18630   out = operands[0];
18631   if (!REG_P (out))
18632     out = gen_reg_rtx (SImode);
18633
18634   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18635   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18636   if (addr1 != XEXP (operands[1], 0))
18637     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18638   if (addr2 != XEXP (operands[2], 0))
18639     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18640
18641   count = operands[3];
18642   countreg = ix86_zero_extend_to_Pmode (count);
18643
18644   /* %%% Iff we are testing strict equality, we can use known alignment
18645      to good advantage.  This may be possible with combine, particularly
18646      once cc0 is dead.  */
18647   align = operands[4];
18648
18649   if (CONST_INT_P (count))
18650     {
18651       if (INTVAL (count) == 0)
18652         {
18653           emit_move_insn (operands[0], const0_rtx);
18654           DONE;
18655         }
18656       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18657                                      operands[1], operands[2]));
18658     }
18659   else
18660     {
18661       if (TARGET_64BIT)
18662         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18663       else
18664         emit_insn (gen_cmpsi_1 (countreg, countreg));
18665       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18666                                   operands[1], operands[2]));
18667     }
18668
18669   outlow = gen_lowpart (QImode, out);
18670   emit_insn (gen_cmpintqi (outlow));
18671   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18672
18673   if (operands[0] != out)
18674     emit_move_insn (operands[0], out);
18675
18676   DONE;
18677 })
18678
18679 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18680
18681 (define_expand "cmpintqi"
18682   [(set (match_dup 1)
18683         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18684    (set (match_dup 2)
18685         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18686    (parallel [(set (match_operand:QI 0 "register_operand" "")
18687                    (minus:QI (match_dup 1)
18688                              (match_dup 2)))
18689               (clobber (reg:CC FLAGS_REG))])]
18690   ""
18691   "operands[1] = gen_reg_rtx (QImode);
18692    operands[2] = gen_reg_rtx (QImode);")
18693
18694 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18695 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18696
18697 (define_expand "cmpstrnqi_nz_1"
18698   [(parallel [(set (reg:CC FLAGS_REG)
18699                    (compare:CC (match_operand 4 "memory_operand" "")
18700                                (match_operand 5 "memory_operand" "")))
18701               (use (match_operand 2 "register_operand" ""))
18702               (use (match_operand:SI 3 "immediate_operand" ""))
18703               (clobber (match_operand 0 "register_operand" ""))
18704               (clobber (match_operand 1 "register_operand" ""))
18705               (clobber (match_dup 2))])]
18706   ""
18707   "")
18708
18709 (define_insn "*cmpstrnqi_nz_1"
18710   [(set (reg:CC FLAGS_REG)
18711         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18712                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18713    (use (match_operand:SI 6 "register_operand" "2"))
18714    (use (match_operand:SI 3 "immediate_operand" "i"))
18715    (clobber (match_operand:SI 0 "register_operand" "=S"))
18716    (clobber (match_operand:SI 1 "register_operand" "=D"))
18717    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18718   "!TARGET_64BIT"
18719   "repz{\;| }cmpsb"
18720   [(set_attr "type" "str")
18721    (set_attr "mode" "QI")
18722    (set_attr "prefix_rep" "1")])
18723
18724 (define_insn "*cmpstrnqi_nz_rex_1"
18725   [(set (reg:CC FLAGS_REG)
18726         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18727                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18728    (use (match_operand:DI 6 "register_operand" "2"))
18729    (use (match_operand:SI 3 "immediate_operand" "i"))
18730    (clobber (match_operand:DI 0 "register_operand" "=S"))
18731    (clobber (match_operand:DI 1 "register_operand" "=D"))
18732    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18733   "TARGET_64BIT"
18734   "repz{\;| }cmpsb"
18735   [(set_attr "type" "str")
18736    (set_attr "mode" "QI")
18737    (set_attr "prefix_rep" "1")])
18738
18739 ;; The same, but the count is not known to not be zero.
18740
18741 (define_expand "cmpstrnqi_1"
18742   [(parallel [(set (reg:CC FLAGS_REG)
18743                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18744                                      (const_int 0))
18745                   (compare:CC (match_operand 4 "memory_operand" "")
18746                               (match_operand 5 "memory_operand" ""))
18747                   (const_int 0)))
18748               (use (match_operand:SI 3 "immediate_operand" ""))
18749               (use (reg:CC FLAGS_REG))
18750               (clobber (match_operand 0 "register_operand" ""))
18751               (clobber (match_operand 1 "register_operand" ""))
18752               (clobber (match_dup 2))])]
18753   ""
18754   "")
18755
18756 (define_insn "*cmpstrnqi_1"
18757   [(set (reg:CC FLAGS_REG)
18758         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18759                              (const_int 0))
18760           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18761                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18762           (const_int 0)))
18763    (use (match_operand:SI 3 "immediate_operand" "i"))
18764    (use (reg:CC FLAGS_REG))
18765    (clobber (match_operand:SI 0 "register_operand" "=S"))
18766    (clobber (match_operand:SI 1 "register_operand" "=D"))
18767    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18768   "!TARGET_64BIT"
18769   "repz{\;| }cmpsb"
18770   [(set_attr "type" "str")
18771    (set_attr "mode" "QI")
18772    (set_attr "prefix_rep" "1")])
18773
18774 (define_insn "*cmpstrnqi_rex_1"
18775   [(set (reg:CC FLAGS_REG)
18776         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18777                              (const_int 0))
18778           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18779                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18780           (const_int 0)))
18781    (use (match_operand:SI 3 "immediate_operand" "i"))
18782    (use (reg:CC FLAGS_REG))
18783    (clobber (match_operand:DI 0 "register_operand" "=S"))
18784    (clobber (match_operand:DI 1 "register_operand" "=D"))
18785    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18786   "TARGET_64BIT"
18787   "repz{\;| }cmpsb"
18788   [(set_attr "type" "str")
18789    (set_attr "mode" "QI")
18790    (set_attr "prefix_rep" "1")])
18791
18792 (define_expand "strlensi"
18793   [(set (match_operand:SI 0 "register_operand" "")
18794         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18795                     (match_operand:QI 2 "immediate_operand" "")
18796                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18797   ""
18798 {
18799  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18800    DONE;
18801  else
18802    FAIL;
18803 })
18804
18805 (define_expand "strlendi"
18806   [(set (match_operand:DI 0 "register_operand" "")
18807         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18808                     (match_operand:QI 2 "immediate_operand" "")
18809                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18810   ""
18811 {
18812  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18813    DONE;
18814  else
18815    FAIL;
18816 })
18817
18818 (define_expand "strlenqi_1"
18819   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18820               (clobber (match_operand 1 "register_operand" ""))
18821               (clobber (reg:CC FLAGS_REG))])]
18822   ""
18823   "")
18824
18825 (define_insn "*strlenqi_1"
18826   [(set (match_operand:SI 0 "register_operand" "=&c")
18827         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18828                     (match_operand:QI 2 "register_operand" "a")
18829                     (match_operand:SI 3 "immediate_operand" "i")
18830                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18831    (clobber (match_operand:SI 1 "register_operand" "=D"))
18832    (clobber (reg:CC FLAGS_REG))]
18833   "!TARGET_64BIT"
18834   "repnz{\;| }scasb"
18835   [(set_attr "type" "str")
18836    (set_attr "mode" "QI")
18837    (set_attr "prefix_rep" "1")])
18838
18839 (define_insn "*strlenqi_rex_1"
18840   [(set (match_operand:DI 0 "register_operand" "=&c")
18841         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18842                     (match_operand:QI 2 "register_operand" "a")
18843                     (match_operand:DI 3 "immediate_operand" "i")
18844                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18845    (clobber (match_operand:DI 1 "register_operand" "=D"))
18846    (clobber (reg:CC FLAGS_REG))]
18847   "TARGET_64BIT"
18848   "repnz{\;| }scasb"
18849   [(set_attr "type" "str")
18850    (set_attr "mode" "QI")
18851    (set_attr "prefix_rep" "1")])
18852
18853 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18854 ;; handled in combine, but it is not currently up to the task.
18855 ;; When used for their truth value, the cmpstrn* expanders generate
18856 ;; code like this:
18857 ;;
18858 ;;   repz cmpsb
18859 ;;   seta       %al
18860 ;;   setb       %dl
18861 ;;   cmpb       %al, %dl
18862 ;;   jcc        label
18863 ;;
18864 ;; The intermediate three instructions are unnecessary.
18865
18866 ;; This one handles cmpstrn*_nz_1...
18867 (define_peephole2
18868   [(parallel[
18869      (set (reg:CC FLAGS_REG)
18870           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18871                       (mem:BLK (match_operand 5 "register_operand" ""))))
18872      (use (match_operand 6 "register_operand" ""))
18873      (use (match_operand:SI 3 "immediate_operand" ""))
18874      (clobber (match_operand 0 "register_operand" ""))
18875      (clobber (match_operand 1 "register_operand" ""))
18876      (clobber (match_operand 2 "register_operand" ""))])
18877    (set (match_operand:QI 7 "register_operand" "")
18878         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18879    (set (match_operand:QI 8 "register_operand" "")
18880         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18881    (set (reg FLAGS_REG)
18882         (compare (match_dup 7) (match_dup 8)))
18883   ]
18884   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18885   [(parallel[
18886      (set (reg:CC FLAGS_REG)
18887           (compare:CC (mem:BLK (match_dup 4))
18888                       (mem:BLK (match_dup 5))))
18889      (use (match_dup 6))
18890      (use (match_dup 3))
18891      (clobber (match_dup 0))
18892      (clobber (match_dup 1))
18893      (clobber (match_dup 2))])]
18894   "")
18895
18896 ;; ...and this one handles cmpstrn*_1.
18897 (define_peephole2
18898   [(parallel[
18899      (set (reg:CC FLAGS_REG)
18900           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18901                                (const_int 0))
18902             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18903                         (mem:BLK (match_operand 5 "register_operand" "")))
18904             (const_int 0)))
18905      (use (match_operand:SI 3 "immediate_operand" ""))
18906      (use (reg:CC FLAGS_REG))
18907      (clobber (match_operand 0 "register_operand" ""))
18908      (clobber (match_operand 1 "register_operand" ""))
18909      (clobber (match_operand 2 "register_operand" ""))])
18910    (set (match_operand:QI 7 "register_operand" "")
18911         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18912    (set (match_operand:QI 8 "register_operand" "")
18913         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18914    (set (reg FLAGS_REG)
18915         (compare (match_dup 7) (match_dup 8)))
18916   ]
18917   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18918   [(parallel[
18919      (set (reg:CC FLAGS_REG)
18920           (if_then_else:CC (ne (match_dup 6)
18921                                (const_int 0))
18922             (compare:CC (mem:BLK (match_dup 4))
18923                         (mem:BLK (match_dup 5)))
18924             (const_int 0)))
18925      (use (match_dup 3))
18926      (use (reg:CC FLAGS_REG))
18927      (clobber (match_dup 0))
18928      (clobber (match_dup 1))
18929      (clobber (match_dup 2))])]
18930   "")
18931
18932
18933 \f
18934 ;; Conditional move instructions.
18935
18936 (define_expand "movdicc"
18937   [(set (match_operand:DI 0 "register_operand" "")
18938         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18939                          (match_operand:DI 2 "general_operand" "")
18940                          (match_operand:DI 3 "general_operand" "")))]
18941   "TARGET_64BIT"
18942   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18943
18944 (define_insn "x86_movdicc_0_m1_rex64"
18945   [(set (match_operand:DI 0 "register_operand" "=r")
18946         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18947           (const_int -1)
18948           (const_int 0)))
18949    (clobber (reg:CC FLAGS_REG))]
18950   "TARGET_64BIT"
18951   "sbb{q}\t%0, %0"
18952   ; Since we don't have the proper number of operands for an alu insn,
18953   ; fill in all the blanks.
18954   [(set_attr "type" "alu")
18955    (set_attr "pent_pair" "pu")
18956    (set_attr "memory" "none")
18957    (set_attr "imm_disp" "false")
18958    (set_attr "mode" "DI")
18959    (set_attr "length_immediate" "0")])
18960
18961 (define_insn "*movdicc_c_rex64"
18962   [(set (match_operand:DI 0 "register_operand" "=r,r")
18963         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18964                                 [(reg FLAGS_REG) (const_int 0)])
18965                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18966                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18967   "TARGET_64BIT && TARGET_CMOVE
18968    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18969   "@
18970    cmov%O2%C1\t{%2, %0|%0, %2}
18971    cmov%O2%c1\t{%3, %0|%0, %3}"
18972   [(set_attr "type" "icmov")
18973    (set_attr "mode" "DI")])
18974
18975 (define_expand "movsicc"
18976   [(set (match_operand:SI 0 "register_operand" "")
18977         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18978                          (match_operand:SI 2 "general_operand" "")
18979                          (match_operand:SI 3 "general_operand" "")))]
18980   ""
18981   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18982
18983 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18984 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18985 ;; So just document what we're doing explicitly.
18986
18987 (define_insn "x86_movsicc_0_m1"
18988   [(set (match_operand:SI 0 "register_operand" "=r")
18989         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18990           (const_int -1)
18991           (const_int 0)))
18992    (clobber (reg:CC FLAGS_REG))]
18993   ""
18994   "sbb{l}\t%0, %0"
18995   ; Since we don't have the proper number of operands for an alu insn,
18996   ; fill in all the blanks.
18997   [(set_attr "type" "alu")
18998    (set_attr "pent_pair" "pu")
18999    (set_attr "memory" "none")
19000    (set_attr "imm_disp" "false")
19001    (set_attr "mode" "SI")
19002    (set_attr "length_immediate" "0")])
19003
19004 (define_insn "*movsicc_noc"
19005   [(set (match_operand:SI 0 "register_operand" "=r,r")
19006         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19007                                 [(reg FLAGS_REG) (const_int 0)])
19008                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19009                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19010   "TARGET_CMOVE
19011    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19012   "@
19013    cmov%O2%C1\t{%2, %0|%0, %2}
19014    cmov%O2%c1\t{%3, %0|%0, %3}"
19015   [(set_attr "type" "icmov")
19016    (set_attr "mode" "SI")])
19017
19018 (define_expand "movhicc"
19019   [(set (match_operand:HI 0 "register_operand" "")
19020         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19021                          (match_operand:HI 2 "general_operand" "")
19022                          (match_operand:HI 3 "general_operand" "")))]
19023   "TARGET_HIMODE_MATH"
19024   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19025
19026 (define_insn "*movhicc_noc"
19027   [(set (match_operand:HI 0 "register_operand" "=r,r")
19028         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19029                                 [(reg FLAGS_REG) (const_int 0)])
19030                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19031                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19032   "TARGET_CMOVE
19033    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19034   "@
19035    cmov%O2%C1\t{%2, %0|%0, %2}
19036    cmov%O2%c1\t{%3, %0|%0, %3}"
19037   [(set_attr "type" "icmov")
19038    (set_attr "mode" "HI")])
19039
19040 (define_expand "movqicc"
19041   [(set (match_operand:QI 0 "register_operand" "")
19042         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19043                          (match_operand:QI 2 "general_operand" "")
19044                          (match_operand:QI 3 "general_operand" "")))]
19045   "TARGET_QIMODE_MATH"
19046   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19047
19048 (define_insn_and_split "*movqicc_noc"
19049   [(set (match_operand:QI 0 "register_operand" "=r,r")
19050         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19051                                 [(match_operand 4 "flags_reg_operand" "")
19052                                  (const_int 0)])
19053                       (match_operand:QI 2 "register_operand" "r,0")
19054                       (match_operand:QI 3 "register_operand" "0,r")))]
19055   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19056   "#"
19057   "&& reload_completed"
19058   [(set (match_dup 0)
19059         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19060                       (match_dup 2)
19061                       (match_dup 3)))]
19062   "operands[0] = gen_lowpart (SImode, operands[0]);
19063    operands[2] = gen_lowpart (SImode, operands[2]);
19064    operands[3] = gen_lowpart (SImode, operands[3]);"
19065   [(set_attr "type" "icmov")
19066    (set_attr "mode" "SI")])
19067
19068 (define_expand "movsfcc"
19069   [(set (match_operand:SF 0 "register_operand" "")
19070         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19071                          (match_operand:SF 2 "register_operand" "")
19072                          (match_operand:SF 3 "register_operand" "")))]
19073   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19074   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19075
19076 (define_insn "*movsfcc_1_387"
19077   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19078         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19079                                 [(reg FLAGS_REG) (const_int 0)])
19080                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19081                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19082   "TARGET_80387 && TARGET_CMOVE
19083    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19084   "@
19085    fcmov%F1\t{%2, %0|%0, %2}
19086    fcmov%f1\t{%3, %0|%0, %3}
19087    cmov%O2%C1\t{%2, %0|%0, %2}
19088    cmov%O2%c1\t{%3, %0|%0, %3}"
19089   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19090    (set_attr "mode" "SF,SF,SI,SI")])
19091
19092 (define_expand "movdfcc"
19093   [(set (match_operand:DF 0 "register_operand" "")
19094         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19095                          (match_operand:DF 2 "register_operand" "")
19096                          (match_operand:DF 3 "register_operand" "")))]
19097   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19098   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19099
19100 (define_insn "*movdfcc_1"
19101   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19102         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19103                                 [(reg FLAGS_REG) (const_int 0)])
19104                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19105                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19106   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19107    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19108   "@
19109    fcmov%F1\t{%2, %0|%0, %2}
19110    fcmov%f1\t{%3, %0|%0, %3}
19111    #
19112    #"
19113   [(set_attr "type" "fcmov,fcmov,multi,multi")
19114    (set_attr "mode" "DF")])
19115
19116 (define_insn "*movdfcc_1_rex64"
19117   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19118         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19119                                 [(reg FLAGS_REG) (const_int 0)])
19120                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19121                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19122   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19123    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19124   "@
19125    fcmov%F1\t{%2, %0|%0, %2}
19126    fcmov%f1\t{%3, %0|%0, %3}
19127    cmov%O2%C1\t{%2, %0|%0, %2}
19128    cmov%O2%c1\t{%3, %0|%0, %3}"
19129   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19130    (set_attr "mode" "DF")])
19131
19132 (define_split
19133   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19134         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19135                                 [(match_operand 4 "flags_reg_operand" "")
19136                                  (const_int 0)])
19137                       (match_operand:DF 2 "nonimmediate_operand" "")
19138                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19139   "!TARGET_64BIT && reload_completed"
19140   [(set (match_dup 2)
19141         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19142                       (match_dup 5)
19143                       (match_dup 7)))
19144    (set (match_dup 3)
19145         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19146                       (match_dup 6)
19147                       (match_dup 8)))]
19148   "split_di (operands+2, 1, operands+5, operands+6);
19149    split_di (operands+3, 1, operands+7, operands+8);
19150    split_di (operands, 1, operands+2, operands+3);")
19151
19152 (define_expand "movxfcc"
19153   [(set (match_operand:XF 0 "register_operand" "")
19154         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19155                          (match_operand:XF 2 "register_operand" "")
19156                          (match_operand:XF 3 "register_operand" "")))]
19157   "TARGET_80387 && TARGET_CMOVE"
19158   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19159
19160 (define_insn "*movxfcc_1"
19161   [(set (match_operand:XF 0 "register_operand" "=f,f")
19162         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19163                                 [(reg FLAGS_REG) (const_int 0)])
19164                       (match_operand:XF 2 "register_operand" "f,0")
19165                       (match_operand:XF 3 "register_operand" "0,f")))]
19166   "TARGET_80387 && TARGET_CMOVE"
19167   "@
19168    fcmov%F1\t{%2, %0|%0, %2}
19169    fcmov%f1\t{%3, %0|%0, %3}"
19170   [(set_attr "type" "fcmov")
19171    (set_attr "mode" "XF")])
19172
19173 ;; These versions of the min/max patterns are intentionally ignorant of
19174 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19175 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19176 ;; are undefined in this condition, we're certain this is correct.
19177
19178 (define_insn "sminsf3"
19179   [(set (match_operand:SF 0 "register_operand" "=x")
19180         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19181                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19182   "TARGET_SSE_MATH"
19183   "minss\t{%2, %0|%0, %2}"
19184   [(set_attr "type" "sseadd")
19185    (set_attr "mode" "SF")])
19186
19187 (define_insn "smaxsf3"
19188   [(set (match_operand:SF 0 "register_operand" "=x")
19189         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19190                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19191   "TARGET_SSE_MATH"
19192   "maxss\t{%2, %0|%0, %2}"
19193   [(set_attr "type" "sseadd")
19194    (set_attr "mode" "SF")])
19195
19196 (define_insn "smindf3"
19197   [(set (match_operand:DF 0 "register_operand" "=x")
19198         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19199                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19200   "TARGET_SSE2 && TARGET_SSE_MATH"
19201   "minsd\t{%2, %0|%0, %2}"
19202   [(set_attr "type" "sseadd")
19203    (set_attr "mode" "DF")])
19204
19205 (define_insn "smaxdf3"
19206   [(set (match_operand:DF 0 "register_operand" "=x")
19207         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19208                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19209   "TARGET_SSE2 && TARGET_SSE_MATH"
19210   "maxsd\t{%2, %0|%0, %2}"
19211   [(set_attr "type" "sseadd")
19212    (set_attr "mode" "DF")])
19213
19214 ;; These versions of the min/max patterns implement exactly the operations
19215 ;;   min = (op1 < op2 ? op1 : op2)
19216 ;;   max = (!(op1 < op2) ? op1 : op2)
19217 ;; Their operands are not commutative, and thus they may be used in the
19218 ;; presence of -0.0 and NaN.
19219
19220 (define_insn "*ieee_sminsf3"
19221   [(set (match_operand:SF 0 "register_operand" "=x")
19222         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19223                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19224                    UNSPEC_IEEE_MIN))]
19225   "TARGET_SSE_MATH"
19226   "minss\t{%2, %0|%0, %2}"
19227   [(set_attr "type" "sseadd")
19228    (set_attr "mode" "SF")])
19229
19230 (define_insn "*ieee_smaxsf3"
19231   [(set (match_operand:SF 0 "register_operand" "=x")
19232         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19233                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19234                    UNSPEC_IEEE_MAX))]
19235   "TARGET_SSE_MATH"
19236   "maxss\t{%2, %0|%0, %2}"
19237   [(set_attr "type" "sseadd")
19238    (set_attr "mode" "SF")])
19239
19240 (define_insn "*ieee_smindf3"
19241   [(set (match_operand:DF 0 "register_operand" "=x")
19242         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19243                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19244                    UNSPEC_IEEE_MIN))]
19245   "TARGET_SSE2 && TARGET_SSE_MATH"
19246   "minsd\t{%2, %0|%0, %2}"
19247   [(set_attr "type" "sseadd")
19248    (set_attr "mode" "DF")])
19249
19250 (define_insn "*ieee_smaxdf3"
19251   [(set (match_operand:DF 0 "register_operand" "=x")
19252         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19253                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19254                    UNSPEC_IEEE_MAX))]
19255   "TARGET_SSE2 && TARGET_SSE_MATH"
19256   "maxsd\t{%2, %0|%0, %2}"
19257   [(set_attr "type" "sseadd")
19258    (set_attr "mode" "DF")])
19259
19260 ;; Make two stack loads independent:
19261 ;;   fld aa              fld aa
19262 ;;   fld %st(0)     ->   fld bb
19263 ;;   fmul bb             fmul %st(1), %st
19264 ;;
19265 ;; Actually we only match the last two instructions for simplicity.
19266 (define_peephole2
19267   [(set (match_operand 0 "fp_register_operand" "")
19268         (match_operand 1 "fp_register_operand" ""))
19269    (set (match_dup 0)
19270         (match_operator 2 "binary_fp_operator"
19271            [(match_dup 0)
19272             (match_operand 3 "memory_operand" "")]))]
19273   "REGNO (operands[0]) != REGNO (operands[1])"
19274   [(set (match_dup 0) (match_dup 3))
19275    (set (match_dup 0) (match_dup 4))]
19276
19277   ;; The % modifier is not operational anymore in peephole2's, so we have to
19278   ;; swap the operands manually in the case of addition and multiplication.
19279   "if (COMMUTATIVE_ARITH_P (operands[2]))
19280      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19281                                  operands[0], operands[1]);
19282    else
19283      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19284                                  operands[1], operands[0]);")
19285
19286 ;; Conditional addition patterns
19287 (define_expand "addqicc"
19288   [(match_operand:QI 0 "register_operand" "")
19289    (match_operand 1 "comparison_operator" "")
19290    (match_operand:QI 2 "register_operand" "")
19291    (match_operand:QI 3 "const_int_operand" "")]
19292   ""
19293   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19294
19295 (define_expand "addhicc"
19296   [(match_operand:HI 0 "register_operand" "")
19297    (match_operand 1 "comparison_operator" "")
19298    (match_operand:HI 2 "register_operand" "")
19299    (match_operand:HI 3 "const_int_operand" "")]
19300   ""
19301   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19302
19303 (define_expand "addsicc"
19304   [(match_operand:SI 0 "register_operand" "")
19305    (match_operand 1 "comparison_operator" "")
19306    (match_operand:SI 2 "register_operand" "")
19307    (match_operand:SI 3 "const_int_operand" "")]
19308   ""
19309   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19310
19311 (define_expand "adddicc"
19312   [(match_operand:DI 0 "register_operand" "")
19313    (match_operand 1 "comparison_operator" "")
19314    (match_operand:DI 2 "register_operand" "")
19315    (match_operand:DI 3 "const_int_operand" "")]
19316   "TARGET_64BIT"
19317   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19318
19319 \f
19320 ;; Misc patterns (?)
19321
19322 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19323 ;; Otherwise there will be nothing to keep
19324 ;;
19325 ;; [(set (reg ebp) (reg esp))]
19326 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19327 ;;  (clobber (eflags)]
19328 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19329 ;;
19330 ;; in proper program order.
19331 (define_insn "pro_epilogue_adjust_stack_1"
19332   [(set (match_operand:SI 0 "register_operand" "=r,r")
19333         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19334                  (match_operand:SI 2 "immediate_operand" "i,i")))
19335    (clobber (reg:CC FLAGS_REG))
19336    (clobber (mem:BLK (scratch)))]
19337   "!TARGET_64BIT"
19338 {
19339   switch (get_attr_type (insn))
19340     {
19341     case TYPE_IMOV:
19342       return "mov{l}\t{%1, %0|%0, %1}";
19343
19344     case TYPE_ALU:
19345       if (CONST_INT_P (operands[2])
19346           && (INTVAL (operands[2]) == 128
19347               || (INTVAL (operands[2]) < 0
19348                   && INTVAL (operands[2]) != -128)))
19349         {
19350           operands[2] = GEN_INT (-INTVAL (operands[2]));
19351           return "sub{l}\t{%2, %0|%0, %2}";
19352         }
19353       return "add{l}\t{%2, %0|%0, %2}";
19354
19355     case TYPE_LEA:
19356       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19357       return "lea{l}\t{%a2, %0|%0, %a2}";
19358
19359     default:
19360       gcc_unreachable ();
19361     }
19362 }
19363   [(set (attr "type")
19364         (cond [(eq_attr "alternative" "0")
19365                  (const_string "alu")
19366                (match_operand:SI 2 "const0_operand" "")
19367                  (const_string "imov")
19368               ]
19369               (const_string "lea")))
19370    (set_attr "mode" "SI")])
19371
19372 (define_insn "pro_epilogue_adjust_stack_rex64"
19373   [(set (match_operand:DI 0 "register_operand" "=r,r")
19374         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19375                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19376    (clobber (reg:CC FLAGS_REG))
19377    (clobber (mem:BLK (scratch)))]
19378   "TARGET_64BIT"
19379 {
19380   switch (get_attr_type (insn))
19381     {
19382     case TYPE_IMOV:
19383       return "mov{q}\t{%1, %0|%0, %1}";
19384
19385     case TYPE_ALU:
19386       if (CONST_INT_P (operands[2])
19387           /* Avoid overflows.  */
19388           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19389           && (INTVAL (operands[2]) == 128
19390               || (INTVAL (operands[2]) < 0
19391                   && INTVAL (operands[2]) != -128)))
19392         {
19393           operands[2] = GEN_INT (-INTVAL (operands[2]));
19394           return "sub{q}\t{%2, %0|%0, %2}";
19395         }
19396       return "add{q}\t{%2, %0|%0, %2}";
19397
19398     case TYPE_LEA:
19399       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19400       return "lea{q}\t{%a2, %0|%0, %a2}";
19401
19402     default:
19403       gcc_unreachable ();
19404     }
19405 }
19406   [(set (attr "type")
19407         (cond [(eq_attr "alternative" "0")
19408                  (const_string "alu")
19409                (match_operand:DI 2 "const0_operand" "")
19410                  (const_string "imov")
19411               ]
19412               (const_string "lea")))
19413    (set_attr "mode" "DI")])
19414
19415 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19416   [(set (match_operand:DI 0 "register_operand" "=r,r")
19417         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19418                  (match_operand:DI 3 "immediate_operand" "i,i")))
19419    (use (match_operand:DI 2 "register_operand" "r,r"))
19420    (clobber (reg:CC FLAGS_REG))
19421    (clobber (mem:BLK (scratch)))]
19422   "TARGET_64BIT"
19423 {
19424   switch (get_attr_type (insn))
19425     {
19426     case TYPE_ALU:
19427       return "add{q}\t{%2, %0|%0, %2}";
19428
19429     case TYPE_LEA:
19430       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19431       return "lea{q}\t{%a2, %0|%0, %a2}";
19432
19433     default:
19434       gcc_unreachable ();
19435     }
19436 }
19437   [(set_attr "type" "alu,lea")
19438    (set_attr "mode" "DI")])
19439
19440 (define_expand "allocate_stack_worker"
19441   [(match_operand:SI 0 "register_operand" "")]
19442   "TARGET_STACK_PROBE"
19443 {
19444   if (reload_completed)
19445     {
19446       if (TARGET_64BIT)
19447         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19448       else
19449         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19450     }
19451   else
19452     {
19453       if (TARGET_64BIT)
19454         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19455       else
19456         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19457     }
19458   DONE;
19459 })
19460
19461 (define_insn "allocate_stack_worker_1"
19462   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19463     UNSPECV_STACK_PROBE)
19464    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19465    (clobber (match_scratch:SI 1 "=0"))
19466    (clobber (reg:CC FLAGS_REG))]
19467   "!TARGET_64BIT && TARGET_STACK_PROBE"
19468   "call\t__alloca"
19469   [(set_attr "type" "multi")
19470    (set_attr "length" "5")])
19471
19472 (define_expand "allocate_stack_worker_postreload"
19473   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19474                                     UNSPECV_STACK_PROBE)
19475               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19476               (clobber (match_dup 0))
19477               (clobber (reg:CC FLAGS_REG))])]
19478   ""
19479   "")
19480
19481 (define_insn "allocate_stack_worker_rex64"
19482   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19483     UNSPECV_STACK_PROBE)
19484    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19485    (clobber (match_scratch:DI 1 "=0"))
19486    (clobber (reg:CC FLAGS_REG))]
19487   "TARGET_64BIT && TARGET_STACK_PROBE"
19488   "call\t__alloca"
19489   [(set_attr "type" "multi")
19490    (set_attr "length" "5")])
19491
19492 (define_expand "allocate_stack_worker_rex64_postreload"
19493   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19494                                     UNSPECV_STACK_PROBE)
19495               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19496               (clobber (match_dup 0))
19497               (clobber (reg:CC FLAGS_REG))])]
19498   ""
19499   "")
19500
19501 (define_expand "allocate_stack"
19502   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19503                    (minus:SI (reg:SI SP_REG)
19504                              (match_operand:SI 1 "general_operand" "")))
19505               (clobber (reg:CC FLAGS_REG))])
19506    (parallel [(set (reg:SI SP_REG)
19507                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19508               (clobber (reg:CC FLAGS_REG))])]
19509   "TARGET_STACK_PROBE"
19510 {
19511 #ifdef CHECK_STACK_LIMIT
19512   if (CONST_INT_P (operands[1])
19513       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19514     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19515                            operands[1]));
19516   else
19517 #endif
19518     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19519                                                             operands[1])));
19520
19521   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19522   DONE;
19523 })
19524
19525 (define_expand "builtin_setjmp_receiver"
19526   [(label_ref (match_operand 0 "" ""))]
19527   "!TARGET_64BIT && flag_pic"
19528 {
19529   if (TARGET_MACHO)
19530     {
19531       rtx xops[3];
19532       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19533       rtx label_rtx = gen_label_rtx ();
19534       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19535       xops[0] = xops[1] = picreg;
19536       xops[2] = gen_rtx_CONST (SImode,
19537                   gen_rtx_MINUS (SImode,
19538                     gen_rtx_LABEL_REF (SImode, label_rtx),
19539                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19540       ix86_expand_binary_operator (MINUS, SImode, xops);
19541     }
19542   else
19543     emit_insn (gen_set_got (pic_offset_table_rtx));
19544   DONE;
19545 })
19546 \f
19547 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19548
19549 (define_split
19550   [(set (match_operand 0 "register_operand" "")
19551         (match_operator 3 "promotable_binary_operator"
19552            [(match_operand 1 "register_operand" "")
19553             (match_operand 2 "aligned_operand" "")]))
19554    (clobber (reg:CC FLAGS_REG))]
19555   "! TARGET_PARTIAL_REG_STALL && reload_completed
19556    && ((GET_MODE (operands[0]) == HImode
19557         && ((!optimize_size && !TARGET_FAST_PREFIX)
19558             /* ??? next two lines just !satisfies_constraint_K (...) */
19559             || !CONST_INT_P (operands[2])
19560             || satisfies_constraint_K (operands[2])))
19561        || (GET_MODE (operands[0]) == QImode
19562            && (TARGET_PROMOTE_QImode || optimize_size)))"
19563   [(parallel [(set (match_dup 0)
19564                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19565               (clobber (reg:CC FLAGS_REG))])]
19566   "operands[0] = gen_lowpart (SImode, operands[0]);
19567    operands[1] = gen_lowpart (SImode, operands[1]);
19568    if (GET_CODE (operands[3]) != ASHIFT)
19569      operands[2] = gen_lowpart (SImode, operands[2]);
19570    PUT_MODE (operands[3], SImode);")
19571
19572 ; Promote the QImode tests, as i386 has encoding of the AND
19573 ; instruction with 32-bit sign-extended immediate and thus the
19574 ; instruction size is unchanged, except in the %eax case for
19575 ; which it is increased by one byte, hence the ! optimize_size.
19576 (define_split
19577   [(set (match_operand 0 "flags_reg_operand" "")
19578         (match_operator 2 "compare_operator"
19579           [(and (match_operand 3 "aligned_operand" "")
19580                 (match_operand 4 "const_int_operand" ""))
19581            (const_int 0)]))
19582    (set (match_operand 1 "register_operand" "")
19583         (and (match_dup 3) (match_dup 4)))]
19584   "! TARGET_PARTIAL_REG_STALL && reload_completed
19585    /* Ensure that the operand will remain sign-extended immediate.  */
19586    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19587    && ! optimize_size
19588    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19589        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19590   [(parallel [(set (match_dup 0)
19591                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19592                                     (const_int 0)]))
19593               (set (match_dup 1)
19594                    (and:SI (match_dup 3) (match_dup 4)))])]
19595 {
19596   operands[4]
19597     = gen_int_mode (INTVAL (operands[4])
19598                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19599   operands[1] = gen_lowpart (SImode, operands[1]);
19600   operands[3] = gen_lowpart (SImode, operands[3]);
19601 })
19602
19603 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19604 ; the TEST instruction with 32-bit sign-extended immediate and thus
19605 ; the instruction size would at least double, which is not what we
19606 ; want even with ! optimize_size.
19607 (define_split
19608   [(set (match_operand 0 "flags_reg_operand" "")
19609         (match_operator 1 "compare_operator"
19610           [(and (match_operand:HI 2 "aligned_operand" "")
19611                 (match_operand:HI 3 "const_int_operand" ""))
19612            (const_int 0)]))]
19613   "! TARGET_PARTIAL_REG_STALL && reload_completed
19614    /* Ensure that the operand will remain sign-extended immediate.  */
19615    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19616    && ! TARGET_FAST_PREFIX
19617    && ! optimize_size"
19618   [(set (match_dup 0)
19619         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19620                          (const_int 0)]))]
19621 {
19622   operands[3]
19623     = gen_int_mode (INTVAL (operands[3])
19624                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19625   operands[2] = gen_lowpart (SImode, operands[2]);
19626 })
19627
19628 (define_split
19629   [(set (match_operand 0 "register_operand" "")
19630         (neg (match_operand 1 "register_operand" "")))
19631    (clobber (reg:CC FLAGS_REG))]
19632   "! TARGET_PARTIAL_REG_STALL && reload_completed
19633    && (GET_MODE (operands[0]) == HImode
19634        || (GET_MODE (operands[0]) == QImode
19635            && (TARGET_PROMOTE_QImode || optimize_size)))"
19636   [(parallel [(set (match_dup 0)
19637                    (neg:SI (match_dup 1)))
19638               (clobber (reg:CC FLAGS_REG))])]
19639   "operands[0] = gen_lowpart (SImode, operands[0]);
19640    operands[1] = gen_lowpart (SImode, operands[1]);")
19641
19642 (define_split
19643   [(set (match_operand 0 "register_operand" "")
19644         (not (match_operand 1 "register_operand" "")))]
19645   "! TARGET_PARTIAL_REG_STALL && reload_completed
19646    && (GET_MODE (operands[0]) == HImode
19647        || (GET_MODE (operands[0]) == QImode
19648            && (TARGET_PROMOTE_QImode || optimize_size)))"
19649   [(set (match_dup 0)
19650         (not:SI (match_dup 1)))]
19651   "operands[0] = gen_lowpart (SImode, operands[0]);
19652    operands[1] = gen_lowpart (SImode, operands[1]);")
19653
19654 (define_split
19655   [(set (match_operand 0 "register_operand" "")
19656         (if_then_else (match_operator 1 "comparison_operator"
19657                                 [(reg FLAGS_REG) (const_int 0)])
19658                       (match_operand 2 "register_operand" "")
19659                       (match_operand 3 "register_operand" "")))]
19660   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19661    && (GET_MODE (operands[0]) == HImode
19662        || (GET_MODE (operands[0]) == QImode
19663            && (TARGET_PROMOTE_QImode || optimize_size)))"
19664   [(set (match_dup 0)
19665         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19666   "operands[0] = gen_lowpart (SImode, operands[0]);
19667    operands[2] = gen_lowpart (SImode, operands[2]);
19668    operands[3] = gen_lowpart (SImode, operands[3]);")
19669
19670 \f
19671 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19672 ;; transform a complex memory operation into two memory to register operations.
19673
19674 ;; Don't push memory operands
19675 (define_peephole2
19676   [(set (match_operand:SI 0 "push_operand" "")
19677         (match_operand:SI 1 "memory_operand" ""))
19678    (match_scratch:SI 2 "r")]
19679   "!optimize_size && !TARGET_PUSH_MEMORY
19680    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19681   [(set (match_dup 2) (match_dup 1))
19682    (set (match_dup 0) (match_dup 2))]
19683   "")
19684
19685 (define_peephole2
19686   [(set (match_operand:DI 0 "push_operand" "")
19687         (match_operand:DI 1 "memory_operand" ""))
19688    (match_scratch:DI 2 "r")]
19689   "!optimize_size && !TARGET_PUSH_MEMORY
19690    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19691   [(set (match_dup 2) (match_dup 1))
19692    (set (match_dup 0) (match_dup 2))]
19693   "")
19694
19695 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19696 ;; SImode pushes.
19697 (define_peephole2
19698   [(set (match_operand:SF 0 "push_operand" "")
19699         (match_operand:SF 1 "memory_operand" ""))
19700    (match_scratch:SF 2 "r")]
19701   "!optimize_size && !TARGET_PUSH_MEMORY
19702    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19703   [(set (match_dup 2) (match_dup 1))
19704    (set (match_dup 0) (match_dup 2))]
19705   "")
19706
19707 (define_peephole2
19708   [(set (match_operand:HI 0 "push_operand" "")
19709         (match_operand:HI 1 "memory_operand" ""))
19710    (match_scratch:HI 2 "r")]
19711   "!optimize_size && !TARGET_PUSH_MEMORY
19712    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19713   [(set (match_dup 2) (match_dup 1))
19714    (set (match_dup 0) (match_dup 2))]
19715   "")
19716
19717 (define_peephole2
19718   [(set (match_operand:QI 0 "push_operand" "")
19719         (match_operand:QI 1 "memory_operand" ""))
19720    (match_scratch:QI 2 "q")]
19721   "!optimize_size && !TARGET_PUSH_MEMORY
19722    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19723   [(set (match_dup 2) (match_dup 1))
19724    (set (match_dup 0) (match_dup 2))]
19725   "")
19726
19727 ;; Don't move an immediate directly to memory when the instruction
19728 ;; gets too big.
19729 (define_peephole2
19730   [(match_scratch:SI 1 "r")
19731    (set (match_operand:SI 0 "memory_operand" "")
19732         (const_int 0))]
19733   "! optimize_size
19734    && ! TARGET_USE_MOV0
19735    && TARGET_SPLIT_LONG_MOVES
19736    && get_attr_length (insn) >= ix86_cost->large_insn
19737    && peep2_regno_dead_p (0, FLAGS_REG)"
19738   [(parallel [(set (match_dup 1) (const_int 0))
19739               (clobber (reg:CC FLAGS_REG))])
19740    (set (match_dup 0) (match_dup 1))]
19741   "")
19742
19743 (define_peephole2
19744   [(match_scratch:HI 1 "r")
19745    (set (match_operand:HI 0 "memory_operand" "")
19746         (const_int 0))]
19747   "! optimize_size
19748    && ! TARGET_USE_MOV0
19749    && TARGET_SPLIT_LONG_MOVES
19750    && get_attr_length (insn) >= ix86_cost->large_insn
19751    && peep2_regno_dead_p (0, FLAGS_REG)"
19752   [(parallel [(set (match_dup 2) (const_int 0))
19753               (clobber (reg:CC FLAGS_REG))])
19754    (set (match_dup 0) (match_dup 1))]
19755   "operands[2] = gen_lowpart (SImode, operands[1]);")
19756
19757 (define_peephole2
19758   [(match_scratch:QI 1 "q")
19759    (set (match_operand:QI 0 "memory_operand" "")
19760         (const_int 0))]
19761   "! optimize_size
19762    && ! TARGET_USE_MOV0
19763    && TARGET_SPLIT_LONG_MOVES
19764    && get_attr_length (insn) >= ix86_cost->large_insn
19765    && peep2_regno_dead_p (0, FLAGS_REG)"
19766   [(parallel [(set (match_dup 2) (const_int 0))
19767               (clobber (reg:CC FLAGS_REG))])
19768    (set (match_dup 0) (match_dup 1))]
19769   "operands[2] = gen_lowpart (SImode, operands[1]);")
19770
19771 (define_peephole2
19772   [(match_scratch:SI 2 "r")
19773    (set (match_operand:SI 0 "memory_operand" "")
19774         (match_operand:SI 1 "immediate_operand" ""))]
19775   "! optimize_size
19776    && get_attr_length (insn) >= ix86_cost->large_insn
19777    && TARGET_SPLIT_LONG_MOVES"
19778   [(set (match_dup 2) (match_dup 1))
19779    (set (match_dup 0) (match_dup 2))]
19780   "")
19781
19782 (define_peephole2
19783   [(match_scratch:HI 2 "r")
19784    (set (match_operand:HI 0 "memory_operand" "")
19785         (match_operand:HI 1 "immediate_operand" ""))]
19786   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19787   && TARGET_SPLIT_LONG_MOVES"
19788   [(set (match_dup 2) (match_dup 1))
19789    (set (match_dup 0) (match_dup 2))]
19790   "")
19791
19792 (define_peephole2
19793   [(match_scratch:QI 2 "q")
19794    (set (match_operand:QI 0 "memory_operand" "")
19795         (match_operand:QI 1 "immediate_operand" ""))]
19796   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19797   && TARGET_SPLIT_LONG_MOVES"
19798   [(set (match_dup 2) (match_dup 1))
19799    (set (match_dup 0) (match_dup 2))]
19800   "")
19801
19802 ;; Don't compare memory with zero, load and use a test instead.
19803 (define_peephole2
19804   [(set (match_operand 0 "flags_reg_operand" "")
19805         (match_operator 1 "compare_operator"
19806           [(match_operand:SI 2 "memory_operand" "")
19807            (const_int 0)]))
19808    (match_scratch:SI 3 "r")]
19809   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19810   [(set (match_dup 3) (match_dup 2))
19811    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19812   "")
19813
19814 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19815 ;; Don't split NOTs with a displacement operand, because resulting XOR
19816 ;; will not be pairable anyway.
19817 ;;
19818 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19819 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19820 ;; so this split helps here as well.
19821 ;;
19822 ;; Note: Can't do this as a regular split because we can't get proper
19823 ;; lifetime information then.
19824
19825 (define_peephole2
19826   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19827         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19828   "!optimize_size
19829    && peep2_regno_dead_p (0, FLAGS_REG)
19830    && ((TARGET_PENTIUM
19831         && (!MEM_P (operands[0])
19832             || !memory_displacement_operand (operands[0], SImode)))
19833        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19834   [(parallel [(set (match_dup 0)
19835                    (xor:SI (match_dup 1) (const_int -1)))
19836               (clobber (reg:CC FLAGS_REG))])]
19837   "")
19838
19839 (define_peephole2
19840   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19841         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19842   "!optimize_size
19843    && peep2_regno_dead_p (0, FLAGS_REG)
19844    && ((TARGET_PENTIUM
19845         && (!MEM_P (operands[0])
19846             || !memory_displacement_operand (operands[0], HImode)))
19847        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19848   [(parallel [(set (match_dup 0)
19849                    (xor:HI (match_dup 1) (const_int -1)))
19850               (clobber (reg:CC FLAGS_REG))])]
19851   "")
19852
19853 (define_peephole2
19854   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19855         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19856   "!optimize_size
19857    && peep2_regno_dead_p (0, FLAGS_REG)
19858    && ((TARGET_PENTIUM
19859         && (!MEM_P (operands[0])
19860             || !memory_displacement_operand (operands[0], QImode)))
19861        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19862   [(parallel [(set (match_dup 0)
19863                    (xor:QI (match_dup 1) (const_int -1)))
19864               (clobber (reg:CC FLAGS_REG))])]
19865   "")
19866
19867 ;; Non pairable "test imm, reg" instructions can be translated to
19868 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19869 ;; byte opcode instead of two, have a short form for byte operands),
19870 ;; so do it for other CPUs as well.  Given that the value was dead,
19871 ;; this should not create any new dependencies.  Pass on the sub-word
19872 ;; versions if we're concerned about partial register stalls.
19873
19874 (define_peephole2
19875   [(set (match_operand 0 "flags_reg_operand" "")
19876         (match_operator 1 "compare_operator"
19877           [(and:SI (match_operand:SI 2 "register_operand" "")
19878                    (match_operand:SI 3 "immediate_operand" ""))
19879            (const_int 0)]))]
19880   "ix86_match_ccmode (insn, CCNOmode)
19881    && (true_regnum (operands[2]) != 0
19882        || satisfies_constraint_K (operands[3]))
19883    && peep2_reg_dead_p (1, operands[2])"
19884   [(parallel
19885      [(set (match_dup 0)
19886            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19887                             (const_int 0)]))
19888       (set (match_dup 2)
19889            (and:SI (match_dup 2) (match_dup 3)))])]
19890   "")
19891
19892 ;; We don't need to handle HImode case, because it will be promoted to SImode
19893 ;; on ! TARGET_PARTIAL_REG_STALL
19894
19895 (define_peephole2
19896   [(set (match_operand 0 "flags_reg_operand" "")
19897         (match_operator 1 "compare_operator"
19898           [(and:QI (match_operand:QI 2 "register_operand" "")
19899                    (match_operand:QI 3 "immediate_operand" ""))
19900            (const_int 0)]))]
19901   "! TARGET_PARTIAL_REG_STALL
19902    && ix86_match_ccmode (insn, CCNOmode)
19903    && true_regnum (operands[2]) != 0
19904    && peep2_reg_dead_p (1, operands[2])"
19905   [(parallel
19906      [(set (match_dup 0)
19907            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19908                             (const_int 0)]))
19909       (set (match_dup 2)
19910            (and:QI (match_dup 2) (match_dup 3)))])]
19911   "")
19912
19913 (define_peephole2
19914   [(set (match_operand 0 "flags_reg_operand" "")
19915         (match_operator 1 "compare_operator"
19916           [(and:SI
19917              (zero_extract:SI
19918                (match_operand 2 "ext_register_operand" "")
19919                (const_int 8)
19920                (const_int 8))
19921              (match_operand 3 "const_int_operand" ""))
19922            (const_int 0)]))]
19923   "! TARGET_PARTIAL_REG_STALL
19924    && ix86_match_ccmode (insn, CCNOmode)
19925    && true_regnum (operands[2]) != 0
19926    && peep2_reg_dead_p (1, operands[2])"
19927   [(parallel [(set (match_dup 0)
19928                    (match_op_dup 1
19929                      [(and:SI
19930                         (zero_extract:SI
19931                           (match_dup 2)
19932                           (const_int 8)
19933                           (const_int 8))
19934                         (match_dup 3))
19935                       (const_int 0)]))
19936               (set (zero_extract:SI (match_dup 2)
19937                                     (const_int 8)
19938                                     (const_int 8))
19939                    (and:SI
19940                      (zero_extract:SI
19941                        (match_dup 2)
19942                        (const_int 8)
19943                        (const_int 8))
19944                      (match_dup 3)))])]
19945   "")
19946
19947 ;; Don't do logical operations with memory inputs.
19948 (define_peephole2
19949   [(match_scratch:SI 2 "r")
19950    (parallel [(set (match_operand:SI 0 "register_operand" "")
19951                    (match_operator:SI 3 "arith_or_logical_operator"
19952                      [(match_dup 0)
19953                       (match_operand:SI 1 "memory_operand" "")]))
19954               (clobber (reg:CC FLAGS_REG))])]
19955   "! optimize_size && ! TARGET_READ_MODIFY"
19956   [(set (match_dup 2) (match_dup 1))
19957    (parallel [(set (match_dup 0)
19958                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19959               (clobber (reg:CC FLAGS_REG))])]
19960   "")
19961
19962 (define_peephole2
19963   [(match_scratch:SI 2 "r")
19964    (parallel [(set (match_operand:SI 0 "register_operand" "")
19965                    (match_operator:SI 3 "arith_or_logical_operator"
19966                      [(match_operand:SI 1 "memory_operand" "")
19967                       (match_dup 0)]))
19968               (clobber (reg:CC FLAGS_REG))])]
19969   "! optimize_size && ! TARGET_READ_MODIFY"
19970   [(set (match_dup 2) (match_dup 1))
19971    (parallel [(set (match_dup 0)
19972                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19973               (clobber (reg:CC FLAGS_REG))])]
19974   "")
19975
19976 ; Don't do logical operations with memory outputs
19977 ;
19978 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19979 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19980 ; the same decoder scheduling characteristics as the original.
19981
19982 (define_peephole2
19983   [(match_scratch:SI 2 "r")
19984    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19985                    (match_operator:SI 3 "arith_or_logical_operator"
19986                      [(match_dup 0)
19987                       (match_operand:SI 1 "nonmemory_operand" "")]))
19988               (clobber (reg:CC FLAGS_REG))])]
19989   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19990   [(set (match_dup 2) (match_dup 0))
19991    (parallel [(set (match_dup 2)
19992                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19993               (clobber (reg:CC FLAGS_REG))])
19994    (set (match_dup 0) (match_dup 2))]
19995   "")
19996
19997 (define_peephole2
19998   [(match_scratch:SI 2 "r")
19999    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20000                    (match_operator:SI 3 "arith_or_logical_operator"
20001                      [(match_operand:SI 1 "nonmemory_operand" "")
20002                       (match_dup 0)]))
20003               (clobber (reg:CC FLAGS_REG))])]
20004   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20005   [(set (match_dup 2) (match_dup 0))
20006    (parallel [(set (match_dup 2)
20007                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20008               (clobber (reg:CC FLAGS_REG))])
20009    (set (match_dup 0) (match_dup 2))]
20010   "")
20011
20012 ;; Attempt to always use XOR for zeroing registers.
20013 (define_peephole2
20014   [(set (match_operand 0 "register_operand" "")
20015         (match_operand 1 "const0_operand" ""))]
20016   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20017    && (! TARGET_USE_MOV0 || optimize_size)
20018    && GENERAL_REG_P (operands[0])
20019    && peep2_regno_dead_p (0, FLAGS_REG)"
20020   [(parallel [(set (match_dup 0) (const_int 0))
20021               (clobber (reg:CC FLAGS_REG))])]
20022 {
20023   operands[0] = gen_lowpart (word_mode, operands[0]);
20024 })
20025
20026 (define_peephole2
20027   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20028         (const_int 0))]
20029   "(GET_MODE (operands[0]) == QImode
20030     || GET_MODE (operands[0]) == HImode)
20031    && (! TARGET_USE_MOV0 || optimize_size)
20032    && peep2_regno_dead_p (0, FLAGS_REG)"
20033   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20034               (clobber (reg:CC FLAGS_REG))])])
20035
20036 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20037 (define_peephole2
20038   [(set (match_operand 0 "register_operand" "")
20039         (const_int -1))]
20040   "(GET_MODE (operands[0]) == HImode
20041     || GET_MODE (operands[0]) == SImode
20042     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20043    && (optimize_size || TARGET_PENTIUM)
20044    && peep2_regno_dead_p (0, FLAGS_REG)"
20045   [(parallel [(set (match_dup 0) (const_int -1))
20046               (clobber (reg:CC FLAGS_REG))])]
20047   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20048                               operands[0]);")
20049
20050 ;; Attempt to convert simple leas to adds. These can be created by
20051 ;; move expanders.
20052 (define_peephole2
20053   [(set (match_operand:SI 0 "register_operand" "")
20054         (plus:SI (match_dup 0)
20055                  (match_operand:SI 1 "nonmemory_operand" "")))]
20056   "peep2_regno_dead_p (0, FLAGS_REG)"
20057   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20058               (clobber (reg:CC FLAGS_REG))])]
20059   "")
20060
20061 (define_peephole2
20062   [(set (match_operand:SI 0 "register_operand" "")
20063         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20064                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20065   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20066   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20067               (clobber (reg:CC FLAGS_REG))])]
20068   "operands[2] = gen_lowpart (SImode, operands[2]);")
20069
20070 (define_peephole2
20071   [(set (match_operand:DI 0 "register_operand" "")
20072         (plus:DI (match_dup 0)
20073                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20074   "peep2_regno_dead_p (0, FLAGS_REG)"
20075   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20076               (clobber (reg:CC FLAGS_REG))])]
20077   "")
20078
20079 (define_peephole2
20080   [(set (match_operand:SI 0 "register_operand" "")
20081         (mult:SI (match_dup 0)
20082                  (match_operand:SI 1 "const_int_operand" "")))]
20083   "exact_log2 (INTVAL (operands[1])) >= 0
20084    && peep2_regno_dead_p (0, FLAGS_REG)"
20085   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20086               (clobber (reg:CC FLAGS_REG))])]
20087   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20088
20089 (define_peephole2
20090   [(set (match_operand:DI 0 "register_operand" "")
20091         (mult:DI (match_dup 0)
20092                  (match_operand:DI 1 "const_int_operand" "")))]
20093   "exact_log2 (INTVAL (operands[1])) >= 0
20094    && peep2_regno_dead_p (0, FLAGS_REG)"
20095   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20096               (clobber (reg:CC FLAGS_REG))])]
20097   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20098
20099 (define_peephole2
20100   [(set (match_operand:SI 0 "register_operand" "")
20101         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20102                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20103   "exact_log2 (INTVAL (operands[2])) >= 0
20104    && REGNO (operands[0]) == REGNO (operands[1])
20105    && peep2_regno_dead_p (0, FLAGS_REG)"
20106   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20107               (clobber (reg:CC FLAGS_REG))])]
20108   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20109
20110 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20111 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20112 ;; many CPUs it is also faster, since special hardware to avoid esp
20113 ;; dependencies is present.
20114
20115 ;; While some of these conversions may be done using splitters, we use peepholes
20116 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20117
20118 ;; Convert prologue esp subtractions to push.
20119 ;; We need register to push.  In order to keep verify_flow_info happy we have
20120 ;; two choices
20121 ;; - use scratch and clobber it in order to avoid dependencies
20122 ;; - use already live register
20123 ;; We can't use the second way right now, since there is no reliable way how to
20124 ;; verify that given register is live.  First choice will also most likely in
20125 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20126 ;; call clobbered registers are dead.  We may want to use base pointer as an
20127 ;; alternative when no register is available later.
20128
20129 (define_peephole2
20130   [(match_scratch:SI 0 "r")
20131    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20132               (clobber (reg:CC FLAGS_REG))
20133               (clobber (mem:BLK (scratch)))])]
20134   "optimize_size || !TARGET_SUB_ESP_4"
20135   [(clobber (match_dup 0))
20136    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20137               (clobber (mem:BLK (scratch)))])])
20138
20139 (define_peephole2
20140   [(match_scratch:SI 0 "r")
20141    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20142               (clobber (reg:CC FLAGS_REG))
20143               (clobber (mem:BLK (scratch)))])]
20144   "optimize_size || !TARGET_SUB_ESP_8"
20145   [(clobber (match_dup 0))
20146    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20147    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20148               (clobber (mem:BLK (scratch)))])])
20149
20150 ;; Convert esp subtractions to push.
20151 (define_peephole2
20152   [(match_scratch:SI 0 "r")
20153    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20154               (clobber (reg:CC FLAGS_REG))])]
20155   "optimize_size || !TARGET_SUB_ESP_4"
20156   [(clobber (match_dup 0))
20157    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20158
20159 (define_peephole2
20160   [(match_scratch:SI 0 "r")
20161    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20162               (clobber (reg:CC FLAGS_REG))])]
20163   "optimize_size || !TARGET_SUB_ESP_8"
20164   [(clobber (match_dup 0))
20165    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20166    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20167
20168 ;; Convert epilogue deallocator to pop.
20169 (define_peephole2
20170   [(match_scratch:SI 0 "r")
20171    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20172               (clobber (reg:CC FLAGS_REG))
20173               (clobber (mem:BLK (scratch)))])]
20174   "optimize_size || !TARGET_ADD_ESP_4"
20175   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20176               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20177               (clobber (mem:BLK (scratch)))])]
20178   "")
20179
20180 ;; Two pops case is tricky, since pop causes dependency on destination register.
20181 ;; We use two registers if available.
20182 (define_peephole2
20183   [(match_scratch:SI 0 "r")
20184    (match_scratch:SI 1 "r")
20185    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20186               (clobber (reg:CC FLAGS_REG))
20187               (clobber (mem:BLK (scratch)))])]
20188   "optimize_size || !TARGET_ADD_ESP_8"
20189   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20190               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20191               (clobber (mem:BLK (scratch)))])
20192    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20193               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20194   "")
20195
20196 (define_peephole2
20197   [(match_scratch:SI 0 "r")
20198    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20199               (clobber (reg:CC FLAGS_REG))
20200               (clobber (mem:BLK (scratch)))])]
20201   "optimize_size"
20202   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20203               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20204               (clobber (mem:BLK (scratch)))])
20205    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20206               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20207   "")
20208
20209 ;; Convert esp additions to pop.
20210 (define_peephole2
20211   [(match_scratch:SI 0 "r")
20212    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20213               (clobber (reg:CC FLAGS_REG))])]
20214   ""
20215   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20216               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20217   "")
20218
20219 ;; Two pops case is tricky, since pop causes dependency on destination register.
20220 ;; We use two registers if available.
20221 (define_peephole2
20222   [(match_scratch:SI 0 "r")
20223    (match_scratch:SI 1 "r")
20224    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20225               (clobber (reg:CC FLAGS_REG))])]
20226   ""
20227   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20228               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20229    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20230               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20231   "")
20232
20233 (define_peephole2
20234   [(match_scratch:SI 0 "r")
20235    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20236               (clobber (reg:CC FLAGS_REG))])]
20237   "optimize_size"
20238   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20239               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20240    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20241               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20242   "")
20243 \f
20244 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20245 ;; required and register dies.  Similarly for 128 to plus -128.
20246 (define_peephole2
20247   [(set (match_operand 0 "flags_reg_operand" "")
20248         (match_operator 1 "compare_operator"
20249           [(match_operand 2 "register_operand" "")
20250            (match_operand 3 "const_int_operand" "")]))]
20251   "(INTVAL (operands[3]) == -1
20252     || INTVAL (operands[3]) == 1
20253     || INTVAL (operands[3]) == 128)
20254    && ix86_match_ccmode (insn, CCGCmode)
20255    && peep2_reg_dead_p (1, operands[2])"
20256   [(parallel [(set (match_dup 0)
20257                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20258               (clobber (match_dup 2))])]
20259   "")
20260 \f
20261 (define_peephole2
20262   [(match_scratch:DI 0 "r")
20263    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20264               (clobber (reg:CC FLAGS_REG))
20265               (clobber (mem:BLK (scratch)))])]
20266   "optimize_size || !TARGET_SUB_ESP_4"
20267   [(clobber (match_dup 0))
20268    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20269               (clobber (mem:BLK (scratch)))])])
20270
20271 (define_peephole2
20272   [(match_scratch:DI 0 "r")
20273    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20274               (clobber (reg:CC FLAGS_REG))
20275               (clobber (mem:BLK (scratch)))])]
20276   "optimize_size || !TARGET_SUB_ESP_8"
20277   [(clobber (match_dup 0))
20278    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20279    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20280               (clobber (mem:BLK (scratch)))])])
20281
20282 ;; Convert esp subtractions to push.
20283 (define_peephole2
20284   [(match_scratch:DI 0 "r")
20285    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20286               (clobber (reg:CC FLAGS_REG))])]
20287   "optimize_size || !TARGET_SUB_ESP_4"
20288   [(clobber (match_dup 0))
20289    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20290
20291 (define_peephole2
20292   [(match_scratch:DI 0 "r")
20293    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20294               (clobber (reg:CC FLAGS_REG))])]
20295   "optimize_size || !TARGET_SUB_ESP_8"
20296   [(clobber (match_dup 0))
20297    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20298    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20299
20300 ;; Convert epilogue deallocator to pop.
20301 (define_peephole2
20302   [(match_scratch:DI 0 "r")
20303    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20304               (clobber (reg:CC FLAGS_REG))
20305               (clobber (mem:BLK (scratch)))])]
20306   "optimize_size || !TARGET_ADD_ESP_4"
20307   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20308               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20309               (clobber (mem:BLK (scratch)))])]
20310   "")
20311
20312 ;; Two pops case is tricky, since pop causes dependency on destination register.
20313 ;; We use two registers if available.
20314 (define_peephole2
20315   [(match_scratch:DI 0 "r")
20316    (match_scratch:DI 1 "r")
20317    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20318               (clobber (reg:CC FLAGS_REG))
20319               (clobber (mem:BLK (scratch)))])]
20320   "optimize_size || !TARGET_ADD_ESP_8"
20321   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20322               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20323               (clobber (mem:BLK (scratch)))])
20324    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20325               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20326   "")
20327
20328 (define_peephole2
20329   [(match_scratch:DI 0 "r")
20330    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20331               (clobber (reg:CC FLAGS_REG))
20332               (clobber (mem:BLK (scratch)))])]
20333   "optimize_size"
20334   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20335               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20336               (clobber (mem:BLK (scratch)))])
20337    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20338               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20339   "")
20340
20341 ;; Convert esp additions to pop.
20342 (define_peephole2
20343   [(match_scratch:DI 0 "r")
20344    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20345               (clobber (reg:CC FLAGS_REG))])]
20346   ""
20347   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20348               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20349   "")
20350
20351 ;; Two pops case is tricky, since pop causes dependency on destination register.
20352 ;; We use two registers if available.
20353 (define_peephole2
20354   [(match_scratch:DI 0 "r")
20355    (match_scratch:DI 1 "r")
20356    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20357               (clobber (reg:CC FLAGS_REG))])]
20358   ""
20359   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20360               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20361    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20362               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20363   "")
20364
20365 (define_peephole2
20366   [(match_scratch:DI 0 "r")
20367    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20368               (clobber (reg:CC FLAGS_REG))])]
20369   "optimize_size"
20370   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20371               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20372    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20373               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20374   "")
20375 \f
20376 ;; Convert imul by three, five and nine into lea
20377 (define_peephole2
20378   [(parallel
20379     [(set (match_operand:SI 0 "register_operand" "")
20380           (mult:SI (match_operand:SI 1 "register_operand" "")
20381                    (match_operand:SI 2 "const_int_operand" "")))
20382      (clobber (reg:CC FLAGS_REG))])]
20383   "INTVAL (operands[2]) == 3
20384    || INTVAL (operands[2]) == 5
20385    || INTVAL (operands[2]) == 9"
20386   [(set (match_dup 0)
20387         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20388                  (match_dup 1)))]
20389   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20390
20391 (define_peephole2
20392   [(parallel
20393     [(set (match_operand:SI 0 "register_operand" "")
20394           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20395                    (match_operand:SI 2 "const_int_operand" "")))
20396      (clobber (reg:CC FLAGS_REG))])]
20397   "!optimize_size
20398    && (INTVAL (operands[2]) == 3
20399        || INTVAL (operands[2]) == 5
20400        || INTVAL (operands[2]) == 9)"
20401   [(set (match_dup 0) (match_dup 1))
20402    (set (match_dup 0)
20403         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20404                  (match_dup 0)))]
20405   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20406
20407 (define_peephole2
20408   [(parallel
20409     [(set (match_operand:DI 0 "register_operand" "")
20410           (mult:DI (match_operand:DI 1 "register_operand" "")
20411                    (match_operand:DI 2 "const_int_operand" "")))
20412      (clobber (reg:CC FLAGS_REG))])]
20413   "TARGET_64BIT
20414    && (INTVAL (operands[2]) == 3
20415        || INTVAL (operands[2]) == 5
20416        || INTVAL (operands[2]) == 9)"
20417   [(set (match_dup 0)
20418         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20419                  (match_dup 1)))]
20420   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20421
20422 (define_peephole2
20423   [(parallel
20424     [(set (match_operand:DI 0 "register_operand" "")
20425           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20426                    (match_operand:DI 2 "const_int_operand" "")))
20427      (clobber (reg:CC FLAGS_REG))])]
20428   "TARGET_64BIT
20429    && !optimize_size
20430    && (INTVAL (operands[2]) == 3
20431        || INTVAL (operands[2]) == 5
20432        || INTVAL (operands[2]) == 9)"
20433   [(set (match_dup 0) (match_dup 1))
20434    (set (match_dup 0)
20435         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20436                  (match_dup 0)))]
20437   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20438
20439 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20440 ;; imul $32bit_imm, reg, reg is direct decoded.
20441 (define_peephole2
20442   [(match_scratch:DI 3 "r")
20443    (parallel [(set (match_operand:DI 0 "register_operand" "")
20444                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20445                             (match_operand:DI 2 "immediate_operand" "")))
20446               (clobber (reg:CC FLAGS_REG))])]
20447   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20448    && !satisfies_constraint_K (operands[2])"
20449   [(set (match_dup 3) (match_dup 1))
20450    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20451               (clobber (reg:CC FLAGS_REG))])]
20452 "")
20453
20454 (define_peephole2
20455   [(match_scratch:SI 3 "r")
20456    (parallel [(set (match_operand:SI 0 "register_operand" "")
20457                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20458                             (match_operand:SI 2 "immediate_operand" "")))
20459               (clobber (reg:CC FLAGS_REG))])]
20460   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20461    && !satisfies_constraint_K (operands[2])"
20462   [(set (match_dup 3) (match_dup 1))
20463    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20464               (clobber (reg:CC FLAGS_REG))])]
20465 "")
20466
20467 (define_peephole2
20468   [(match_scratch:SI 3 "r")
20469    (parallel [(set (match_operand:DI 0 "register_operand" "")
20470                    (zero_extend:DI
20471                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20472                               (match_operand:SI 2 "immediate_operand" ""))))
20473               (clobber (reg:CC FLAGS_REG))])]
20474   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20475    && !satisfies_constraint_K (operands[2])"
20476   [(set (match_dup 3) (match_dup 1))
20477    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20478               (clobber (reg:CC FLAGS_REG))])]
20479 "")
20480
20481 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20482 ;; Convert it into imul reg, reg
20483 ;; It would be better to force assembler to encode instruction using long
20484 ;; immediate, but there is apparently no way to do so.
20485 (define_peephole2
20486   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20487                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20488                             (match_operand:DI 2 "const_int_operand" "")))
20489               (clobber (reg:CC FLAGS_REG))])
20490    (match_scratch:DI 3 "r")]
20491   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20492    && satisfies_constraint_K (operands[2])"
20493   [(set (match_dup 3) (match_dup 2))
20494    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20495               (clobber (reg:CC FLAGS_REG))])]
20496 {
20497   if (!rtx_equal_p (operands[0], operands[1]))
20498     emit_move_insn (operands[0], operands[1]);
20499 })
20500
20501 (define_peephole2
20502   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20503                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20504                             (match_operand:SI 2 "const_int_operand" "")))
20505               (clobber (reg:CC FLAGS_REG))])
20506    (match_scratch:SI 3 "r")]
20507   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20508    && satisfies_constraint_K (operands[2])"
20509   [(set (match_dup 3) (match_dup 2))
20510    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20511               (clobber (reg:CC FLAGS_REG))])]
20512 {
20513   if (!rtx_equal_p (operands[0], operands[1]))
20514     emit_move_insn (operands[0], operands[1]);
20515 })
20516
20517 (define_peephole2
20518   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20519                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20520                             (match_operand:HI 2 "immediate_operand" "")))
20521               (clobber (reg:CC FLAGS_REG))])
20522    (match_scratch:HI 3 "r")]
20523   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20524   [(set (match_dup 3) (match_dup 2))
20525    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20526               (clobber (reg:CC FLAGS_REG))])]
20527 {
20528   if (!rtx_equal_p (operands[0], operands[1]))
20529     emit_move_insn (operands[0], operands[1]);
20530 })
20531
20532 ;; After splitting up read-modify operations, array accesses with memory
20533 ;; operands might end up in form:
20534 ;;  sall    $2, %eax
20535 ;;  movl    4(%esp), %edx
20536 ;;  addl    %edx, %eax
20537 ;; instead of pre-splitting:
20538 ;;  sall    $2, %eax
20539 ;;  addl    4(%esp), %eax
20540 ;; Turn it into:
20541 ;;  movl    4(%esp), %edx
20542 ;;  leal    (%edx,%eax,4), %eax
20543
20544 (define_peephole2
20545   [(parallel [(set (match_operand 0 "register_operand" "")
20546                    (ashift (match_operand 1 "register_operand" "")
20547                            (match_operand 2 "const_int_operand" "")))
20548                (clobber (reg:CC FLAGS_REG))])
20549    (set (match_operand 3 "register_operand")
20550         (match_operand 4 "x86_64_general_operand" ""))
20551    (parallel [(set (match_operand 5 "register_operand" "")
20552                    (plus (match_operand 6 "register_operand" "")
20553                          (match_operand 7 "register_operand" "")))
20554                    (clobber (reg:CC FLAGS_REG))])]
20555   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20556    /* Validate MODE for lea.  */
20557    && ((!TARGET_PARTIAL_REG_STALL
20558         && (GET_MODE (operands[0]) == QImode
20559             || GET_MODE (operands[0]) == HImode))
20560        || GET_MODE (operands[0]) == SImode
20561        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20562    /* We reorder load and the shift.  */
20563    && !rtx_equal_p (operands[1], operands[3])
20564    && !reg_overlap_mentioned_p (operands[0], operands[4])
20565    /* Last PLUS must consist of operand 0 and 3.  */
20566    && !rtx_equal_p (operands[0], operands[3])
20567    && (rtx_equal_p (operands[3], operands[6])
20568        || rtx_equal_p (operands[3], operands[7]))
20569    && (rtx_equal_p (operands[0], operands[6])
20570        || rtx_equal_p (operands[0], operands[7]))
20571    /* The intermediate operand 0 must die or be same as output.  */
20572    && (rtx_equal_p (operands[0], operands[5])
20573        || peep2_reg_dead_p (3, operands[0]))"
20574   [(set (match_dup 3) (match_dup 4))
20575    (set (match_dup 0) (match_dup 1))]
20576 {
20577   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20578   int scale = 1 << INTVAL (operands[2]);
20579   rtx index = gen_lowpart (Pmode, operands[1]);
20580   rtx base = gen_lowpart (Pmode, operands[3]);
20581   rtx dest = gen_lowpart (mode, operands[5]);
20582
20583   operands[1] = gen_rtx_PLUS (Pmode, base,
20584                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20585   if (mode != Pmode)
20586     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20587   operands[0] = dest;
20588 })
20589 \f
20590 ;; Call-value patterns last so that the wildcard operand does not
20591 ;; disrupt insn-recog's switch tables.
20592
20593 (define_insn "*call_value_pop_0"
20594   [(set (match_operand 0 "" "")
20595         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20596               (match_operand:SI 2 "" "")))
20597    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20598                             (match_operand:SI 3 "immediate_operand" "")))]
20599   "!TARGET_64BIT"
20600 {
20601   if (SIBLING_CALL_P (insn))
20602     return "jmp\t%P1";
20603   else
20604     return "call\t%P1";
20605 }
20606   [(set_attr "type" "callv")])
20607
20608 (define_insn "*call_value_pop_1"
20609   [(set (match_operand 0 "" "")
20610         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20611               (match_operand:SI 2 "" "")))
20612    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20613                             (match_operand:SI 3 "immediate_operand" "i")))]
20614   "!TARGET_64BIT"
20615 {
20616   if (constant_call_address_operand (operands[1], Pmode))
20617     {
20618       if (SIBLING_CALL_P (insn))
20619         return "jmp\t%P1";
20620       else
20621         return "call\t%P1";
20622     }
20623   if (SIBLING_CALL_P (insn))
20624     return "jmp\t%A1";
20625   else
20626     return "call\t%A1";
20627 }
20628   [(set_attr "type" "callv")])
20629
20630 (define_insn "*call_value_0"
20631   [(set (match_operand 0 "" "")
20632         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20633               (match_operand:SI 2 "" "")))]
20634   "!TARGET_64BIT"
20635 {
20636   if (SIBLING_CALL_P (insn))
20637     return "jmp\t%P1";
20638   else
20639     return "call\t%P1";
20640 }
20641   [(set_attr "type" "callv")])
20642
20643 (define_insn "*call_value_0_rex64"
20644   [(set (match_operand 0 "" "")
20645         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20646               (match_operand:DI 2 "const_int_operand" "")))]
20647   "TARGET_64BIT"
20648 {
20649   if (SIBLING_CALL_P (insn))
20650     return "jmp\t%P1";
20651   else
20652     return "call\t%P1";
20653 }
20654   [(set_attr "type" "callv")])
20655
20656 (define_insn "*call_value_1"
20657   [(set (match_operand 0 "" "")
20658         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20659               (match_operand:SI 2 "" "")))]
20660   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20661 {
20662   if (constant_call_address_operand (operands[1], Pmode))
20663     return "call\t%P1";
20664   return "call\t%A1";
20665 }
20666   [(set_attr "type" "callv")])
20667
20668 (define_insn "*sibcall_value_1"
20669   [(set (match_operand 0 "" "")
20670         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20671               (match_operand:SI 2 "" "")))]
20672   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20673 {
20674   if (constant_call_address_operand (operands[1], Pmode))
20675     return "jmp\t%P1";
20676   return "jmp\t%A1";
20677 }
20678   [(set_attr "type" "callv")])
20679
20680 (define_insn "*call_value_1_rex64"
20681   [(set (match_operand 0 "" "")
20682         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20683               (match_operand:DI 2 "" "")))]
20684   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20685 {
20686   if (constant_call_address_operand (operands[1], Pmode))
20687     return "call\t%P1";
20688   return "call\t%A1";
20689 }
20690   [(set_attr "type" "callv")])
20691
20692 (define_insn "*sibcall_value_1_rex64"
20693   [(set (match_operand 0 "" "")
20694         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20695               (match_operand:DI 2 "" "")))]
20696   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20697   "jmp\t%P1"
20698   [(set_attr "type" "callv")])
20699
20700 (define_insn "*sibcall_value_1_rex64_v"
20701   [(set (match_operand 0 "" "")
20702         (call (mem:QI (reg:DI R11_REG))
20703               (match_operand:DI 1 "" "")))]
20704   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20705   "jmp\t*%%r11"
20706   [(set_attr "type" "callv")])
20707 \f
20708 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20709 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20710 ;; caught for use by garbage collectors and the like.  Using an insn that
20711 ;; maps to SIGILL makes it more likely the program will rightfully die.
20712 ;; Keeping with tradition, "6" is in honor of #UD.
20713 (define_insn "trap"
20714   [(trap_if (const_int 1) (const_int 6))]
20715   ""
20716   { return ASM_SHORT "0x0b0f"; }
20717   [(set_attr "length" "2")])
20718
20719 (define_expand "sse_prologue_save"
20720   [(parallel [(set (match_operand:BLK 0 "" "")
20721                    (unspec:BLK [(reg:DI 21)
20722                                 (reg:DI 22)
20723                                 (reg:DI 23)
20724                                 (reg:DI 24)
20725                                 (reg:DI 25)
20726                                 (reg:DI 26)
20727                                 (reg:DI 27)
20728                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20729               (use (match_operand:DI 1 "register_operand" ""))
20730               (use (match_operand:DI 2 "immediate_operand" ""))
20731               (use (label_ref:DI (match_operand 3 "" "")))])]
20732   "TARGET_64BIT"
20733   "")
20734
20735 (define_insn "*sse_prologue_save_insn"
20736   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20737                           (match_operand:DI 4 "const_int_operand" "n")))
20738         (unspec:BLK [(reg:DI 21)
20739                      (reg:DI 22)
20740                      (reg:DI 23)
20741                      (reg:DI 24)
20742                      (reg:DI 25)
20743                      (reg:DI 26)
20744                      (reg:DI 27)
20745                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20746    (use (match_operand:DI 1 "register_operand" "r"))
20747    (use (match_operand:DI 2 "const_int_operand" "i"))
20748    (use (label_ref:DI (match_operand 3 "" "X")))]
20749   "TARGET_64BIT
20750    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20751    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20752   "*
20753 {
20754   int i;
20755   operands[0] = gen_rtx_MEM (Pmode,
20756                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20757   output_asm_insn (\"jmp\\t%A1\", operands);
20758   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20759     {
20760       operands[4] = adjust_address (operands[0], DImode, i*16);
20761       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20762       PUT_MODE (operands[4], TImode);
20763       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20764         output_asm_insn (\"rex\", operands);
20765       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20766     }
20767   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20768                              CODE_LABEL_NUMBER (operands[3]));
20769   return \"\";
20770 }
20771   "
20772   [(set_attr "type" "other")
20773    (set_attr "length_immediate" "0")
20774    (set_attr "length_address" "0")
20775    (set_attr "length" "135")
20776    (set_attr "memory" "store")
20777    (set_attr "modrm" "0")
20778    (set_attr "mode" "DI")])
20779
20780 (define_expand "prefetch"
20781   [(prefetch (match_operand 0 "address_operand" "")
20782              (match_operand:SI 1 "const_int_operand" "")
20783              (match_operand:SI 2 "const_int_operand" ""))]
20784   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20785 {
20786   int rw = INTVAL (operands[1]);
20787   int locality = INTVAL (operands[2]);
20788
20789   gcc_assert (rw == 0 || rw == 1);
20790   gcc_assert (locality >= 0 && locality <= 3);
20791   gcc_assert (GET_MODE (operands[0]) == Pmode
20792               || GET_MODE (operands[0]) == VOIDmode);
20793
20794   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20795      supported by SSE counterpart or the SSE prefetch is not available
20796      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20797      of locality.  */
20798   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20799     operands[2] = GEN_INT (3);
20800   else
20801     operands[1] = const0_rtx;
20802 })
20803
20804 (define_insn "*prefetch_sse"
20805   [(prefetch (match_operand:SI 0 "address_operand" "p")
20806              (const_int 0)
20807              (match_operand:SI 1 "const_int_operand" ""))]
20808   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20809 {
20810   static const char * const patterns[4] = {
20811    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20812   };
20813
20814   int locality = INTVAL (operands[1]);
20815   gcc_assert (locality >= 0 && locality <= 3);
20816
20817   return patterns[locality];
20818 }
20819   [(set_attr "type" "sse")
20820    (set_attr "memory" "none")])
20821
20822 (define_insn "*prefetch_sse_rex"
20823   [(prefetch (match_operand:DI 0 "address_operand" "p")
20824              (const_int 0)
20825              (match_operand:SI 1 "const_int_operand" ""))]
20826   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20827 {
20828   static const char * const patterns[4] = {
20829    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20830   };
20831
20832   int locality = INTVAL (operands[1]);
20833   gcc_assert (locality >= 0 && locality <= 3);
20834
20835   return patterns[locality];
20836 }
20837   [(set_attr "type" "sse")
20838    (set_attr "memory" "none")])
20839
20840 (define_insn "*prefetch_3dnow"
20841   [(prefetch (match_operand:SI 0 "address_operand" "p")
20842              (match_operand:SI 1 "const_int_operand" "n")
20843              (const_int 3))]
20844   "TARGET_3DNOW && !TARGET_64BIT"
20845 {
20846   if (INTVAL (operands[1]) == 0)
20847     return "prefetch\t%a0";
20848   else
20849     return "prefetchw\t%a0";
20850 }
20851   [(set_attr "type" "mmx")
20852    (set_attr "memory" "none")])
20853
20854 (define_insn "*prefetch_3dnow_rex"
20855   [(prefetch (match_operand:DI 0 "address_operand" "p")
20856              (match_operand:SI 1 "const_int_operand" "n")
20857              (const_int 3))]
20858   "TARGET_3DNOW && TARGET_64BIT"
20859 {
20860   if (INTVAL (operands[1]) == 0)
20861     return "prefetch\t%a0";
20862   else
20863     return "prefetchw\t%a0";
20864 }
20865   [(set_attr "type" "mmx")
20866    (set_attr "memory" "none")])
20867
20868 (define_expand "stack_protect_set"
20869   [(match_operand 0 "memory_operand" "")
20870    (match_operand 1 "memory_operand" "")]
20871   ""
20872 {
20873 #ifdef TARGET_THREAD_SSP_OFFSET
20874   if (TARGET_64BIT)
20875     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20876                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20877   else
20878     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20879                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20880 #else
20881   if (TARGET_64BIT)
20882     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20883   else
20884     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20885 #endif
20886   DONE;
20887 })
20888
20889 (define_insn "stack_protect_set_si"
20890   [(set (match_operand:SI 0 "memory_operand" "=m")
20891         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20892    (set (match_scratch:SI 2 "=&r") (const_int 0))
20893    (clobber (reg:CC FLAGS_REG))]
20894   ""
20895   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20896   [(set_attr "type" "multi")])
20897
20898 (define_insn "stack_protect_set_di"
20899   [(set (match_operand:DI 0 "memory_operand" "=m")
20900         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20901    (set (match_scratch:DI 2 "=&r") (const_int 0))
20902    (clobber (reg:CC FLAGS_REG))]
20903   "TARGET_64BIT"
20904   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20905   [(set_attr "type" "multi")])
20906
20907 (define_insn "stack_tls_protect_set_si"
20908   [(set (match_operand:SI 0 "memory_operand" "=m")
20909         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20910    (set (match_scratch:SI 2 "=&r") (const_int 0))
20911    (clobber (reg:CC FLAGS_REG))]
20912   ""
20913   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20914   [(set_attr "type" "multi")])
20915
20916 (define_insn "stack_tls_protect_set_di"
20917   [(set (match_operand:DI 0 "memory_operand" "=m")
20918         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20919    (set (match_scratch:DI 2 "=&r") (const_int 0))
20920    (clobber (reg:CC FLAGS_REG))]
20921   "TARGET_64BIT"
20922   {
20923      /* The kernel uses a different segment register for performance reasons; a
20924         system call would not have to trash the userspace segment register,
20925         which would be expensive */
20926      if (ix86_cmodel != CM_KERNEL)
20927         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20928      else
20929         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20930   }
20931   [(set_attr "type" "multi")])
20932
20933 (define_expand "stack_protect_test"
20934   [(match_operand 0 "memory_operand" "")
20935    (match_operand 1 "memory_operand" "")
20936    (match_operand 2 "" "")]
20937   ""
20938 {
20939   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20940   ix86_compare_op0 = operands[0];
20941   ix86_compare_op1 = operands[1];
20942   ix86_compare_emitted = flags;
20943
20944 #ifdef TARGET_THREAD_SSP_OFFSET
20945   if (TARGET_64BIT)
20946     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20947                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20948   else
20949     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20950                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20951 #else
20952   if (TARGET_64BIT)
20953     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20954   else
20955     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20956 #endif
20957   emit_jump_insn (gen_beq (operands[2]));
20958   DONE;
20959 })
20960
20961 (define_insn "stack_protect_test_si"
20962   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20963         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20964                      (match_operand:SI 2 "memory_operand" "m")]
20965                     UNSPEC_SP_TEST))
20966    (clobber (match_scratch:SI 3 "=&r"))]
20967   ""
20968   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20969   [(set_attr "type" "multi")])
20970
20971 (define_insn "stack_protect_test_di"
20972   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20973         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20974                      (match_operand:DI 2 "memory_operand" "m")]
20975                     UNSPEC_SP_TEST))
20976    (clobber (match_scratch:DI 3 "=&r"))]
20977   "TARGET_64BIT"
20978   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20979   [(set_attr "type" "multi")])
20980
20981 (define_insn "stack_tls_protect_test_si"
20982   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20983         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20984                      (match_operand:SI 2 "const_int_operand" "i")]
20985                     UNSPEC_SP_TLS_TEST))
20986    (clobber (match_scratch:SI 3 "=r"))]
20987   ""
20988   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20989   [(set_attr "type" "multi")])
20990
20991 (define_insn "stack_tls_protect_test_di"
20992   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20993         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20994                      (match_operand:DI 2 "const_int_operand" "i")]
20995                     UNSPEC_SP_TLS_TEST))
20996    (clobber (match_scratch:DI 3 "=r"))]
20997   "TARGET_64BIT"
20998   {
20999      /* The kernel uses a different segment register for performance reasons; a
21000         system call would not have to trash the userspace segment register,
21001         which would be expensive */
21002      if (ix86_cmodel != CM_KERNEL)
21003         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21004      else
21005         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21006   }
21007   [(set_attr "type" "multi")])
21008
21009 (include "mmx.md")
21010 (include "sse.md")
21011 (include "sync.md")